1
use super::stored::ReprRuleStored;
2
use crate::bug;
3
use serde::{Deserialize, Deserializer, Serialize, Serializer};
4

            
5
pub type ReprRulePtr = &'static dyn ReprRuleStored;
6

            
7
inventory::collect!(ReprRulePtr);
8

            
9
5184989
pub fn get_repr_rules() -> impl Iterator<Item = ReprRulePtr> {
10
5184989
    inventory::iter::<ReprRulePtr>.into_iter().copied()
11
5184989
}
12

            
13
4918218
pub fn get_repr_by_name(name: &str) -> Option<ReprRulePtr> {
14
4918218
    inventory::iter::<ReprRulePtr>
15
4918218
        .into_iter()
16
4918218
        .copied()
17
47630701
        .find(|rule| rule.name() == name)
18
4918218
}
19

            
20
/// Look up a representation by short name that is applicable to `decl`.
21
///
22
/// Short names are not unique -- nine representations are called `packed` -- so a declaration is
23
/// required to disambiguate, via [`ReprRuleStored::probe_for`]. There is deliberately no lookup by
24
/// short name alone.
25
124
pub fn get_applicable_repr_by_short_name(
26
124
    decl: &crate::ast::DeclarationPtr,
27
124
    short_name: &str,
28
124
) -> Option<ReprRulePtr> {
29
124
    inventory::iter::<ReprRulePtr>
30
124
        .into_iter()
31
124
        .copied()
32
2759
        .find(|rule| rule.short_name() == short_name && rule.probe_for(decl).is_ok())
33
124
}
34

            
35
impl Serialize for ReprRulePtr {
36
    fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
37
    where
38
        S: Serializer,
39
    {
40
        self.name().serialize(serializer)
41
    }
42
}
43

            
44
impl<'de> Deserialize<'de> for ReprRulePtr {
45
    fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
46
    where
47
        D: Deserializer<'de>,
48
    {
49
        let name = String::deserialize(deserializer)?;
50
        let res = get_repr_by_name(&name)
51
            .unwrap_or_else(|| bug!("Unknown representation rule: {}", name));
52
        Ok(res)
53
    }
54
}