Skip to main content

recoco_core/ops/
registry.rs

1// ReCoco is a Rust-only fork of CocoIndex, by [CocoIndex](https://CocoIndex)
2// Original code from CocoIndex is copyrighted by CocoIndex
3// SPDX-FileCopyrightText: 2025-2026 CocoIndex (upstream)
4// SPDX-FileContributor: CocoIndex Contributors
5//
6// All modifications from the upstream for ReCoco are copyrighted by Knitli Inc.
7// SPDX-FileCopyrightText: 2026 Knitli Inc. (ReCoco)
8// SPDX-FileContributor: Adam Poulemanos <adam@knit.li>
9//
10// Both the upstream CocoIndex code and the ReCoco modifications are licensed under the Apache-2.0 License.
11// SPDX-License-Identifier: Apache-2.0
12
13use super::interface::ExecutorFactory;
14use crate::prelude::*;
15use recoco_utils::internal_error;
16use std::collections::HashMap;
17use std::sync::Arc;
18
19pub struct ExecutorFactoryRegistry {
20    source_factories: HashMap<String, Arc<dyn super::interface::SourceFactory + Send + Sync>>,
21    function_factories:
22        HashMap<String, Arc<dyn super::interface::SimpleFunctionFactory + Send + Sync>>,
23    target_factories: HashMap<String, Arc<dyn super::interface::TargetFactory + Send + Sync>>,
24    target_attachment_factories:
25        HashMap<String, Arc<dyn super::interface::TargetAttachmentFactory + Send + Sync>>,
26}
27
28impl Default for ExecutorFactoryRegistry {
29    fn default() -> Self {
30        Self::new()
31    }
32}
33
34impl ExecutorFactoryRegistry {
35    pub fn new() -> Self {
36        Self {
37            source_factories: HashMap::new(),
38            function_factories: HashMap::new(),
39            target_factories: HashMap::new(),
40            target_attachment_factories: HashMap::new(),
41        }
42    }
43
44    pub fn register(&mut self, name: String, factory: ExecutorFactory) -> Result<()> {
45        match factory {
46            ExecutorFactory::Source(source_factory) => match self.source_factories.entry(name) {
47                std::collections::hash_map::Entry::Occupied(entry) => Err(internal_error!(
48                    "Source factory with name already exists: {}",
49                    entry.key()
50                )),
51                std::collections::hash_map::Entry::Vacant(entry) => {
52                    entry.insert(source_factory);
53                    Ok(())
54                }
55            },
56            ExecutorFactory::SimpleFunction(function_factory) => {
57                match self.function_factories.entry(name) {
58                    std::collections::hash_map::Entry::Occupied(entry) => Err(internal_error!(
59                        "Function factory with name already exists: {}",
60                        entry.key()
61                    )),
62                    std::collections::hash_map::Entry::Vacant(entry) => {
63                        entry.insert(function_factory);
64                        Ok(())
65                    }
66                }
67            }
68            ExecutorFactory::ExportTarget(target_factory) => {
69                match self.target_factories.entry(name) {
70                    std::collections::hash_map::Entry::Occupied(entry) => Err(internal_error!(
71                        "Target factory with name already exists: {}",
72                        entry.key()
73                    )),
74                    std::collections::hash_map::Entry::Vacant(entry) => {
75                        entry.insert(target_factory);
76                        Ok(())
77                    }
78                }
79            }
80            ExecutorFactory::TargetAttachment(target_attachment_factory) => {
81                match self.target_attachment_factories.entry(name) {
82                    std::collections::hash_map::Entry::Occupied(entry) => Err(internal_error!(
83                        "Target attachment factory with name already exists: {}",
84                        entry.key()
85                    )),
86                    std::collections::hash_map::Entry::Vacant(entry) => {
87                        entry.insert(target_attachment_factory);
88                        Ok(())
89                    }
90                }
91            }
92        }
93    }
94
95    pub fn get_source(
96        &self,
97        name: &str,
98    ) -> Option<&Arc<dyn super::interface::SourceFactory + Send + Sync>> {
99        self.source_factories.get(name)
100    }
101
102    pub fn get_function(
103        &self,
104        name: &str,
105    ) -> Option<&Arc<dyn super::interface::SimpleFunctionFactory + Send + Sync>> {
106        self.function_factories.get(name)
107    }
108
109    pub fn get_target(
110        &self,
111        name: &str,
112    ) -> Option<&Arc<dyn super::interface::TargetFactory + Send + Sync>> {
113        self.target_factories.get(name)
114    }
115
116    pub fn get_target_attachment(
117        &self,
118        name: &str,
119    ) -> Option<&Arc<dyn super::interface::TargetAttachmentFactory + Send + Sync>> {
120        self.target_attachment_factories.get(name)
121    }
122}