geop_core_program/
operation_registry.rs1use std::{collections::BTreeMap, rc::Rc};
2
3use geop_core_math::geop_error::{GeopError, GeopResult};
4
5use crate::operation::{ErasedOperation, Operation};
6
7#[derive(Clone, Default)]
9pub struct OperationRegistry(BTreeMap<&'static str, Rc<dyn ErasedOperation>>);
10
11impl OperationRegistry {
12 pub fn with<O: Operation>(self, operation: O) -> GeopResult<Self> {
15 self.with_erased(Rc::new(operation))
16 }
17
18 pub fn with_erased(mut self, operation: Rc<dyn ErasedOperation>) -> GeopResult<Self> {
20 let kind = operation.kind();
21 if self.0.contains_key(kind) {
22 return Err(GeopError::new(format!(
23 "operation `{kind}` is registered twice"
24 )));
25 }
26 self.0.insert(kind, operation);
27 Ok(self)
28 }
29
30 pub fn get(&self, name: &str) -> GeopResult<&dyn ErasedOperation> {
31 self.0
32 .get(name)
33 .map(Rc::as_ref)
34 .ok_or_else(|| GeopError::new(format!("unknown operation `{name}`")))
35 }
36}