openzeppelin_monitor/repositories/
network.rs1#![allow(clippy::result_large_err)]
8
9use std::{collections::HashMap, path::Path};
10
11use async_trait::async_trait;
12
13use crate::{
14 models::{ConfigLoader, Network},
15 repositories::error::RepositoryError,
16};
17
18#[derive(Clone)]
20pub struct NetworkRepository {
21 pub networks: HashMap<String, Network>,
23}
24
25impl NetworkRepository {
26 pub async fn new(path: Option<&Path>) -> Result<Self, RepositoryError> {
31 let networks = Self::load_all(path).await?;
32 Ok(NetworkRepository { networks })
33 }
34}
35
36#[async_trait]
41pub trait NetworkRepositoryTrait: Clone {
42 async fn new(path: Option<&Path>) -> Result<Self, RepositoryError>
44 where
45 Self: Sized;
46
47 async fn load_all(path: Option<&Path>) -> Result<HashMap<String, Network>, RepositoryError>;
52
53 fn get(&self, network_id: &str) -> Option<Network>;
57
58 fn get_all(&self) -> HashMap<String, Network>;
62}
63
64#[async_trait]
65impl NetworkRepositoryTrait for NetworkRepository {
66 async fn new(path: Option<&Path>) -> Result<Self, RepositoryError> {
67 NetworkRepository::new(path).await
68 }
69
70 async fn load_all(path: Option<&Path>) -> Result<HashMap<String, Network>, RepositoryError> {
71 Network::load_all(path).await.map_err(|e| {
72 RepositoryError::load_error(
73 "Failed to load networks",
74 Some(Box::new(e)),
75 Some(HashMap::from([(
76 "path".to_string(),
77 path.map_or_else(|| "default".to_string(), |p| p.display().to_string()),
78 )])),
79 )
80 })
81 }
82
83 fn get(&self, network_id: &str) -> Option<Network> {
84 self.networks.get(network_id).cloned()
85 }
86
87 fn get_all(&self) -> HashMap<String, Network> {
88 self.networks.clone()
89 }
90}
91
92#[derive(Clone)]
98pub struct NetworkService<T: NetworkRepositoryTrait> {
99 repository: T,
100}
101
102impl<T: NetworkRepositoryTrait> NetworkService<T> {
103 pub async fn new(
105 path: Option<&Path>,
106 ) -> Result<NetworkService<NetworkRepository>, RepositoryError> {
107 let repository = NetworkRepository::new(path).await?;
108 Ok(NetworkService { repository })
109 }
110
111 pub fn new_with_repository(repository: T) -> Result<Self, RepositoryError> {
113 Ok(NetworkService { repository })
114 }
115
116 pub async fn new_with_path(
118 path: Option<&Path>,
119 ) -> Result<NetworkService<NetworkRepository>, RepositoryError> {
120 let repository = NetworkRepository::new(path).await?;
121 Ok(NetworkService { repository })
122 }
123
124 pub fn get(&self, network_id: &str) -> Option<Network> {
126 self.repository.get(network_id)
127 }
128
129 pub fn get_all(&self) -> HashMap<String, Network> {
131 self.repository.get_all()
132 }
133}
134
135#[cfg(test)]
136mod tests {
137 use super::*;
138
139 #[tokio::test]
140 async fn test_load_error_messages() {
141 let invalid_path = Path::new("/non/existent/path");
143 let result = NetworkRepository::load_all(Some(invalid_path)).await;
144
145 assert!(result.is_err());
146 let err = result.unwrap_err();
147 match err {
148 RepositoryError::LoadError(message) => {
149 assert!(message.to_string().contains("Failed to load networks"));
150 }
151 _ => panic!("Expected RepositoryError::LoadError"),
152 }
153 }
154}