2025-06-18 08:36:01 +09:00
|
|
|
pub mod error;
|
2025-06-19 07:24:44 +09:00
|
|
|
mod storage;
|
|
|
|
mod p2p;
|
2025-08-14 08:02:00 +09:00
|
|
|
mod rpc;
|
2025-05-24 06:11:00 +09:00
|
|
|
|
2025-05-30 09:26:47 +09:00
|
|
|
use std::path::Path;
|
2025-07-05 10:30:55 +09:00
|
|
|
use crate::{utils::{emptiable::Emptiable, mergeable::Mergeable}};
|
2025-06-18 08:36:01 +09:00
|
|
|
pub use error::ConfigError;
|
|
|
|
use serde::{de::DeserializeOwned, Deserialize, Serialize};
|
2025-06-11 08:38:03 +09:00
|
|
|
|
2025-05-30 09:26:47 +09:00
|
|
|
use tokio::{fs::File, io::{AsyncReadExt, AsyncWriteExt}};
|
2025-06-19 07:24:44 +09:00
|
|
|
pub use storage::{StorageConfig, PartialStorageConfig};
|
|
|
|
pub use p2p::{P2pConfig, PartialP2pConfig};
|
2025-08-14 08:02:00 +09:00
|
|
|
pub use rpc::*;
|
|
|
|
|
|
|
|
#[cfg(feature="desktop")]
|
|
|
|
use clap::Args;
|
2025-06-18 08:36:01 +09:00
|
|
|
|
2025-08-16 11:47:04 +09:00
|
|
|
#[derive(Clone, Debug)]
|
|
|
|
pub struct Config {
|
2025-08-18 08:22:20 +09:00
|
|
|
pub p2p: P2pConfig,
|
|
|
|
pub storage: StorageConfig,
|
|
|
|
pub rpc: RpcConfig,
|
2025-07-04 08:05:43 +09:00
|
|
|
}
|
|
|
|
|
2025-08-14 08:02:00 +09:00
|
|
|
#[cfg_attr(feature="desktop", derive(Args))]
|
2025-08-16 11:47:04 +09:00
|
|
|
#[derive(Clone, Debug, Default, Deserialize, PartialEq, Serialize)]
|
|
|
|
pub struct PartialConfig {
|
2025-08-14 08:02:00 +09:00
|
|
|
#[cfg_attr(feature="desktop", command(flatten))]
|
2025-08-18 08:22:20 +09:00
|
|
|
pub p2p: PartialP2pConfig,
|
2025-08-14 08:02:00 +09:00
|
|
|
#[cfg_attr(feature="desktop", command(flatten))]
|
2025-08-18 08:22:20 +09:00
|
|
|
pub storage: PartialStorageConfig,
|
2025-08-14 08:02:00 +09:00
|
|
|
#[cfg_attr(feature="desktop", command(flatten))]
|
2025-08-18 08:22:20 +09:00
|
|
|
pub rpc: PartialRpcConfig,
|
2025-08-14 08:02:00 +09:00
|
|
|
}
|
|
|
|
|
2025-08-16 11:47:04 +09:00
|
|
|
impl PartialConfig {
|
2025-08-18 08:22:20 +09:00
|
|
|
pub fn new() -> Self {
|
2025-08-14 08:02:00 +09:00
|
|
|
Self {
|
|
|
|
p2p : PartialP2pConfig::empty().with_new_secret(),
|
|
|
|
storage: PartialStorageConfig::empty(),
|
2025-08-15 06:50:14 +09:00
|
|
|
rpc: PartialRpcConfig::empty(),
|
2025-08-14 08:02:00 +09:00
|
|
|
}
|
|
|
|
}
|
2025-08-18 08:22:20 +09:00
|
|
|
pub fn from_toml(s: &str) -> Result<Self, toml::de::Error> {
|
2025-06-19 07:24:44 +09:00
|
|
|
toml::from_str(s)
|
|
|
|
}
|
2025-08-18 08:22:20 +09:00
|
|
|
pub fn into_toml(&self) -> Result<String, toml::ser::Error> {
|
2025-06-19 07:24:44 +09:00
|
|
|
toml::to_string(self)
|
|
|
|
}
|
2025-08-18 08:22:20 +09:00
|
|
|
pub async fn read_or_create<T>(path: T) -> Result<Self, ConfigError>
|
2025-06-18 08:36:01 +09:00
|
|
|
where
|
|
|
|
T: AsRef<Path>
|
|
|
|
{
|
|
|
|
if !path.as_ref().exists() {
|
|
|
|
Self::new().write_to(&path).await?;
|
|
|
|
}
|
|
|
|
Self::read_from(&path).await
|
|
|
|
}
|
2025-08-18 08:22:20 +09:00
|
|
|
pub async fn read_from<T>(path:T) -> Result<Self, ConfigError>
|
2025-06-18 08:36:01 +09:00
|
|
|
where
|
|
|
|
T: AsRef<Path>
|
|
|
|
{
|
|
|
|
let mut file = File::open(path.as_ref()).await?;
|
|
|
|
let mut content = String::new();
|
|
|
|
file.read_to_string(&mut content).await?;
|
|
|
|
let config: Self = toml::from_str(&content)?;
|
|
|
|
Ok(config)
|
|
|
|
}
|
2025-08-18 08:22:20 +09:00
|
|
|
pub async fn write_to<T>(&self, path:T) -> Result<(), ConfigError>
|
2025-06-18 08:36:01 +09:00
|
|
|
where
|
|
|
|
T: AsRef<Path>
|
|
|
|
{
|
|
|
|
if !path.as_ref().exists() {
|
|
|
|
if let Some(x) = path.as_ref().parent() {
|
|
|
|
std::fs::create_dir_all(x)?;
|
|
|
|
};
|
|
|
|
let _ = File::create(&path).await?;
|
|
|
|
}
|
|
|
|
let mut file = File::create(&path).await?;
|
|
|
|
file.write_all(toml::to_string(self)?.as_bytes()).await?;
|
|
|
|
Ok(())
|
|
|
|
}
|
2025-06-19 07:24:44 +09:00
|
|
|
}
|
|
|
|
|
2025-08-16 11:47:04 +09:00
|
|
|
impl Emptiable for PartialConfig {
|
|
|
|
fn empty() -> Self {
|
|
|
|
Self {
|
|
|
|
p2p: PartialP2pConfig::empty(),
|
|
|
|
storage: PartialStorageConfig::empty(),
|
|
|
|
rpc: PartialRpcConfig::empty()
|
2025-06-19 07:24:44 +09:00
|
|
|
}
|
2025-07-04 08:05:43 +09:00
|
|
|
}
|
2025-06-19 07:24:44 +09:00
|
|
|
|
2025-08-16 11:47:04 +09:00
|
|
|
fn is_empty(&self) -> bool {
|
|
|
|
self.p2p.is_empty() && self.rpc.is_empty() && self.storage.is_empty()
|
2025-06-19 07:24:44 +09:00
|
|
|
}
|
2025-08-16 11:47:04 +09:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use libp2p::identity;
|
|
|
|
use super::*;
|
|
|
|
use crate::{tests::test_toml_serialize_deserialize};
|
2025-06-19 07:24:44 +09:00
|
|
|
|
|
|
|
#[tokio::test]
|
|
|
|
async fn test_p2p_config_serialize_deserialize() {
|
2025-08-16 11:47:04 +09:00
|
|
|
test_toml_serialize_deserialize(PartialConfig::empty());
|
2025-06-19 07:24:44 +09:00
|
|
|
}
|
2025-06-18 08:36:01 +09:00
|
|
|
}
|