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
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
/* CollectionExtract trait for ergonomic entity collection extraction.
Allows extractor closures to return either `&[A]` or `&Vec<A>`,
so users can write `vec(|s| &s.employees)` without `.as_slice()`.
# Usage
```
use solverforge_scoring::stream::collection_extract::{CollectionExtract, VecExtract, vec};
struct Schedule { employees: Vec<String> }
// Direct slice closure — works out of the box:
let e1 = |s: &Schedule| s.employees.as_slice();
let _: &[String] = e1.extract(&Schedule { employees: vec![] });
// Vec reference closure — wrap with `vec(...)`:
let e2 = vec(|s: &Schedule| &s.employees);
let _: &[String] = e2.extract(&Schedule { employees: vec![] });
```
*/
/* Extracts a slice of entities from the solution.
The associated type `Item` names the entity type, allowing callers to
write `E: CollectionExtract<S, Item = A>` when `A` must be inferred from `E`
rather than stated as a separate generic parameter.
*/
/* Wraps a `Fn(&S) -> &Vec<A>` closure so it satisfies `CollectionExtract<S>`.
Construct via the [`vec`] free function.
*/
;
/* Wraps a `Fn(&S) -> &Vec<A>` closure into a [`VecExtract`] that satisfies
[`CollectionExtract<S>`].
Use this when your solution field is a `Vec<A>` and you want to write
`|s| &s.field` instead of `|s| s.field.as_slice()`.
# Example
```
use solverforge_scoring::stream::collection_extract::{CollectionExtract, vec};
struct Schedule { employees: Vec<String> }
let extractor = vec(|s: &Schedule| &s.employees);
let schedule = Schedule { employees: vec!["Alice".into()] };
assert_eq!(extractor.extract(&schedule), &["Alice".to_string()]);
```
*/