| Crates.io | semigroup |
| lib.rs | semigroup |
| version | 0.4.3 |
| created_at | 2025-10-19 07:26:33.877959+00 |
| updated_at | 2025-11-29 07:32:29.57745+00 |
| description | Useful semigroup trait |
| homepage | |
| repository | https://github.com/hayas1/semigroup |
| max_upload_size | |
| id | 1890159 |
| size | 191,875 |
Semigroup trait is useful for combining multiple elements.
For example:
This crate enables you to derive Semigroup
and provides many practical implementations.
cargo add semigroup --features derive,monoid
A CLI example of clap and serde integration, see https://github.com/hayas1/semigroup/blob/master/semigroup/examples/clap_serde.rs
use semigroup::Semigroup;
#[derive(Debug, Clone, PartialEq, Semigroup)]
#[semigroup(with = "semigroup::op::Coalesce")]
pub struct Config<'a> {
pub num: Option<u32>,
pub str: Option<&'a str>,
#[semigroup(with = "semigroup::op::Overwrite")]
pub boolean: bool,
}
let cli = Config { num: Some(1), str: None, boolean: true };
let file = Config { num: None, str: Some("ten"), boolean: false };
let env = Config { num: Some(100), str: None, boolean: false };
let config = cli.semigroup(file).semigroup(env);
assert_eq!(config, Config { num: Some(1), str: Some("ten"), boolean: false });
More detail is in [Annotate] and [Lazy].
use semigroup::{Annotate, Lazy, Semigroup};
#[derive(Debug, Clone, PartialEq, Semigroup)]
#[semigroup(annotated, with = "semigroup::op::Coalesce")]
pub struct Config<'a> {
pub num: Option<u32>,
pub str: Option<&'a str>,
#[semigroup(with = "semigroup::op::Overwrite")]
pub boolean: bool,
}
#[derive(Debug, Clone, PartialEq)]
pub enum Source {
File,
Env,
Cli,
}
let cli = Config { num: Some(1), str: None, boolean: true }.annotated(Source::Cli);
let file = Config { num: None, str: Some("ten"), boolean: false }.annotated(Source::File);
let env = Config { num: Some(100), str: None, boolean: false }.annotated(Source::Env);
let lazy = Lazy::from(cli).semigroup(file.into()).semigroup(env.into());
assert_eq!(lazy.first().value(), &Config { num: Some(1), str: None, boolean: true });
assert_eq!(lazy.last().value(), &Config { num: Some(100), str: None, boolean: false });
let config = lazy.combine();
assert_eq!(config.value(), &Config { num: Some(1), str: Some("ten"), boolean: false });
assert_eq!(config.annotation().num, Source::Cli);
assert_eq!(config.annotation().str, Source::File);
assert_eq!(config.annotation().boolean, Source::Env);
#[derive(Semigroup)] and #[derive(Construction)]
Semigroup] implements semigroup for a struct by field level semantics.Construction] defines a new semigroup operation (Some operations are already defined in [crate::op]).op::Coalesce] can have an annotation that is represented by [Annotate] trait.CombineIterator] provides fold and combine operations for iterators.Lazy] provides lazy evaluation.segment_tree::SegmentTree] is useful for fast range queries on [Monoid].[Semigroup] |
[Annotate] |
[Monoid] |
[Commutative] |
|
|---|---|---|---|---|
| property | associativity | annotation | identity element | commutativity |
#[derive(Semigroup)] #[semigroup(...)] |
annotated |
monoid |
commutative |
|
#[derive(Construction)] #[construction(...)] |
annotated |
monoid |
commutative |
|
| testing | [assert_semigroup!] |
[assert_monoid!] |
[assert_commutative!] |
|
| typical combiner | [CombineIterator] |
[Lazy] |
SegmentTree |
[CombineStream] |
// TODO
https://hayas1.github.io/semigroup/semigroup/tarpaulin-report.html