Skip to main content

jstd/
num_ref.rs

1use jstd::registry::Identifier;
2
3/// A generic wrapper struct for referencing an ID with a context.
4/// This is the basis for all `*Ref` and `*MutRef`
5pub struct BaseRef<Ctx, Id: Identifier> {
6    pub id: Id,
7    pub ctx: Ctx,
8}
9
10impl<Ctx, Id: Identifier> BaseRef<Ctx, Id> {
11    pub fn new(ctx: Ctx, id: Id) -> Self {
12        BaseRef { id, ctx }
13    }
14}
15
16impl<Ctx, Id: Identifier> BaseRef<Ctx, Id> {
17    pub fn from_id(ctx: Ctx, id: Id) -> Self {
18        BaseRef { id, ctx }
19    }
20}
21
22/// Convert mutable refs to immutable refs by cloning the ID and sharing the context reference.
23impl<'ctx, Ctx, Id: Identifier> From<BaseRef<&'ctx mut Ctx, Id>> for BaseRef<&'ctx Ctx, Id> {
24    fn from(r: BaseRef<&'ctx mut Ctx, Id>) -> Self {
25        BaseRef {
26            id: r.id,
27            ctx: r.ctx,
28        }
29    }
30}
31
32#[cfg(test)]
33mod tests {
34    use super::BaseRef;
35
36    #[test]
37    fn constructors_keep_context_and_identifier() {
38        let reference = BaseRef::new("context", 7_usize);
39        let from_id = BaseRef::from_id("other", 9_usize);
40
41        assert_eq!(reference.ctx, "context");
42        assert_eq!(reference.id, 7);
43        assert_eq!(from_id.ctx, "other");
44        assert_eq!(from_id.id, 9);
45    }
46
47    #[test]
48    fn mutable_context_reference_converts_to_shared_reference() {
49        let mut context = String::from("context");
50        let mutable = BaseRef::new(&mut context, 3_usize);
51        let shared: BaseRef<&String, usize> = mutable.into();
52
53        assert_eq!(shared.id, 3);
54        assert_eq!(shared.ctx, "context");
55    }
56}