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            dependencies: info.dependencies,
66            optional_dependencies: HashMap::new(), // ModuleInfo doesn't track optional deps separately
67            entry_point: info.entry_point,
68        }
69    }
70}
71
72impl From<RefModuleError> for crate::composition::types::CompositionError {
73    fn from(err: RefModuleError) -> Self {
74        match err {
75            RefModuleError::CryptoError(msg) => {
76                crate::composition::types::CompositionError::InstallationFailed(format!(
77                    "Crypto error: {msg}"
78                ))
79            }
80            RefModuleError::ModuleNotFound(name) => {
81                crate::composition::types::CompositionError::ModuleNotFound(name)
82            }
83            RefModuleError::InvalidManifest(msg) => {
84                crate::composition::types::CompositionError::InvalidConfiguration(msg)
85            }
86            RefModuleError::OperationError(msg) => {
87                crate::composition::types::CompositionError::InstallationFailed(msg)
88            }
89            RefModuleError::DependencyMissing(msg) => {
90                crate::composition::types::CompositionError::DependencyResolutionFailed(msg)
91            }
92            RefModuleError::PermissionDenied(msg) => {
93                crate::composition::types::CompositionError::InstallationFailed(format!(
94                    "Permission denied: {msg}"
95                ))
96            }
97            RefModuleError::IpcError(msg) => {
98                crate::composition::types::CompositionError::InstallationFailed(format!(
99                    "IPC error: {msg}"
100                ))
101            }
102            RefModuleError::InitializationError(msg) => {
103                crate::composition::types::CompositionError::InstallationFailed(format!(
104                    "Initialization error: {msg}"
105                ))
106            }
107            RefModuleError::VersionIncompatible(msg) => {
108                crate::composition::types::CompositionError::InstallationFailed(format!(
109                    "Version incompatible: {msg}"
110                ))
111            }
112            RefModuleError::ModuleCrashed(msg) => {
113                crate::composition::types::CompositionError::InstallationFailed(format!(
114                    "Module crashed: {msg}"
115                ))
116            }
117            RefModuleError::SerializationError(msg) => {
118                crate::composition::types::CompositionError::SerializationError(msg)
119            }
120            RefModuleError::RateLimitExceeded(msg) => {
121                crate::composition::types::CompositionError::InstallationFailed(format!(
122                    "Rate limit exceeded: {msg}"
123                ))
124            }
125            RefModuleError::Timeout => {
126                crate::composition::types::CompositionError::InstallationFailed(
127                    "Timeout waiting for module response".to_string(),
128                )
129            }
130            RefModuleError::ResourceLimitExceeded(msg) => {
131                crate::composition::types::CompositionError::InstallationFailed(format!(
132                    "Resource limit exceeded: {msg}"
133                ))
134            }
135            RefModuleError::Config(msg) => {
136                crate::composition::types::CompositionError::InvalidConfiguration(msg)
137            }
138            RefModuleError::Rpc(msg) => {
139                crate::composition::types::CompositionError::InstallationFailed(format!(
140                    "RPC error: {msg}"
141                ))
142            }
143            RefModuleError::Migration(msg) => {
144                crate::composition::types::CompositionError::InstallationFailed(format!(
145                    "Migration error: {msg}"
146                ))
147            }
148            RefModuleError::Cli(msg) => {
149                crate::composition::types::CompositionError::InstallationFailed(format!(
150                    "CLI error: {msg}"
151                ))
152            }
153            RefModuleError::Other(msg) => {
154                crate::composition::types::CompositionError::InstallationFailed(msg)
155            }
156        }
157    }
158}