harmos_domain/operations/common/
catalog.rs1use std::collections::BTreeSet;
18use super::{Declares, Definition, OperationDeclaration, OperationPolicy, ReplaySafety, Visibility};
22use crate::catalog::{self, Catalog, Member, Node, Projection, Visitor};
23use crate::{Error, Identifier, Result};
24
25#[derive(Clone, Copy, Debug, PartialEq, Eq)]
34pub struct Entry {
35 pub id: &'static str,
36 pub description: &'static str,
37 pub policy: OperationPolicy,
38 pub visibility: Visibility,
39 pub replay: ReplaySafety,
40}
41
42pub struct Declarations;
43
44impl Entry {
51 pub const fn of<O: OperationDeclaration>() -> Self {
52 Self { id: O::ID, description: O::DESCRIPTION, policy: O::POLICY, visibility: O::VISIBILITY, replay: O::REPLAY }
53 }
54
55 pub fn definition(&self) -> Result<Definition> {
56 let id = Identifier::new(self.id)?;
57 let definition = Definition {
58 id,
59 description: self.description.to_owned(),
60 policy: self.policy,
61 visibility: self.visibility,
62 replay: self.replay,
63 };
64 definition.validate()?;
65 Ok(definition)
66 }
67}
68
69impl Visitor for Declarations {
70 type Entry = Entry;
71}
72
73impl<M: Declares> Member<M> for Declarations {
74 const ENTRY: Entry = Entry::of::<M::Declaration>();
75}
76
77impl Declarations {
78 pub fn of<C: Catalog<Self>>() -> Result<Vec<Definition>> {
79 Self::from_projection(&C::ENTRIES)
80 }
81
82 pub fn from_entries(entries: &[Entry]) -> Result<Vec<Definition>> {
83 let mut names = BTreeSet::new();
84 let mut definitions = Vec::with_capacity(entries.len());
85 for declaration in entries {
86 append(declaration, &mut names, &mut definitions)?;
87 }
88 Ok(definitions)
89 }
90
91 pub fn from_tree(entries: &[Node<Entry>]) -> Result<Vec<Definition>> {
92 let mut names = BTreeSet::new();
93 let mut definitions = Vec::with_capacity(catalog::count(entries));
94 catalog::try_for_each(entries, |declaration| append(declaration, &mut names, &mut definitions))?;
95 Ok(definitions)
96 }
97
98 pub fn from_projection<P: Projection<Entry>>(entries: &P) -> Result<Vec<Definition>> {
99 let mut names = BTreeSet::new();
100 let mut definitions = Vec::with_capacity(P::LEN);
101 entries.try_for_each(|declaration| append(declaration, &mut names, &mut definitions))?;
102 Ok(definitions)
103 }
104}
105
106fn append(declaration: &Entry, names: &mut BTreeSet<Identifier>, definitions: &mut Vec<Definition>) -> Result<()> {
111 let definition = declaration.definition()?;
112 if !names.insert(definition.id.clone()) {
113 return Err(Error::DuplicateOperation { id: declaration.id.to_owned() });
114 }
115 definitions.push(definition);
116 Ok(())
117}
118
119