Skip to main content

blvm_sdk/composition/
conversion.rs

1//! Type Conversions
2//!
3//! Conversions between blvm-sdk composition types and blvm-node module types.
4
5use crate::composition::types::ModuleInfo;
6use blvm_node::module::registry::DiscoveredModule as RefDiscoveredModule;
7use blvm_node::module::traits::ModuleError as RefModuleError;
8use blvm_node::module::traits::ModuleMetadata as RefModuleMetadata;
9use std::collections::HashMap;
10
11impl From<&RefDiscoveredModule> for ModuleInfo {
12    fn from(discovered: &RefDiscoveredModule) -> Self {
13        ModuleInfo {
14            name: discovered.manifest.name.clone(),
15            version: discovered.manifest.version.clone(),
16            description: discovered.manifest.description.clone(),
17            author: discovered.manifest.author.clone(),
18            capabilities: discovered.manifest.capabilities.clone(),
19            dependencies: discovered.manifest.dependencies.clone(),
20            entry_point: discovered.manifest.entry_point.clone(),
21            directory: Some(discovered.directory.clone()),
22            binary_path: Some(discovered.binary_path.clone()),
23            config_schema: discovered.manifest.config_schema.clone(),
24        }
25    }
26}
27
28impl From<RefDiscoveredModule> for ModuleInfo {
29    fn from(discovered: RefDiscoveredModule) -> Self {
30        Self::from(&discovered)
31    }
32}
33
34impl From<&RefModuleMetadata> for ModuleInfo {
35    fn from(metadata: &RefModuleMetadata) -> Self {
36        ModuleInfo {
37            name: metadata.name.clone(),
38            version: metadata.version.clone(),
39            description: Some(metadata.description.clone()),
40            author: Some(metadata.author.clone()),
41            capabilities: metadata.capabilities.clone(),
42            dependencies: metadata.dependencies.clone(),
43            entry_point: metadata.entry_point.clone(),
44            directory: None,
45            binary_path: None,
46            config_schema: HashMap::new(),
47        }
48    }
49}
50
51impl From<RefModuleMetadata> for ModuleInfo {
52    fn from(metadata: RefModuleMetadata) -> Self {
53        Self::from(&metadata)
54    }
55}
56
57impl From<ModuleInfo> for RefModuleMetadata {
58    fn from(info: ModuleInfo) -> Self {
59        RefModuleMetadata {
60            name: info.name,
61            version: info.version,
62            description: info.description.unwrap_or_default(),
63            author: info.author.unwrap_or_default(),
64            capabilities: info.capabilities,
65            rpc_overrides: Vec::new(),
66            dependencies: info.dependencies,
67            optional_dependencies: HashMap::new(), // ModuleInfo doesn't track optional deps separately
68            entry_point: info.entry_point,
69        }
70    }
71}
72
73impl From<RefModuleError> for crate::composition::types::CompositionError {
74    fn from(err: RefModuleError) -> Self {
75        match err {
76            RefModuleError::CryptoError(msg) => {
77                crate::composition::types::CompositionError::InstallationFailed(format!(
78                    "Crypto error: {msg}"
79                ))
80            }
81            RefModuleError::ModuleNotFound(name) => {
82                crate::composition::types::CompositionError::ModuleNotFound(name)
83            }
84            RefModuleError::InvalidManifest(msg) => {
85                crate::composition::types::CompositionError::InvalidConfiguration(msg)
86            }
87            RefModuleError::OperationError(msg) => {
88                crate::composition::types::CompositionError::InstallationFailed(msg)
89            }
90            RefModuleError::DependencyMissing(msg) => {
91                crate::composition::types::CompositionError::DependencyResolutionFailed(msg)
92            }
93            RefModuleError::PermissionDenied(msg) => {
94                crate::composition::types::CompositionError::InstallationFailed(format!(
95                    "Permission denied: {msg}"
96                ))
97            }
98            RefModuleError::IpcError(msg) => {
99                crate::composition::types::CompositionError::InstallationFailed(format!(
100                    "IPC error: {msg}"
101                ))
102            }
103            RefModuleError::InitializationError(msg) => {
104                crate::composition::types::CompositionError::InstallationFailed(format!(
105                    "Initialization error: {msg}"
106                ))
107            }
108            RefModuleError::VersionIncompatible(msg) => {
109                crate::composition::types::CompositionError::InstallationFailed(format!(
110                    "Version incompatible: {msg}"
111                ))
112            }
113            RefModuleError::ModuleCrashed(msg) => {
114                crate::composition::types::CompositionError::InstallationFailed(format!(
115                    "Module crashed: {msg}"
116                ))
117            }
118            RefModuleError::SerializationError(msg) => {
119                crate::composition::types::CompositionError::SerializationError(msg)
120            }
121            RefModuleError::RateLimitExceeded(msg) => {
122                crate::composition::types::CompositionError::InstallationFailed(format!(
123                    "Rate limit exceeded: {msg}"
124                ))
125            }
126            RefModuleError::Timeout => {
127                crate::composition::types::CompositionError::InstallationFailed(
128                    "Timeout waiting for module response".to_string(),
129                )
130            }
131            RefModuleError::ResourceLimitExceeded(msg) => {
132                crate::composition::types::CompositionError::InstallationFailed(format!(
133                    "Resource limit exceeded: {msg}"
134                ))
135            }
136            RefModuleError::Config(msg) => {
137                crate::composition::types::CompositionError::InvalidConfiguration(msg)
138            }
139            RefModuleError::Rpc(msg) => {
140                crate::composition::types::CompositionError::InstallationFailed(format!(
141                    "RPC error: {msg}"
142                ))
143            }
144            RefModuleError::Migration(msg) => {
145                crate::composition::types::CompositionError::InstallationFailed(format!(
146                    "Migration error: {msg}"
147                ))
148            }
149            RefModuleError::Cli(msg) => {
150                crate::composition::types::CompositionError::InstallationFailed(format!(
151                    "CLI error: {msg}"
152                ))
153            }
154            RefModuleError::Other(msg) => {
155                crate::composition::types::CompositionError::InstallationFailed(msg)
156            }
157        }
158    }
159}