Skip to main content

substrate_data/schema/refs/
id.rs

1//! [`Id`]: the id of something of a kind, of that kind's id type.
2
3use std::fmt;
4use std::marker::PhantomData;
5
6use super::{Kind, RefId, read_id, ref_shape};
7use crate::frame::{Packer, Unpacker};
8use crate::model::borrowed::ValueRef;
9use crate::model::value::{Ref, Value};
10use crate::schema::{Reader, Schema, Shape};
11
12/// The id of something of kind `K`, of `K`'s id type: written
13/// `@file:images/logo.png`, `@user:42`.
14pub struct Id<K: Kind> {
15    /// The id.
16    pub id: K::Id,
17    kind: PhantomData<K>,
18}
19
20impl<K: Kind> Id<K> {
21    /// The id `id` of something of kind `K`.
22    pub fn new(id: impl Into<K::Id>) -> Self {
23        Self {
24            id: id.into(),
25            kind: PhantomData,
26        }
27    }
28
29    /// As a reference.
30    pub fn to_ref(&self) -> Ref {
31        Ref::of::<K>(&self.id)
32    }
33}
34
35impl<K: Kind> Clone for Id<K> {
36    fn clone(&self) -> Self {
37        Self::new(self.id.clone())
38    }
39}
40impl<K: Kind> PartialEq for Id<K> {
41    fn eq(&self, o: &Self) -> bool {
42        self.id == o.id
43    }
44}
45impl<K: Kind> Eq for Id<K> where K::Id: Eq {}
46impl<K: Kind> std::hash::Hash for Id<K>
47where
48    K::Id: std::hash::Hash,
49{
50    fn hash<H: std::hash::Hasher>(&self, h: &mut H) {
51        self.id.hash(h);
52    }
53}
54impl<K: Kind> fmt::Debug for Id<K> {
55    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
56        write!(f, "@{}:{}", K::NAME, self.id.spell())
57    }
58}
59impl<K: Kind> fmt::Display for Id<K> {
60    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
61        f.write_str(&self.id.spell())
62    }
63}
64
65/// In a frame, only its id (the kind is the field's).
66impl<K: Kind> Schema for Id<K> {
67    fn shape() -> Shape {
68        ref_shape::<K>()
69    }
70    fn read(v: &ValueRef<'_>, cx: &mut Reader<'_>) -> Option<Self> {
71        read_id::<K>(v, cx).map(Id::new)
72    }
73    fn write(&self) -> Value {
74        Value::Ref(self.to_ref())
75    }
76    fn pack(&self, p: &mut Packer) {
77        self.id.pack(p);
78    }
79    fn unpack(u: &mut Unpacker<'_>) -> Option<Self> {
80        K::Id::unpack(u).map(Id::new)
81    }
82}