1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
//! # score-set
//!
//! A Rust library for building **weighted scoring operator sets** with three
//! dispatch strategies — from compile-time fixed to fully dynamic.
//!
//! It does not prescribe a unified input or context type. Instead it declares,
//! stores, normalizes, and combines a set of weighted operators.
//!
//! # Three-layer architecture
//!
//! | Layer | Type | Dispatch | When to use |
//! |---|---|---|---|
//! | 1 — fixed | [`FixedScoreSet`] via [`fixed_score_set!`] | Compile-time, zero vtable | Known metric set at compile time |
//! | 2 — finite | [`FiniteScoreSet`] via [`finite_score_set!`] | Enum match, zero vtable | Runtime composition, known metric types |
//! | 3 — dynamic | [`DynamicScoreSet`] via [`dynamic_score_set!`] | Vtable per call | Fully heterogeneous, runtime assembly |
//!
//! # Quick example (Layer 1 — fixed)
//!
//! ```ignore
//! use score_set::*;
//!
//! let gc = metric("gc")
//! .measure().by(|dna: &&str| gc_ratio(dna))
//! .map01().by(|raw: &f64, _: &&str| Value01::witness(*raw).unwrap());
//!
//! let len = metric("len")
//! .measure().by(|len: &usize| *len)
//! .map01().by(|raw: &usize, _: &usize| {
//! Value01::witness((*raw as f64 / 100.0).min(1.0)).unwrap()
//! });
//!
//! let ms = fixed_score_set! {
//! 2.0 => gc,
//! 3.0 => len,
//! }?;
//!
//! let dna = "ACGTACGT";
//! let score = ms.score().by(|(gc, len)| {
//! gc.contribute(gc.metric().eval(&dna))
//! + len.contribute(len.metric().eval(&dna.len()))
//! });
//! # Ok::<(), &'static str>(())
//! ```
// Public API
pub use Breakdown;
pub use ;
pub use ;
pub use *;
pub use ;
pub use Float;
// fixed_score_set!, dynamic_score_set!, and finite_metric! are exported at crate root via #[macro_export]
pub use ;
pub use ;
pub use ;
pub use ;