Add carretta project

This commit is contained in:
fluo10 2025-08-15 06:50:14 +09:00
parent 8f04832397
commit 18e6d9239b
11 changed files with 81 additions and 89 deletions

View file

@ -1,5 +1,27 @@
[package]
name = "caretta"
edition.workspace = true
version.workspace = true
description.workspace = true
license.workspace = true
repository.workspace = true
[features]
default = []
mobile = ["dep:caretta-mobile"]
desktop = ["dep:caretta-desktop"]
test = ["caretta-core/test"]
[dependencies]
caretta-core.workspace = true
caretta-desktop = { path="desktop", optional = true }
caretta-mobile = { path = "mobile", optional = true }
[dev-dependencies]
caretta-core = {workspace = true, features = ["test"]}
[workspace] [workspace]
members = [ "core", "core/macros", "desktop", "mobile", "examples/*" ] members = [ ".", "core", "core/macros", "desktop", "mobile", "examples/*" ]
resolver = "3" resolver = "3"
[workspace.package] [workspace.package]
@ -23,3 +45,4 @@ thiserror = "2.0.12"
tokio = { version = "1.45.0", features = ["macros", "rt", "rt-multi-thread"] } tokio = { version = "1.45.0", features = ["macros", "rt", "rt-multi-thread"] }
tonic = "0.14.0" tonic = "0.14.0"
uuid = { version = "1.17.0", features = ["v7"] } uuid = { version = "1.17.0", features = ["v7"] }

View file

@ -40,7 +40,7 @@ impl BaseConfig {
Self { Self {
p2p : PartialP2pConfig::empty().with_new_secret(), p2p : PartialP2pConfig::empty().with_new_secret(),
storage: PartialStorageConfig::empty(), storage: PartialStorageConfig::empty(),
rpc: PartialRpcConfig::empty().with_unused_port(), rpc: PartialRpcConfig::empty(),
} }
} }
fn from_toml(s: &str) -> Result<Self, toml::de::Error> { fn from_toml(s: &str) -> Result<Self, toml::de::Error> {

View file

@ -1,4 +1,4 @@
use std::{net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener}, path::PathBuf}; use std::{net::{IpAddr, Ipv4Addr, SocketAddr, TcpListener}, path::PathBuf, str::FromStr};
#[cfg(feature="desktop")] #[cfg(feature="desktop")]
use clap::Args; use clap::Args;
use crate::{config::PartialConfig, utils::{emptiable::Emptiable, mergeable::Mergeable}}; use crate::{config::PartialConfig, utils::{emptiable::Emptiable, mergeable::Mergeable}};
@ -7,55 +7,59 @@ use serde::{Deserialize, Serialize};
use crate::config::error::ConfigError; use crate::config::error::ConfigError;
#[cfg(unix)]
static DEFAULT_SOCKET_PATH: &str = "caretta.sock";
pub struct RpcConfig { pub struct RpcConfig {
pub listen_address: IpAddr, pub socket_path: PathBuf,
pub port: u16,
} }
impl TryFrom<PartialRpcConfig> for RpcConfig { impl TryFrom<PartialRpcConfig> for RpcConfig {
type Error = ConfigError; type Error = ConfigError;
fn try_from(config: PartialRpcConfig) -> Result<Self, Self::Error> { fn try_from(config: PartialRpcConfig) -> Result<Self, Self::Error> {
Ok(Self{ Ok(Self{
listen_address: config.listen_address.ok_or(ConfigError::MissingConfig("listen_address".to_string()))?, socket_path: config.socket_path.ok_or(ConfigError::MissingConfig("port".to_string()))?,
port: config.port.ok_or(ConfigError::MissingConfig("port".to_string()))?,
}) })
} }
} }
#[derive(Args, Clone, Debug, Deserialize, Emptiable, Mergeable, Serialize)] #[cfg_attr(feature="desktop", derive(Args))]
#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct PartialRpcConfig { pub struct PartialRpcConfig {
pub listen_address: Option<IpAddr>, pub socket_path: Option<PathBuf>,
pub port: Option<u16>,
}
impl PartialRpcConfig {
pub fn with_unused_port(mut self) -> Self {
let listneer = if let Some(x) = self.listen_address {
TcpListener::bind(SocketAddr::new(x,0)).unwrap()
} else {
TcpListener::bind("127.0.0.1:0").unwrap()
};
self.port = Some(listneer.local_addr().unwrap().port());
self
}
} }
impl Default for PartialRpcConfig { impl Default for PartialRpcConfig {
fn default() -> Self { fn default() -> Self {
Self{ Self{
listen_address: Some(IpAddr::V4(Ipv4Addr::LOCALHOST)), socket_path: Some(PathBuf::from_str(DEFAULT_SOCKET_PATH).unwrap()),
port: None,
} }
} }
} }
impl Emptiable for PartialRpcConfig {
fn empty() -> Self {
Self {
socket_path: None,
}
}
fn is_empty(&self) -> bool {
self.socket_path.is_none()
}
}
impl From<RpcConfig> for PartialRpcConfig { impl From<RpcConfig> for PartialRpcConfig {
fn from(source: RpcConfig) -> Self { fn from(source: RpcConfig) -> Self {
Self { Self {
listen_address: Some(source.listen_address), socket_path: Some(source.socket_path),
port: Some(source.port),
} }
} }
} }
impl Mergeable for PartialRpcConfig {
fn merge(&mut self, other: Self) {
if let Some(x) = other.socket_path {
self.socket_path = Some(x);
}
}
}

View file

@ -1 +1,3 @@
pub mod server; pub mod server;
pub mod service;

16
core/src/rpc/server.rs Normal file
View file

@ -0,0 +1,16 @@
use tonic::transport::Server;
use crate::{proto::cached_peer_service_server::CachedPeerServiceServer, rpc::service::cached_peer::CachedPeerService};
pub async fn start_server() ->Result<(), Error> {
let addr = "[::1]:50051".parse()?;
let cached_peer_server = CachedPeerService::default();
Server::builder()
.add_service(CachedPeerServiceServer::new(cached_peer_server))
.serve(addr)
.await?;
Ok(())
}

View file

@ -6,20 +6,16 @@ use crate::config::{PartialP2pConfig, PartialStorageConfig};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
use crate::{ use crate::global::DEFAULT_CONFIG_FILE_PATH;
config::DesktopBaseConfig,
error::Error,
global::DEFAULT_CONFIG_FILE_PATH
};
#[derive(Args, Clone, Debug)] #[derive(Args, Clone, Debug)]
pub struct ConfigArgs { pub struct ConfigArgs {
#[arg(short = 'c', long = "config")] #[arg(short = 'c', long = "config")]
pub file_path: Option<PathBuf>, pub file_path: Option<PathBuf>,
#[arg(skip)] #[arg(skip)]
pub file_content: Option<DesktopBaseConfig>, pub file_content: Option<BaseConfig>,
#[command(flatten)] #[command(flatten)]
pub args: DesktopBaseConfig, pub args: BaseConfig,
} }
@ -27,9 +23,9 @@ impl ConfigArgs {
pub fn get_file_path_or_default(&self) -> PathBuf { pub fn get_file_path_or_default(&self) -> PathBuf {
self.file_path.clone().unwrap_or((*DEFAULT_CONFIG_FILE_PATH).clone()) self.file_path.clone().unwrap_or((*DEFAULT_CONFIG_FILE_PATH).clone())
} }
pub async fn get_or_read_file_content(&mut self) -> &mut DesktopBaseConfig { pub async fn get_or_read_file_content(&mut self) -> &mut BaseConfig {
self.file_content.get_or_insert( self.file_content.get_or_insert(
DesktopBaseConfig::read_from(self.get_file_path_or_default()).await.unwrap() BaseConfig::read_from(self.get_file_path_or_default()).await.unwrap()
) )
} }
} }

View file

@ -1,48 +0,0 @@
pub mod rpc;
use clap::Args;
pub use caretta_core::config::*;
use caretta_core::utils::{emptiable::Emptiable, mergeable::Mergeable};
use serde::{Deserialize, Serialize};
#[cfg(unix)]
pub use rpc::*;
#[cfg(windows)]
pub use windows::*;
#[derive(Args, Clone, Debug, Deserialize, Emptiable, Mergeable, Serialize)]
pub struct DesktopBaseConfig {
#[command(flatten)]
p2p: PartialP2pConfig,
#[command(flatten)]
storage: PartialStorageConfig,
#[command(flatten)]
rpc: PartialRpcConfig,
}
impl BaseConfig for DesktopBaseConfig {
fn new() -> Self {
Self {
p2p : PartialP2pConfig::empty().with_new_secret(),
storage: PartialStorageConfig::empty(),
rpc: PartialRpcConfig::empty().with_unused_port(),
}
}
}
impl Into<PartialP2pConfig> for &DesktopBaseConfig {
fn into(self) -> PartialP2pConfig {
self.p2p.clone()
}
}
impl Into<PartialStorageConfig> for &DesktopBaseConfig {
fn into(self) -> PartialStorageConfig {
self.storage.clone()
}
}
impl Into<PartialRpcConfig> for &DesktopBaseConfig {
fn into(self) -> PartialRpcConfig {
self.rpc.clone()
}
}

View file

@ -1,9 +1,3 @@
pub mod cli; pub mod cli;
pub mod config;
pub mod global; pub mod global;
pub mod utils; pub mod utils;
pub use caretta_core::{
cache,
data,
error,
};

5
src/lib.rs Normal file
View file

@ -0,0 +1,5 @@
pub use caretta_core::*;
#[cfg(desktop)]
pub use caretta_desktop::*;
#[cfg(mobile)]
pub use caretta_mobile::*;