From a80b9bcdf1edd9e321f1acf025b680f9ae0b3ecf Mon Sep 17 00:00:00 2001 From: fluo10 Date: Thu, 19 Jun 2025 07:24:44 +0900 Subject: [PATCH] Add global traits --- lazy-supplements-core/src/config/mod.rs | 67 ++++++++- .../src/config/{core.rs => p2p.rs} | 46 ++++-- lazy-supplements-core/src/config/storage.rs | 91 +++++++++++ lazy-supplements-core/src/global/database.rs | 64 -------- .../src/global/database_connection.rs | 32 ++++ lazy-supplements-core/src/global/mod.rs | 141 +++--------------- lazy-supplements-core/src/global/peers.rs | 18 +++ .../src/global/storage_config.rs | 22 +++ lazy-supplements-core/src/lib.rs | 1 + lazy-supplements-core/src/message.rs | 15 ++ lazy-supplements-core/src/p2p/mod.rs | 8 +- lazy-supplements-core/src/tests.rs | 23 +++ 12 files changed, 320 insertions(+), 208 deletions(-) rename lazy-supplements-core/src/config/{core.rs => p2p.rs} (80%) create mode 100644 lazy-supplements-core/src/config/storage.rs delete mode 100644 lazy-supplements-core/src/global/database.rs create mode 100644 lazy-supplements-core/src/global/database_connection.rs create mode 100644 lazy-supplements-core/src/global/peers.rs create mode 100644 lazy-supplements-core/src/global/storage_config.rs create mode 100644 lazy-supplements-core/src/message.rs diff --git a/lazy-supplements-core/src/config/mod.rs b/lazy-supplements-core/src/config/mod.rs index 41d9304..6e8b7d8 100644 --- a/lazy-supplements-core/src/config/mod.rs +++ b/lazy-supplements-core/src/config/mod.rs @@ -1,22 +1,31 @@ pub mod error; -mod core; +mod storage; +mod p2p; use std::path::Path; use crate::error::Error; -pub use core::{ CoreConfig, PartialCoreConfig }; pub use error::ConfigError; use serde::{de::DeserializeOwned, Deserialize, Serialize}; use tokio::{fs::File, io::{AsyncReadExt, AsyncWriteExt}}; +pub use storage::{StorageConfig, PartialStorageConfig}; +pub use p2p::{P2pConfig, PartialP2pConfig}; +pub trait PartialConfig: Serialize + Sized + DeserializeOwned +{ -pub trait PartialConfig: From -where T: TryFrom { fn default() -> Self; fn empty() -> Self; fn merge(&mut self, other: Self); + fn from_toml(s: &str) -> Result { + toml::from_str(s) + } + fn into_toml(&self) -> Result { + toml::to_string(self) + } + fn is_empty(&self) -> bool; } -pub trait ConfigFile: DeserializeOwned + Serialize { +pub trait ConfigRoot: DeserializeOwned + Serialize { fn new() -> Self; async fn read_or_create(path: T) -> Result @@ -52,4 +61,52 @@ pub trait ConfigFile: DeserializeOwned + Serialize { file.write_all(toml::to_string(self)?.as_bytes()).await?; Ok(()) } +} + +#[cfg(test)] +mod tests { + use serde::{Deserialize, Serialize}; + + use crate::tests::test_toml_serialize_deserialize; + + use super::{p2p::{P2pConfig, PartialP2pConfig}, PartialConfig}; + + #[derive(Debug, Deserialize, Serialize, PartialEq)] + pub struct TestConfig { + + p2p: Option + } + + impl PartialConfig for TestConfig { + fn default() -> Self { + Self { + p2p: Some(PartialP2pConfig::default()), + } + } + + fn empty() -> Self { + Self { + p2p: None, + } + } + + fn is_empty(&self) -> bool { + self.p2p.is_none() + } + + fn merge(&mut self, other: Self) { + if let Some(p2p) = other.p2p { + self.p2p = Some(p2p); + } + } + } + + #[tokio::test] + async fn test_p2p_config_serialize_deserialize() { + test_toml_serialize_deserialize(TestConfig::empty()); + test_toml_serialize_deserialize(TestConfig::default()); + assert_eq!(TestConfig::empty(), toml::from_str("").unwrap()); + assert_eq!("", &toml::to_string(&TestConfig::empty()).unwrap()); + } + } \ No newline at end of file diff --git a/lazy-supplements-core/src/config/core.rs b/lazy-supplements-core/src/config/p2p.rs similarity index 80% rename from lazy-supplements-core/src/config/core.rs rename to lazy-supplements-core/src/config/p2p.rs index 5477e86..fdf96bf 100644 --- a/lazy-supplements-core/src/config/core.rs +++ b/lazy-supplements-core/src/config/p2p.rs @@ -1,4 +1,4 @@ -use std::{net::IpAddr, ops, path::{Path, PathBuf}}; +use std::{net::{IpAddr, Ipv4Addr}, ops, path::{Path, PathBuf}}; use base64::{prelude::BASE64_STANDARD, Engine}; #[cfg(feature="desktop")] @@ -14,6 +14,9 @@ use crate::{ error::Error, p2p }; +static DEFAULT_P2P_LISTEN_IPS: &[IpAddr] = &[IpAddr::V4(Ipv4Addr::new(0, 0, 0, 0))]; +static DEFAULT_P2P_PORT: u16 = 0; + fn keypair_to_base64(keypair: &Keypair) -> String { let vec = match keypair.to_protobuf_encoding() { Ok(x) => x, @@ -28,14 +31,14 @@ fn base64_to_keypair(base64: &str) -> Result { } #[derive(Clone, Debug, Deserialize, Serialize)] -pub struct CoreConfig { +pub struct P2pConfig { #[serde(with = "keypair_parser")] pub secret: Keypair, pub listen_ips: Vec, pub port: u16, } -impl CoreConfig { +impl P2pConfig { pub async fn try_into_swarm (self) -> Result, Error> { let mut swarm = libp2p::SwarmBuilder::with_existing_identity(self.secret) .with_tokio() @@ -51,10 +54,10 @@ impl CoreConfig { } } -impl TryFrom for CoreConfig { +impl TryFrom for P2pConfig { type Error = Error; - fn try_from(raw: PartialCoreConfig) -> Result { - Ok(CoreConfig { + fn try_from(raw: PartialP2pConfig) -> Result { + Ok(P2pConfig { secret: base64_to_keypair(&raw.secret.ok_or(Error::MissingConfig("secret"))?)?, listen_ips: raw.listen_ips.ok_or(Error::MissingConfig("listen_ips"))?, port: raw.port.ok_or(Error::MissingConfig("port"))? @@ -83,8 +86,8 @@ mod keypair_parser { } #[cfg_attr(feature="desktop",derive(Args))] -#[derive(Clone, Debug, Deserialize, Serialize)] -pub struct PartialCoreConfig { +#[derive(Clone, Debug, Deserialize, Serialize, PartialEq)] +pub struct PartialP2pConfig { #[cfg_attr(feature="desktop",arg(long))] pub secret: Option, #[cfg_attr(feature="desktop",arg(long))] @@ -92,7 +95,7 @@ pub struct PartialCoreConfig { #[cfg_attr(feature="desktop",arg(long))] pub port: Option, } -impl PartialCoreConfig { +impl PartialP2pConfig { pub fn with_new_secret(mut self) -> Self { self.secret = Some(keypair_to_base64(&Keypair::generate_ed25519())); @@ -133,8 +136,8 @@ impl PartialCoreConfig { } } -impl From for PartialCoreConfig { - fn from(config: CoreConfig) -> Self { +impl From for PartialP2pConfig { + fn from(config: P2pConfig) -> Self { Self { secret: Some(keypair_to_base64(&config.secret)), listen_ips: Some(config.listen_ips), @@ -142,7 +145,8 @@ impl From for PartialCoreConfig { } } } -impl PartialConfig for PartialCoreConfig { + +impl PartialConfig for PartialP2pConfig { fn empty() -> Self { Self { secret: None, @@ -150,6 +154,9 @@ impl PartialConfig for PartialCoreConfig { port: None, } } + fn is_empty(&self) -> bool { + self.secret.is_none() && self.listen_ips.is_none() && self.port.is_none() + } fn merge(&mut self, another: Self) { if let Some(x) = another.secret { self.secret = Some(x); @@ -163,14 +170,22 @@ impl PartialConfig for PartialCoreConfig { } fn default() -> Self { - todo!() + Self { + secret: None, + listen_ips: Some(Vec::from(DEFAULT_P2P_LISTEN_IPS)), + port: Some(DEFAULT_P2P_PORT), + } } } + + + #[cfg(test)] mod tests { use libp2p::identity; use super::*; + use crate::{config::PartialConfig, tests::test_toml_serialize_deserialize}; #[tokio::test] @@ -180,4 +195,9 @@ mod tests { assert_eq!(keypair.public(), keypair2.public()); } + #[tokio::test] + async fn test_p2p_config_serialize_deserialize() { + test_toml_serialize_deserialize(PartialP2pConfig::empty()); + test_toml_serialize_deserialize(PartialP2pConfig::default()); + } } diff --git a/lazy-supplements-core/src/config/storage.rs b/lazy-supplements-core/src/config/storage.rs new file mode 100644 index 0000000..64041d7 --- /dev/null +++ b/lazy-supplements-core/src/config/storage.rs @@ -0,0 +1,91 @@ +use std::path::PathBuf; + +#[cfg(feature="desktop")] +use clap::Args; +use crate::config::{ConfigError, PartialConfig}; +use libp2p::mdns::Config; +use serde::{Deserialize, Serialize}; + +static DATA_DATABASE_NAME: &str = "data.sqlite"; +static CACHE_DATABASE_NAME: &str = "cache.sqlite"; + +#[cfg(any(test, feature="test"))] +static TEST_DATA_DATABASE_PATH: std::sync::LazyLock = std::sync::LazyLock::new(|| { + let mut temp_path = tempfile::NamedTempFile::new().unwrap().into_temp_path(); + temp_path.disable_cleanup(true); + println!("{}", temp_path.as_os_str().to_str().unwrap()); + temp_path +}); + + + +#[derive(Debug)] +pub struct StorageConfig { + pub data_directory: PathBuf, + pub cache_directory: PathBuf, +} + +impl StorageConfig { + #[cfg(any(test, feature="test"))] + pub fn new_test() -> Self { + let mut temp_path = tempfile::NamedTempFile::new().unwrap().into_temp_path().keep().unwrap(); + Self { data_directory: temp_path.clone(), cache_directory: temp_path } + } + pub fn get_data_database_path(&self) -> PathBuf{ + self.data_directory.join(DATA_DATABASE_NAME) + } + pub fn get_cache_database_path(&self) -> PathBuf { + self.cache_directory.join(CACHE_DATABASE_NAME) + } +} + +impl TryFrom for StorageConfig { + type Error = ConfigError; + + fn try_from(value: PartialStorageConfig) -> Result { + Ok(Self { + data_directory: value.data_directory.ok_or(ConfigError::MissingConfig("data_directory".to_string()))?, + cache_directory: value.cache_directory.ok_or(ConfigError::MissingConfig("cache_directory".to_string()))?, + }) + } +} +#[cfg_attr(feature="desktop", derive(Args))] +#[derive(Clone, Debug, Deserialize, Serialize)] +pub struct PartialStorageConfig { + #[cfg_attr(feature="desktop", arg(long))] + pub data_directory: Option, + #[cfg_attr(feature="desktop", arg(long))] + pub cache_directory: Option, +} + +impl From for PartialStorageConfig { + fn from(config: StorageConfig) -> PartialStorageConfig { + Self { + data_directory: Some(config.data_directory), + cache_directory: Some(config.cache_directory), + } + } +} + +impl PartialConfig for PartialStorageConfig { + fn empty() -> Self { + Self{ + data_directory: None, + cache_directory: None, + } + } + fn is_empty(&self) -> bool { + self.data_directory.is_none() && self.cache_directory.is_none() + } + fn default() -> Self { + todo!() + } + fn merge(&mut self, other: Self) { + if let Some(x) = other.data_directory { + self.data_directory = Some(x); + } + if let Some(x) = other.cache_directory { + self.cache_directory = Some(x); + } + } +} \ No newline at end of file diff --git a/lazy-supplements-core/src/global/database.rs b/lazy-supplements-core/src/global/database.rs deleted file mode 100644 index 06873af..0000000 --- a/lazy-supplements-core/src/global/database.rs +++ /dev/null @@ -1,64 +0,0 @@ -use std::path::Path; - -use sea_orm::{ConnectOptions, Database, DbErr, DatabaseConnection}; -use sea_orm_migration::MigratorTrait; -use crate::error::Error; -use tokio::sync::OnceCell; - -use super::Global; - -#[cfg(any(test, feature="test"))] -pub static TEST_MAIN_DATABASE_URL: std::sync::LazyLock = std::sync::LazyLock::new(|| { - let mut temp_path = tempfile::NamedTempFile::new().unwrap().into_temp_path(); - temp_path.disable_cleanup(true); - println!("{}", temp_path.as_os_str().to_str().unwrap()); - temp_path -}); -#[cfg(any(test, feature="test"))] -pub static TEST_CACHE_DATABASE_URL: std::sync::LazyLock = std::sync::LazyLock::new(|| { - let mut temp_path = tempfile::NamedTempFile::new().unwrap().into_temp_path(); - temp_path.disable_cleanup(true); - println!("{}", temp_path.as_os_str().to_str().unwrap()); - temp_path -}); - -pub trait GlobalDatabase { - fn get_main_database(&self) -> Option<&DatabaseConnection>; - async fn get_or_try_init_main_database(&self, path: T, _: U) -> Result<&DatabaseConnection, Error> - where - T: AsRef, - U: MigratorTrait - ; - fn get_unwrapped_main_database(&self) -> &DatabaseConnection { - match self.get_main_database() { - Some(x) => x, - None => unreachable!("Error: global main database is not initialized!") - } - } - fn get_cache_database(&self) -> Option<&DatabaseConnection>; - async fn get_or_try_init_cache_database(&self, path: T, _: U) -> Result<&DatabaseConnection, Error> - where - T: AsRef, - U: MigratorTrait - ; - fn get_unwrapped_cache_database(&self) -> &DatabaseConnection { - match self.get_cache_database() { - Some(x) => x, - None => unreachable!("Error: global main database is not initialized!") - } - } - #[cfg(any(test, feature="test"))] - async fn get_or_try_init_temporary_main_database(&self, migrator: T) -> Result<&DatabaseConnection, Error> - where - T: MigratorTrait, - { - self.get_or_try_init_main_database(&*TEST_MAIN_DATABASE_URL, migrator).await - } - #[cfg(any(test, feature="test"))] - async fn get_or_try_init_temporary_cache_database(&self, migrator: T) -> Result<&DatabaseConnection, Error> - where - T: MigratorTrait, - { - self.get_or_try_init_cache_database(&*TEST_CACHE_DATABASE_URL, migrator).await - } -} \ No newline at end of file diff --git a/lazy-supplements-core/src/global/database_connection.rs b/lazy-supplements-core/src/global/database_connection.rs new file mode 100644 index 0000000..467cd2b --- /dev/null +++ b/lazy-supplements-core/src/global/database_connection.rs @@ -0,0 +1,32 @@ +use std::path::Path; + +use sea_orm::{ConnectOptions, Database, DbErr, DatabaseConnection}; +use sea_orm_migration::MigratorTrait; +use crate::error::Error; +use tokio::sync::OnceCell; + +use super::storage_config::GlobalStorageConfig; + +static UNINITIALIZED_MESSAGE: &str = "global database connection uninitialized!"; + +pub trait GlobalDatabaseConnection: GlobalStorageConfig { + fn get_data_database_connection_as_once_cell(&'static self) -> &'static OnceCell; + fn get_data_database_connection(&'static self) -> Option<&'static DatabaseConnection> { + self.get_data_database_connection_as_once_cell().get() + } + fn get_and_unwrap_data_database_connection(&'static self) -> &'static DatabaseConnection { + self.get_data_database_connection().expect(UNINITIALIZED_MESSAGE) + } + async fn get_or_try_init_data_database_connection(&'static self, _: T) -> Result<&DatabaseConnection, Error> + where + T: MigratorTrait + { + let url = "sqlite://".to_string() + self.get_and_unwrap_storage_config().get_data_database_path().to_str().unwrap() + "?mode=rwc"; + Ok(self.get_data_database_connection_as_once_cell().get_or_try_init(|| async { + let db = Database::connect(&url).await?; + T::up(&db, None).await?; + Ok::(db) + }).await?) + } + +} \ No newline at end of file diff --git a/lazy-supplements-core/src/global/mod.rs b/lazy-supplements-core/src/global/mod.rs index 7184b2e..ce2a464 100644 --- a/lazy-supplements-core/src/global/mod.rs +++ b/lazy-supplements-core/src/global/mod.rs @@ -1,14 +1,17 @@ use std::{collections::HashMap, net::{IpAddr, Ipv4Addr}, path::{Path, PathBuf}, sync::LazyLock}; -use crate::{config::{CoreConfig, PartialCoreConfig}, error::Error}; +use crate::{config::{P2pConfig, PartialP2pConfig, StorageConfig}, error::Error}; use futures::StreamExt; use libp2p::{swarm::SwarmEvent, Multiaddr, PeerId}; use sea_orm::{prelude::*, Database}; use sea_orm_migration::MigratorTrait; use tokio::sync::{OnceCell, RwLock}; -mod database; -use database::GlobalDatabase; +mod peers; +pub use peers::GlobalPeers; +mod storage_config; +mod database_connection; +pub use database_connection::GlobalDatabaseConnection; use uuid::{ContextV7, Timestamp, Uuid}; pub fn generate_uuid() -> Uuid { @@ -30,123 +33,17 @@ pub static DEFAULT_DATABASE_FILE_NAME: LazyLock = LazyLock::new(|| { PathBuf::from(String::new() + env!("CARGO_PKG_NAME") + ".sqlite") }); - - -pub static GLOBAL: Global = Global{ - core_config: OnceCell::const_new(), - main_database: OnceCell::const_new(), - cache_database: OnceCell::const_new(), - peers: OnceCell::const_new(), - +#[cfg(any(test, feature="test"))] +pub struct TestGlobal { + p2p_config: OnceCell, + storage_config: OnceCell, + data_database_connection: OnceCell, + cache_database_connection: OnceCell, +} +#[cfg(any(test, feature="test"))] +pub static GLOBAL: TestGlobal = TestGlobal{ + p2p_config: OnceCell::const_new(), + storage_config: OnceCell::const_new(), + data_database_connection: OnceCell::const_new(), + cache_database_connection: OnceCell::const_new(), }; -pub struct Global { - pub core_config: OnceCell, - pub main_database: OnceCell, - pub cache_database: OnceCell, - pub peers: OnceCell>>, -} - -impl Global { - pub fn get_core_config(&self) -> Option<&CoreConfig> { - self.core_config.get() - } - pub async fn get_or_init_core_config(&self, config: CoreConfig) -> &CoreConfig { - self.core_config.get_or_init(|| async {config}).await - } - pub async fn get_or_init_peers(&self) -> &RwLock> { - self.peers.get_or_init(|| async { - RwLock::new(HashMap::new()) - }).await - } - pub async fn read_peers(&self) -> tokio::sync::RwLockReadGuard<'_, HashMap>{ - self.get_or_init_peers().await.read().await - } - pub async fn write_peers(&self) -> tokio::sync::RwLockWriteGuard<'_, HashMap>{ - self.get_or_init_peers().await.write().await - } - pub async fn launch_swarm(&self) -> Result<(), Error> { - let mut swarm = self.get_core_config().unwrap().clone().try_into_swarm().await?; - loop{ - let swarm_event = swarm.select_next_some().await; - tokio::spawn(async move{ - match swarm_event { - SwarmEvent::NewListenAddr { address, .. } => println!("Listening on {address:?}"), - SwarmEvent::Behaviour(event) => { - println!("{event:?}"); - event.run().await; - }, - _ => {} - } - }); - } - } -} - -impl GlobalDatabase for Global { - fn get_main_database(&self) -> Option<&DatabaseConnection> { - self.main_database.get() - } - async fn get_or_try_init_main_database(&self, path: T, _: U) -> Result<&DatabaseConnection, Error> - where - T: AsRef, - U: MigratorTrait, - { - let url = "sqlite://".to_string() + path.as_ref().to_str().unwrap() + "?mode=rwc"; - - Ok(self.main_database.get_or_try_init(|| async { - let db = Database::connect(&url).await?; - U::up(&db, None).await?; - Ok::(db) - }).await?) - } - fn get_cache_database(&self) -> Option<&DatabaseConnection> { - self.cache_database.get() - } - async fn get_or_try_init_cache_database(&self, path: T, _: U) -> Result<&DatabaseConnection, Error> - where - T: AsRef, - U: MigratorTrait, - { - let url = "sqlite://".to_string() + path.as_ref().to_str().unwrap() + "?mode=rwc"; - - Ok(self.cache_database.get_or_try_init(|| async { - let db = Database::connect(&url).await?; - U::up(&db, None).await?; - Ok::(db) - }).await?) - } - -} - - -#[cfg(test)] -pub use tests::{get_or_init_temporary_main_database, get_or_init_temporary_cache_database}; -#[cfg(test)] -pub mod tests { - use std::sync::LazyLock; - - use sea_orm_migration::MigratorTrait; - - use crate::{global::GLOBAL, cache::migration::CacheMigrator, data::migration::MainMigrator}; - - use super::*; - - pub async fn get_or_init_temporary_main_database() -> &'static DatabaseConnection { - GLOBAL.get_or_try_init_temporary_main_database(MainMigrator).await.unwrap() - } - pub async fn get_or_init_temporary_cache_database() -> &'static DatabaseConnection { - GLOBAL.get_or_try_init_temporary_cache_database(CacheMigrator).await.unwrap() - } - - #[tokio::test] - async fn connect_main_database () { - let db = get_or_init_temporary_main_database().await; - assert!(db.ping().await.is_ok()); - } - - #[tokio::test] - async fn connect_cache_database () { - let db = get_or_init_temporary_cache_database().await; - assert!(db.ping().await.is_ok()); - } -} \ No newline at end of file diff --git a/lazy-supplements-core/src/global/peers.rs b/lazy-supplements-core/src/global/peers.rs new file mode 100644 index 0000000..7affc74 --- /dev/null +++ b/lazy-supplements-core/src/global/peers.rs @@ -0,0 +1,18 @@ +use std::collections::HashSet; + +use libp2p::bytes::buf::UninitSlice; +use tokio::sync::{OnceCell, RwLock, RwLockReadGuard}; + +use crate::cache::entity::PeerModel; + +static UNINITIALIZED_MESSAGE: &str = "Global peer set uninitialized!"; +pub trait GlobalPeers { + fn get_peers_once_cell(&'static self) -> &OnceCell>>; + async fn write_peers(&'static self) -> tokio::sync::RwLockWriteGuard<'_ ,HashSet> { + self.get_peers_once_cell().get().expect(UNINITIALIZED_MESSAGE).write().await + } + async fn read_peers(&'static self) -> RwLockReadGuard<'_, HashSet> { + self.get_peers_once_cell().get().expect(UNINITIALIZED_MESSAGE).read().await + + } +} \ No newline at end of file diff --git a/lazy-supplements-core/src/global/storage_config.rs b/lazy-supplements-core/src/global/storage_config.rs new file mode 100644 index 0000000..87c589c --- /dev/null +++ b/lazy-supplements-core/src/global/storage_config.rs @@ -0,0 +1,22 @@ +use std::path::Path; + +use sea_orm::{ConnectOptions, Database, DbErr, DatabaseConnection}; +use sea_orm_migration::MigratorTrait; +use crate::{config::StorageConfig, error::Error}; +use tokio::sync::OnceCell; + +static UNINITIALIZED_MESSAGE: &str = "global storage is uninitialized!"; + +pub trait GlobalStorageConfig { + + fn init_storage_config(&'static self, config: StorageConfig) { + self.get_storage_config_once_cell().set(config).unwrap(); + } + fn get_storage_config_once_cell(&'static self) -> &'static OnceCell; + fn get_storage_config(&'static self) -> Option<&'static StorageConfig> { + self.get_storage_config_once_cell().get() + } + fn get_and_unwrap_storage_config(&'static self) -> &'static StorageConfig { + self.get_storage_config().expect(UNINITIALIZED_MESSAGE) + } +} \ No newline at end of file diff --git a/lazy-supplements-core/src/lib.rs b/lazy-supplements-core/src/lib.rs index 14f26b1..9cbbfd8 100644 --- a/lazy-supplements-core/src/lib.rs +++ b/lazy-supplements-core/src/lib.rs @@ -4,6 +4,7 @@ pub mod data; pub mod error; pub mod global; pub mod ipc; +pub mod message; pub mod migration; pub mod p2p; #[cfg(any(test, feature="test"))] diff --git a/lazy-supplements-core/src/message.rs b/lazy-supplements-core/src/message.rs new file mode 100644 index 0000000..5fba819 --- /dev/null +++ b/lazy-supplements-core/src/message.rs @@ -0,0 +1,15 @@ +use serde::{de::DeserializeOwned, Serialize}; + +pub trait Message: DeserializeOwned + Sized + Serialize { + fn into_writer(&self, writer: W) -> Result<(), ciborium::ser::Error> { + ciborium::into_writer(self, writer) + } + fn into_vec_u8(&self) -> Result, ciborium::ser::Error> { + let mut buf: Vec = Vec::new(); + self.into_writer(&mut buf)?; + Ok(buf) + } + fn from_reader(reader: R) -> Result> { + ciborium::from_reader(reader) + } +} \ No newline at end of file diff --git a/lazy-supplements-core/src/p2p/mod.rs b/lazy-supplements-core/src/p2p/mod.rs index a64add5..392a6de 100644 --- a/lazy-supplements-core/src/p2p/mod.rs +++ b/lazy-supplements-core/src/p2p/mod.rs @@ -35,11 +35,11 @@ impl Event { match x { mdns::Event::Discovered(e) => { for peer in e { - let mut peers = crate::global::GLOBAL.write_peers().await; - peers.insert(peer.0, peer.1); + //let mut peers = crate::global::GLOBAL.write_peers().await; + //peers.insert(peer.0, peer.1); } - let peers = crate::global::GLOBAL.read_peers().await; - println!("Peers: {peers:?}"); + //let peers = crate::global::GLOBAL.read_peers().await; + //println!("Peers: {peers:?}"); }, _ => {}, } diff --git a/lazy-supplements-core/src/tests.rs b/lazy-supplements-core/src/tests.rs index a13cb7b..d0ed15a 100644 --- a/lazy-supplements-core/src/tests.rs +++ b/lazy-supplements-core/src/tests.rs @@ -1,6 +1,10 @@ use std::{path::PathBuf, sync::LazyLock}; use tempfile::TempDir; +use crate::{ config::PartialConfig, message::Message}; + +use serde::{de::DeserializeOwned, Deserialize, Serialize}; + pub static TEST_DIR_PATH: LazyLock = LazyLock::new(|| { let pkg_name = env!("CARGO_PKG_NAME"); @@ -15,3 +19,22 @@ pub static TEST_DIR: LazyLock = LazyLock::new(|| { pub static TEST_DATABASE_PATH: std::sync::LazyLock = std::sync::LazyLock::new(|| { TEST_DIR_PATH.join("lazy-supplements.sqlite") }); + +#[cfg(any(test, feature="test"))] +pub fn test_cbor_serialize_deserialize(src: T) +where T: DeserializeOwned + Serialize + PartialEq + std::fmt::Debug +{ + let mut buf: Vec = Vec::new(); + ciborium::into_writer(&src, &mut buf).unwrap(); + let dst: T = ciborium::from_reader(buf.as_slice()).unwrap(); + assert_eq!(src, dst); +} + +#[cfg(any(test, feature="test"))] +pub fn test_toml_serialize_deserialize(src: T) +where T: DeserializeOwned + Serialize + PartialEq + std::fmt::Debug +{ + let buf = toml::to_string(&src).unwrap(); + let dst: T = toml::from_str(&buf).unwrap(); + assert_eq!(src, dst); +} \ No newline at end of file