Skip to main content

conjure_cp_core/representation/
registry.rs

1use super::stored::ReprRuleStored;
2use crate::bug;
3use serde::{Deserialize, Deserializer, Serialize, Serializer};
4
5pub type ReprRulePtr = &'static dyn ReprRuleStored;
6
7inventory::collect!(ReprRulePtr);
8
9pub fn get_repr_rules() -> impl Iterator<Item = ReprRulePtr> {
10    inventory::iter::<ReprRulePtr>.into_iter().copied()
11}
12
13pub fn get_repr_by_name(name: &str) -> Option<ReprRulePtr> {
14    inventory::iter::<ReprRulePtr>
15        .into_iter()
16        .copied()
17        .find(|rule| rule.name() == name)
18}
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.
25pub fn get_applicable_repr_by_short_name(
26    decl: &crate::ast::DeclarationPtr,
27    short_name: &str,
28) -> Option<ReprRulePtr> {
29    inventory::iter::<ReprRulePtr>
30        .into_iter()
31        .copied()
32        .find(|rule| rule.short_name() == short_name && rule.probe_for(decl).is_ok())
33}
34
35impl 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
44impl<'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}