Refuctor dpts-error and dpts-config
This commit is contained in:
parent
7bebdf7490
commit
663cc6effc
40 changed files with 302 additions and 283 deletions
83
Cargo.lock
generated
83
Cargo.lock
generated
|
@ -113,12 +113,6 @@ dependencies = [
|
||||||
"windows-sys 0.59.0",
|
"windows-sys 0.59.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "anyhow"
|
|
||||||
version = "1.0.98"
|
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
|
||||||
checksum = "e16d2d3311acee920a9eb8d33b8cbc1787ce4a264e85f964c2404b969bdcd487"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "ascii_utils"
|
name = "ascii_utils"
|
||||||
version = "0.9.3"
|
version = "0.9.3"
|
||||||
|
@ -381,9 +375,9 @@ checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "axum"
|
name = "axum"
|
||||||
version = "0.8.3"
|
version = "0.8.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "de45108900e1f9b9242f7f2e254aa3e2c029c921c258fe9e6b4217eeebd54288"
|
checksum = "021e862c184ae977658b36c4500f7feac3221ca5da43e3f25bd04ab6c79a29b5"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"axum-core",
|
"axum-core",
|
||||||
"bytes",
|
"bytes",
|
||||||
|
@ -792,35 +786,42 @@ version = "0.15.7"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
checksum = "1aaf95b3e5c8f23aa320147307562d361db0ae0d51242340f558153b4eb2439b"
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dpts"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"dpts-config",
|
|
||||||
"dpts-csv",
|
|
||||||
"dpts-database",
|
|
||||||
"dpts-entity",
|
|
||||||
"dpts-error",
|
|
||||||
"dpts-migration",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dpts-cli"
|
name = "dpts-cli"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"dpts",
|
"dpts-core",
|
||||||
|
"thiserror 2.0.12",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dpts-config"
|
name = "dpts-client"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"clap",
|
||||||
|
"dpts-core",
|
||||||
|
"serde",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"tokio",
|
||||||
|
"toml",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "dpts-core"
|
||||||
|
version = "0.1.0"
|
||||||
|
dependencies = [
|
||||||
|
"async-graphql",
|
||||||
|
"axum",
|
||||||
|
"chrono",
|
||||||
"chrono-tz",
|
"chrono-tz",
|
||||||
|
"clap",
|
||||||
|
"dotenv",
|
||||||
"dpts-entity",
|
"dpts-entity",
|
||||||
"dpts-error",
|
"dpts-migration",
|
||||||
"iana-time-zone",
|
"iana-time-zone",
|
||||||
|
"log",
|
||||||
"sea-orm",
|
"sea-orm",
|
||||||
"serde",
|
"serde",
|
||||||
"thiserror 2.0.12",
|
"thiserror 2.0.12",
|
||||||
|
@ -835,24 +836,8 @@ dependencies = [
|
||||||
"chrono",
|
"chrono",
|
||||||
"csv",
|
"csv",
|
||||||
"dpts-entity",
|
"dpts-entity",
|
||||||
"dpts-error",
|
|
||||||
"serde",
|
"serde",
|
||||||
]
|
"thiserror 2.0.12",
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dpts-database"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"async-graphql",
|
|
||||||
"axum",
|
|
||||||
"chrono",
|
|
||||||
"dotenv",
|
|
||||||
"dpts-config",
|
|
||||||
"dpts-entity",
|
|
||||||
"dpts-migration",
|
|
||||||
"log",
|
|
||||||
"sea-orm",
|
|
||||||
"tokio",
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -863,7 +848,6 @@ dependencies = [
|
||||||
"axum",
|
"axum",
|
||||||
"chrono",
|
"chrono",
|
||||||
"dotenv",
|
"dotenv",
|
||||||
"dpts-database",
|
|
||||||
"dpts-migration",
|
"dpts-migration",
|
||||||
"log",
|
"log",
|
||||||
"sea-orm",
|
"sea-orm",
|
||||||
|
@ -871,16 +855,6 @@ dependencies = [
|
||||||
"tokio",
|
"tokio",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "dpts-error"
|
|
||||||
version = "0.1.0"
|
|
||||||
dependencies = [
|
|
||||||
"anyhow",
|
|
||||||
"clap",
|
|
||||||
"thiserror 2.0.12",
|
|
||||||
"toml",
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "dpts-migration"
|
name = "dpts-migration"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
|
@ -893,9 +867,14 @@ dependencies = [
|
||||||
name = "dpts-server"
|
name = "dpts-server"
|
||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
|
"axum",
|
||||||
"chrono",
|
"chrono",
|
||||||
"clap",
|
"clap",
|
||||||
"dpts",
|
"dpts-core",
|
||||||
|
"serde",
|
||||||
|
"thiserror 2.0.12",
|
||||||
|
"tokio",
|
||||||
|
"toml",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
27
Cargo.toml
27
Cargo.toml
|
@ -1,32 +1,17 @@
|
||||||
[package]
|
|
||||||
name = "dpts"
|
|
||||||
version.workspace = true
|
|
||||||
edition.workspace = true
|
|
||||||
license.workspace = true
|
|
||||||
repository.workspace = true
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
dpts-config.workspace = true
|
|
||||||
dpts-csv.workspace = true
|
|
||||||
dpts-entity.workspace = true
|
|
||||||
dpts-error.workspace = true
|
|
||||||
dpts-migration.workspace = true
|
|
||||||
dpts-database.workspace = true
|
|
||||||
|
|
||||||
[workspace]
|
[workspace]
|
||||||
members = [".", "dpts-*"]
|
members = ["dpts-*"]
|
||||||
|
|
||||||
[workspace.dependencies]
|
[workspace.dependencies]
|
||||||
dpts = { path = "." }
|
dpts-cli.path = "dpts-cli"
|
||||||
dpts-config = { path = "dpts-config" }
|
dpts-client.path = "dpts-client"
|
||||||
|
dpts-core = { path = "dpts-core" }
|
||||||
dpts-csv = { path = "dpts-csv" }
|
dpts-csv = { path = "dpts-csv" }
|
||||||
dpts-database = { path = "dpts-database" }
|
|
||||||
dpts-entity = { path = "dpts-entity" }
|
dpts-entity = { path = "dpts-entity" }
|
||||||
dpts-error = { path = "dpts-error" }
|
|
||||||
dpts-migration = {path = "dpts-migration"}
|
dpts-migration = {path = "dpts-migration"}
|
||||||
|
dpts-server.path = "dpts-server"
|
||||||
chrono = {version = "0.4", features = ["serde"]}
|
chrono = {version = "0.4", features = ["serde"]}
|
||||||
chrono-tz = {version = "0.10.3", features = ["serde"]}
|
chrono-tz = {version = "0.10.3", features = ["serde"]}
|
||||||
clap = "4.5"
|
clap = {version = "4.5", features = ["derive"]}
|
||||||
dotenv = "0.15.0"
|
dotenv = "0.15.0"
|
||||||
serde = { version = "1.0", features = ["derive"] }
|
serde = { version = "1.0", features = ["derive"] }
|
||||||
thiserror = "2.0.12"
|
thiserror = "2.0.12"
|
||||||
|
|
|
@ -6,6 +6,7 @@ edition.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dpts = {workspace = true}
|
dpts-core = {workspace = true}
|
||||||
chrono = {workspace = true}
|
chrono = {workspace = true}
|
||||||
clap = {workspace = true, features = ["derive"]}
|
clap = {workspace = true, features = ["derive"]}
|
||||||
|
thiserror.workspace = true
|
8
dpts-cli/src/error.rs
Normal file
8
dpts-cli/src/error.rs
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Parse int error")]
|
||||||
|
ParseInt(#[from] std::num::ParseIntError),
|
||||||
|
#[error("Missing config value: ({0})")]
|
||||||
|
MissingConfig(String)
|
||||||
|
|
||||||
|
}
|
|
@ -1,10 +1,12 @@
|
||||||
//mod label;
|
//mod label;
|
||||||
|
pub mod error;
|
||||||
mod record;
|
mod record;
|
||||||
|
|
||||||
|
|
||||||
//use label::LabelArgs;
|
//use label::LabelArgs;
|
||||||
use record::{RecordArgs,RecordAddArgs};
|
use record::{RecordArgs,RecordAddArgs};
|
||||||
|
|
||||||
use dpts::error::Error;
|
use error::Error;
|
||||||
|
|
||||||
use clap::{Args, CommandFactory, Parser, Subcommand};
|
use clap::{Args, CommandFactory, Parser, Subcommand};
|
||||||
|
|
||||||
|
@ -23,33 +25,14 @@ enum Command {
|
||||||
Record(RecordArgs),
|
Record(RecordArgs),
|
||||||
}
|
}
|
||||||
|
|
||||||
fn try_parse() -> Result<Cli, Error> {
|
|
||||||
Ok(try_parse_from(std::env::args_os())?)
|
|
||||||
}
|
|
||||||
|
|
||||||
fn try_parse_from<I, T>(itr: I) -> Result<Cli, Error>
|
|
||||||
where I: IntoIterator<Item=T>,
|
|
||||||
T: Into<OsString> + Clone,
|
|
||||||
{
|
|
||||||
let os_string_vec: Vec<OsString> = itr.into_iter().map(|x| Into::<OsString>::into(x)).collect();
|
|
||||||
Cli::try_parse_from(os_string_vec.clone()).or_else(|err| match err.kind() {
|
|
||||||
clap::error::ErrorKind::InvalidSubcommand => {
|
|
||||||
try_parse_from(vec![OsString::from("record"), OsString::from("add")].into_iter().chain(os_string_vec.clone().into_iter()))
|
|
||||||
},
|
|
||||||
_ => Err(err)?,
|
|
||||||
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn main() -> Result<(), Error> {
|
fn main() -> Result<(), Error> {
|
||||||
let cli = try_parse();
|
let cli = Cli::parse();
|
||||||
match cli {
|
match cli.command {
|
||||||
Err(_) => Ok(Cli::command().print_help()?),
|
//Some(Commands::Add(x)) => x.run(),
|
||||||
Ok(x) => match x.command {
|
//Some(Commands::Label(x)) => x.run(),
|
||||||
//Some(Commands::Add(x)) => x.run(),
|
Command::Record(x) => x.run(),
|
||||||
//Some(Commands::Label(x)) => x.run(),
|
|
||||||
Command::Record(x) => x.run(),
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
use chrono::prelude::*;
|
use chrono::prelude::*;
|
||||||
use clap::{Args, Subcommand};
|
use clap::{Args, Subcommand};
|
||||||
use dpts::error::Error;
|
use crate::error::Error;
|
||||||
use std::str::FromStr;
|
use std::str::FromStr;
|
||||||
|
|
||||||
#[derive(Args, Clone, Debug)]
|
#[derive(Args, Clone, Debug)]
|
||||||
|
|
16
dpts-client/Cargo.toml
Normal file
16
dpts-client/Cargo.toml
Normal file
|
@ -0,0 +1,16 @@
|
||||||
|
[package]
|
||||||
|
name = "dpts-client"
|
||||||
|
version = "0.1.0"
|
||||||
|
edition = "2024"
|
||||||
|
|
||||||
|
[features]
|
||||||
|
default = ["clap"]
|
||||||
|
clap = ["dep:clap"]
|
||||||
|
|
||||||
|
[dependencies]
|
||||||
|
clap = { workspace = true, optional = true }
|
||||||
|
dpts-core.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
thiserror.workspace = true
|
||||||
|
tokio.workspace = true
|
||||||
|
toml.workspace = true
|
|
@ -2,41 +2,19 @@ mod storage;
|
||||||
|
|
||||||
pub use storage::*;
|
pub use storage::*;
|
||||||
|
|
||||||
|
use crate::error::Error;
|
||||||
use serde::{
|
use serde::{
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Serialize
|
Serialize
|
||||||
};
|
};
|
||||||
|
|
||||||
use chrono_tz::{Tz, UTC};
|
|
||||||
use tokio::sync::OnceCell;
|
use tokio::sync::OnceCell;
|
||||||
use crate::{get_host_time_zone_or_utc, Error};
|
|
||||||
|
|
||||||
pub static CLIENT_CONFIG: OnceClientConfig = OnceClientConfig::const_new();
|
pub static CLIENT_CONFIG: OnceCell<ClientConfig> = OnceCell::const_new();
|
||||||
|
|
||||||
pub struct OnceClientConfig {
|
|
||||||
inner: OnceCell<ClientConfig>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl OnceClientConfig {
|
|
||||||
const fn const_new() -> Self {
|
|
||||||
Self {
|
|
||||||
inner: OnceCell::const_new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn get(&self) -> Option<&ClientConfig> {
|
|
||||||
self.inner.get()
|
|
||||||
}
|
|
||||||
pub async fn get_or_init<F, T>(&self, f: F) -> &ClientConfig where
|
|
||||||
F: FnOnce() -> T,
|
|
||||||
T: Future<Output = ClientConfig>
|
|
||||||
{
|
|
||||||
self.inner.get_or_init(f).await
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub struct ClientConfig {
|
pub struct ClientConfig {
|
||||||
pub time_zone: Tz,
|
|
||||||
pub storage: ClientStorageConfig,
|
pub storage: ClientStorageConfig,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -44,7 +22,6 @@ impl TryFrom<&PartialClientConfig> for ClientConfig {
|
||||||
type Error = Error;
|
type Error = Error;
|
||||||
fn try_from(p: &PartialClientConfig) -> Result<ClientConfig, Self::Error> {
|
fn try_from(p: &PartialClientConfig) -> Result<ClientConfig, Self::Error> {
|
||||||
Ok(ClientConfig{
|
Ok(ClientConfig{
|
||||||
time_zone: p.time_zone.ok_or(Error::MissingConfig("time_zone".to_string()))?,
|
|
||||||
storage: p.clone().storage.ok_or(Error::MissingConfig("storage".to_string()))?,
|
storage: p.clone().storage.ok_or(Error::MissingConfig("storage".to_string()))?,
|
||||||
})
|
})
|
||||||
|
|
||||||
|
@ -53,7 +30,6 @@ impl TryFrom<&PartialClientConfig> for ClientConfig {
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Clone, Debug, Deserialize, PartialEq, Serialize)]
|
||||||
pub struct PartialClientConfig {
|
pub struct PartialClientConfig {
|
||||||
pub time_zone: Option<Tz>,
|
|
||||||
pub storage: Option<ClientStorageConfig>,
|
pub storage: Option<ClientStorageConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -65,7 +41,6 @@ impl PartialClientConfig {
|
||||||
impl Default for PartialClientConfig {
|
impl Default for PartialClientConfig {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
PartialClientConfig {
|
PartialClientConfig {
|
||||||
time_zone: Some(get_host_time_zone_or_utc()),
|
|
||||||
storage: None
|
storage: None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -83,7 +58,6 @@ mod tests {
|
||||||
async fn get_empty_config_struct() -> &'static PartialClientConfig {
|
async fn get_empty_config_struct() -> &'static PartialClientConfig {
|
||||||
EMPTY_CONFIG_STRUCT.get_or_init(|| async {
|
EMPTY_CONFIG_STRUCT.get_or_init(|| async {
|
||||||
PartialClientConfig{
|
PartialClientConfig{
|
||||||
time_zone: None,
|
|
||||||
storage: None,
|
storage: None,
|
||||||
}
|
}
|
||||||
}).await
|
}).await
|
||||||
|
@ -109,7 +83,6 @@ storage = "local"
|
||||||
async fn get_local_storage_client_config_struct() -> &'static PartialClientConfig {
|
async fn get_local_storage_client_config_struct() -> &'static PartialClientConfig {
|
||||||
LOCAL_STORAGE_CONFIG_STRUCT.get_or_init(|| async {
|
LOCAL_STORAGE_CONFIG_STRUCT.get_or_init(|| async {
|
||||||
PartialClientConfig{
|
PartialClientConfig{
|
||||||
time_zone: Some(UTC),
|
|
||||||
storage: Some(ClientStorageConfig::Local),
|
storage: Some(ClientStorageConfig::Local),
|
||||||
}
|
}
|
||||||
}).await
|
}).await
|
||||||
|
@ -136,7 +109,6 @@ access_key = "test"
|
||||||
async fn get_remote_storage_client_config_struct() -> &'static PartialClientConfig {
|
async fn get_remote_storage_client_config_struct() -> &'static PartialClientConfig {
|
||||||
REMOTE_STORAGE_CONFIG_STRUCT.get_or_init(|| async {
|
REMOTE_STORAGE_CONFIG_STRUCT.get_or_init(|| async {
|
||||||
PartialClientConfig{
|
PartialClientConfig{
|
||||||
time_zone: Some(UTC),
|
|
||||||
storage: Some(ClientStorageConfig::Remote(ClientRemoteStorageConfig {
|
storage: Some(ClientStorageConfig::Remote(ClientRemoteStorageConfig {
|
||||||
endpoint: "https://example.com".to_string(),
|
endpoint: "https://example.com".to_string(),
|
||||||
access_key: "test".to_string(),
|
access_key: "test".to_string(),
|
|
@ -1,5 +1,4 @@
|
||||||
use chrono_tz::{Tz, UTC};
|
use crate::error::Error;
|
||||||
use crate::{get_host_time_zone_or_utc, Error};
|
|
||||||
use serde::{
|
use serde::{
|
||||||
Deserialize,
|
Deserialize,
|
||||||
Serialize
|
Serialize
|
|
@ -1,5 +1,7 @@
|
||||||
#[derive(thiserror::Error, Debug)]
|
#[derive(thiserror::Error, Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
|
#[error("Parse int error")]
|
||||||
|
ParseInt(#[from] std::num::ParseIntError),
|
||||||
#[error("Parse toml error")]
|
#[error("Parse toml error")]
|
||||||
TomlDe(#[from] toml::de::Error),
|
TomlDe(#[from] toml::de::Error),
|
||||||
#[error("Missing config value: ({0})")]
|
#[error("Missing config value: ({0})")]
|
17
dpts-client/src/lib.rs
Normal file
17
dpts-client/src/lib.rs
Normal file
|
@ -0,0 +1,17 @@
|
||||||
|
pub mod config;
|
||||||
|
pub mod error;
|
||||||
|
|
||||||
|
pub fn add(left: u64, right: u64) -> u64 {
|
||||||
|
left + right
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn it_works() {
|
||||||
|
let result = add(2, 2);
|
||||||
|
assert_eq!(result, 4);
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,23 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "dpts-config"
|
|
||||||
version.workspace = true
|
|
||||||
edition.workspace = true
|
|
||||||
license.workspace = true
|
|
||||||
repository.workspace = true
|
|
||||||
|
|
||||||
[features]
|
|
||||||
default = ["client", "server"]
|
|
||||||
client = []
|
|
||||||
server = []
|
|
||||||
test = []
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
chrono-tz.workspace = true
|
|
||||||
dpts-entity.workspace = true
|
|
||||||
dpts-error.workspace = true
|
|
||||||
iana-time-zone = "0.1.63"
|
|
||||||
sea-orm.workspace = true
|
|
||||||
serde.workspace = true
|
|
||||||
thiserror.workspace = true
|
|
||||||
tokio.workspace = true
|
|
||||||
toml.workspace = true
|
|
|
@ -1,38 +0,0 @@
|
||||||
#[cfg(feature="client")]
|
|
||||||
mod client;
|
|
||||||
mod database;
|
|
||||||
mod error;
|
|
||||||
#[cfg(feature="server")]
|
|
||||||
mod server;
|
|
||||||
|
|
||||||
#[cfg(feature="client")]
|
|
||||||
pub use client::{
|
|
||||||
ClientConfig,
|
|
||||||
CLIENT_CONFIG,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use database::{
|
|
||||||
DatabaseConfig,
|
|
||||||
PartialDatabaseConfig,
|
|
||||||
};
|
|
||||||
|
|
||||||
pub use error::Error;
|
|
||||||
|
|
||||||
#[cfg(feature="server")]
|
|
||||||
pub use server::{
|
|
||||||
ServerConfig,
|
|
||||||
PartialServerConfig,
|
|
||||||
SERVER_CONFIG,
|
|
||||||
};
|
|
||||||
|
|
||||||
use chrono_tz::{Tz, UTC};
|
|
||||||
|
|
||||||
fn get_host_time_zone_or_utc() -> Tz {
|
|
||||||
match iana_time_zone::get_timezone() {
|
|
||||||
Ok(x) => match x.parse(){
|
|
||||||
Ok(x) => x,
|
|
||||||
Err(_) => UTC
|
|
||||||
},
|
|
||||||
Err(_) => UTC
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,29 +1,27 @@
|
||||||
[package]
|
[package]
|
||||||
name = "dpts-database"
|
name = "dpts-core"
|
||||||
version.workspace = true
|
version.workspace = true
|
||||||
edition.workspace = true
|
edition.workspace = true
|
||||||
license.workspace = true
|
license.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|
||||||
[features]
|
[features]
|
||||||
default = ["server", "client"]
|
default = ["clap",]
|
||||||
client = []
|
clap = ["dep:clap"]
|
||||||
server = []
|
|
||||||
test = []
|
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dpts-config.workspace = true
|
async-graphql = { version = "7.0", features = ["chrono"] }
|
||||||
dpts-entity = { workspace = true }
|
|
||||||
dpts-migration = { workspace = true }
|
|
||||||
async-graphql = {version = "7.0", features = ["chrono"]}
|
|
||||||
axum = "0.8"
|
axum = "0.8"
|
||||||
chrono = {workspace = true}
|
chrono = {workspace = true}
|
||||||
|
chrono-tz.workspace = true
|
||||||
|
clap = { workspace = true, optional = true }
|
||||||
dotenv = {workspace = true}
|
dotenv = {workspace = true}
|
||||||
|
dpts-entity = { workspace = true }
|
||||||
|
dpts-migration = { workspace = true }
|
||||||
|
iana-time-zone = "0.1.63"
|
||||||
log = "0.4.27"
|
log = "0.4.27"
|
||||||
sea-orm.workspace = true
|
sea-orm.workspace = true
|
||||||
|
serde.workspace = true
|
||||||
|
thiserror.workspace = true
|
||||||
tokio.workspace = true
|
tokio.workspace = true
|
||||||
|
toml.workspace = true
|
||||||
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
dpts-config = { workspace = true, features = ["test"] }
|
|
|
@ -1,7 +1,10 @@
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
|
|
||||||
|
#[cfg(feature="clap")]
|
||||||
|
use clap::Args;
|
||||||
use sea_orm::ConnectOptions;
|
use sea_orm::ConnectOptions;
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
|
use tokio::sync::OnceCell;
|
||||||
|
|
||||||
use crate::Error;
|
use crate::Error;
|
||||||
|
|
||||||
|
@ -61,14 +64,26 @@ impl TryFrom<PartialDatabaseConfig> for DatabaseConfig{
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
|
||||||
|
#[cfg_attr(feature="clap", derive(Args))]
|
||||||
pub struct PartialDatabaseConfig {
|
pub struct PartialDatabaseConfig {
|
||||||
pub url: Option<String>,
|
pub url: Option<String>,
|
||||||
pub max_connections: Option<u32>,
|
pub max_connections: Option<u32>,
|
||||||
pub min_connections: Option<u32>,
|
pub min_connections: Option<u32>,
|
||||||
|
#[cfg_attr(feature="clap", arg(value_parser = parse_duration ))]
|
||||||
pub connect_timeout: Option<Duration>,
|
pub connect_timeout: Option<Duration>,
|
||||||
|
#[cfg_attr(feature="clap", arg(value_parser = parse_duration ))]
|
||||||
pub acquire_timeout: Option<Duration>,
|
pub acquire_timeout: Option<Duration>,
|
||||||
|
#[cfg_attr(feature="clap", arg(value_parser = parse_duration ))]
|
||||||
pub idle_timeout: Option<Duration>,
|
pub idle_timeout: Option<Duration>,
|
||||||
|
#[cfg_attr(feature="clap", arg(value_parser = parse_duration ))]
|
||||||
pub max_lifetime: Option<Duration>,
|
pub max_lifetime: Option<Duration>,
|
||||||
pub sqlx_logging: Option<bool>
|
pub sqlx_logging: Option<bool>
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[cfg(feature="clap")]
|
||||||
|
fn parse_duration(arg: &str) -> Result<std::time::Duration, Error> {
|
||||||
|
let seconds = arg.parse()?;
|
||||||
|
Ok(std::time::Duration::from_secs(seconds))
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static DATABASE_CONFIG: OnceCell<DatabaseConfig> = OnceCell::const_new();
|
32
dpts-core/src/config/global.rs
Normal file
32
dpts-core/src/config/global.rs
Normal file
|
@ -0,0 +1,32 @@
|
||||||
|
use chrono_tz::Tz;
|
||||||
|
#[cfg(feature="clap")]
|
||||||
|
use clap::Args;
|
||||||
|
use serde::Deserialize;
|
||||||
|
use tokio::sync::OnceCell;
|
||||||
|
|
||||||
|
use crate::Error;
|
||||||
|
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||||
|
pub struct GlobalConfig {
|
||||||
|
pub time_zone: Tz,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<PartialGlobalConfig> for GlobalConfig{
|
||||||
|
type Error = Error;
|
||||||
|
fn try_from(p: PartialGlobalConfig) -> Result<GlobalConfig, Self::Error> {
|
||||||
|
Ok(GlobalConfig{
|
||||||
|
time_zone: p.time_zone.ok_or(Error::MissingConfig("time_zone".to_string()))?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Default, Deserialize, PartialEq)]
|
||||||
|
#[cfg_attr(feature="clap", derive(Args))]
|
||||||
|
pub struct PartialGlobalConfig {
|
||||||
|
#[cfg_attr(feature="clap", arg(short, long))]
|
||||||
|
|
||||||
|
pub time_zone: Option<Tz>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub static GLOBAL_CONFIG: OnceCell<GlobalConfig> = OnceCell::const_new();
|
14
dpts-core/src/config/mod.rs
Normal file
14
dpts-core/src/config/mod.rs
Normal file
|
@ -0,0 +1,14 @@
|
||||||
|
mod database;
|
||||||
|
mod global;
|
||||||
|
|
||||||
|
pub use database::{
|
||||||
|
DatabaseConfig,
|
||||||
|
PartialDatabaseConfig,
|
||||||
|
DATABASE_CONFIG,
|
||||||
|
};
|
||||||
|
|
||||||
|
pub use global::{
|
||||||
|
GlobalConfig,
|
||||||
|
PartialGlobalConfig,
|
||||||
|
GLOBAL_CONFIG,
|
||||||
|
};
|
|
@ -1,7 +1,10 @@
|
||||||
|
use crate::config::{
|
||||||
|
DATABASE_CONFIG,
|
||||||
|
DatabaseConfig
|
||||||
|
};
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use sea_orm::{entity::*, query::*, ConnectOptions, Database, DatabaseConnection};
|
use sea_orm::{entity::*, query::*, ConnectOptions, Database, DatabaseConnection};
|
||||||
use dpts_migration::{Migrator, MigratorTrait};
|
use dpts_migration::{Migrator, MigratorTrait};
|
||||||
use dpts_config::ServerConfig;
|
|
||||||
|
|
||||||
use tokio::sync::OnceCell;
|
use tokio::sync::OnceCell;
|
||||||
|
|
||||||
|
@ -25,15 +28,15 @@ impl OnceDatabaseConnection {
|
||||||
self.inner.get_or_init(f).await
|
self.inner.get_or_init(f).await
|
||||||
}
|
}
|
||||||
|
|
||||||
pub async fn get_or_init_with_server_config(&self, c: &ServerConfig) -> &DatabaseConnection {
|
pub async fn get_or_init_with_server_config(&self, c: &DatabaseConfig) -> &DatabaseConnection {
|
||||||
self.get_or_init( || async {
|
self.get_or_init( || async {
|
||||||
let db = Database::connect(&c.database).await.unwrap();
|
let db = Database::connect(c).await.unwrap();
|
||||||
Migrator::fresh(&db).await.unwrap();
|
Migrator::fresh(&db).await.unwrap();
|
||||||
db
|
db
|
||||||
}).await
|
}).await
|
||||||
}
|
}
|
||||||
pub async fn get_or_init_with_static_server_config(&self) -> &DatabaseConnection {
|
pub async fn get_or_init_with_static_server_config(&self) -> &DatabaseConnection {
|
||||||
self.get_or_init_with_server_config(dpts_config::SERVER_CONFIG.get().unwrap()).await
|
self.get_or_init_with_server_config(DATABASE_CONFIG.get().unwrap()).await
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
10
dpts-core/src/error.rs
Normal file
10
dpts-core/src/error.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Parse int error")]
|
||||||
|
ParseInt(#[from] std::num::ParseIntError),
|
||||||
|
#[error("Parse toml error")]
|
||||||
|
TomlDe(#[from] toml::de::Error),
|
||||||
|
#[error("Missing config value: ({0})")]
|
||||||
|
MissingConfig(String)
|
||||||
|
|
||||||
|
}
|
6
dpts-core/src/graphql/mod.rs
Normal file
6
dpts-core/src/graphql/mod.rs
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
mod query;
|
||||||
|
|
||||||
|
mod response;
|
||||||
|
|
||||||
|
//pub use query::GraphqlQuery;
|
||||||
|
//pub use response::GraphqlResponse;
|
0
dpts-core/src/graphql/response.rs
Normal file
0
dpts-core/src/graphql/response.rs
Normal file
11
dpts-core/src/lib.rs
Normal file
11
dpts-core/src/lib.rs
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
pub mod config;
|
||||||
|
mod database_connection;
|
||||||
|
pub mod error;
|
||||||
|
mod graphql;
|
||||||
|
|
||||||
|
pub use database_connection::*;
|
||||||
|
pub use error::Error;
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
}
|
|
@ -7,7 +7,7 @@ repository.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dpts-entity = { workspace = true }
|
dpts-entity = { workspace = true }
|
||||||
dpts-error = { workspace = true }
|
|
||||||
chrono = { workspace = true }
|
chrono = { workspace = true }
|
||||||
serde = { workspace = true }
|
serde = { workspace = true }
|
||||||
csv = "1.3.1"
|
csv = "1.3.1"
|
||||||
|
thiserror.workspace = true
|
||||||
|
|
7
dpts-csv/src/error.rs
Normal file
7
dpts-csv/src/error.rs
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Parse int error")]
|
||||||
|
ParseInt(#[from] std::num::ParseIntError),
|
||||||
|
#[error("Missing config value: ({0})")]
|
||||||
|
MissingConfig(String)
|
||||||
|
}
|
|
@ -1,15 +1,15 @@
|
||||||
|
pub mod error;
|
||||||
mod reader;
|
mod reader;
|
||||||
mod record;
|
mod record;
|
||||||
mod table;
|
mod table;
|
||||||
mod writer;
|
mod writer;
|
||||||
|
|
||||||
|
use error::Error;
|
||||||
pub use reader::CsvReader;
|
pub use reader::CsvReader;
|
||||||
pub use record::CsvRecord;
|
pub use record::CsvRecord;
|
||||||
pub use table::CsvTable;
|
pub use table::CsvTable;
|
||||||
pub use writer::CsvWriter;
|
pub use writer::CsvWriter;
|
||||||
|
|
||||||
use dpts_error::Error;
|
|
||||||
|
|
||||||
use chrono::{DateTime, NaiveDateTime};
|
use chrono::{DateTime, NaiveDateTime};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
use chrono::{DateTime, NaiveDateTime};
|
use chrono::{DateTime, NaiveDateTime};
|
||||||
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
use serde::{Deserialize, Deserializer, Serialize, Serializer};
|
||||||
use dpts_entity::RecordDetailModel;
|
use dpts_entity::RecordDetailModel;
|
||||||
use dpts_error::Error;
|
use crate::error::Error;
|
||||||
|
|
||||||
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
#[derive(Debug, Deserialize, PartialEq, Serialize)]
|
||||||
pub struct CsvRecord{
|
pub struct CsvRecord{
|
||||||
|
|
|
@ -1,4 +1,4 @@
|
||||||
use dpts_error::Error;
|
use crate::error::Error;
|
||||||
use super::CsvRecord;
|
use super::CsvRecord;
|
||||||
pub struct CsvTable{
|
pub struct CsvTable{
|
||||||
inner: Vec<CsvRecord>
|
inner: Vec<CsvRecord>
|
||||||
|
|
|
@ -1,7 +0,0 @@
|
||||||
mod connection;
|
|
||||||
|
|
||||||
pub use connection::*;
|
|
||||||
|
|
||||||
#[cfg(test)]
|
|
||||||
mod tests {
|
|
||||||
}
|
|
|
@ -25,6 +25,3 @@ features = [
|
||||||
"with-chrono",
|
"with-chrono",
|
||||||
]
|
]
|
||||||
default-features = false
|
default-features = false
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
dpts-database = { workspace = true, features = ["test"] }
|
|
|
@ -1,12 +0,0 @@
|
||||||
[package]
|
|
||||||
name = "dpts-error"
|
|
||||||
version.workspace = true
|
|
||||||
edition.workspace = true
|
|
||||||
license.workspace = true
|
|
||||||
repository.workspace = true
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
anyhow = "1.0.98"
|
|
||||||
thiserror = "2.0.12"
|
|
||||||
clap.workspace = true
|
|
||||||
toml.workspace = true
|
|
|
@ -1,23 +0,0 @@
|
||||||
#[derive(thiserror::Error, Debug)]
|
|
||||||
pub enum Error {
|
|
||||||
#[error("Parser error")]
|
|
||||||
Clap(#[from] clap::Error),
|
|
||||||
#[error("Parse int error")]
|
|
||||||
ParseInt(#[from] std::num::ParseIntError),
|
|
||||||
#[error("IO Error")]
|
|
||||||
Io(#[from] std::io::Error),
|
|
||||||
#[error("Parse toml error")]
|
|
||||||
TomlDe(#[from] toml::de::Error),
|
|
||||||
#[error("Missing config value: ({0})")]
|
|
||||||
MissingConfig(String)
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Error {
|
|
||||||
pub fn print(&self) -> Result<(), Error> {
|
|
||||||
match self {
|
|
||||||
Error::Clap(x) => Ok(x.print()?),
|
|
||||||
_ => unimplemented!(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -6,6 +6,11 @@ edition.workspace = true
|
||||||
repository.workspace = true
|
repository.workspace = true
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
dpts = {workspace = true}
|
dpts-core = {workspace = true}
|
||||||
chrono = {workspace = true}
|
chrono = {workspace = true}
|
||||||
clap = {workspace = true, features = ["derive"]}
|
clap = {workspace = true, features = ["derive"]}
|
||||||
|
axum = "0.8.4"
|
||||||
|
serde.workspace = true
|
||||||
|
thiserror.workspace = true
|
||||||
|
tokio.workspace = true
|
||||||
|
toml.workspace = true
|
||||||
|
|
29
dpts-server/src/args.rs
Normal file
29
dpts-server/src/args.rs
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
use crate::config::PartialServerConfig;
|
||||||
|
use clap::Parser;
|
||||||
|
use dpts_core::config::{
|
||||||
|
PartialDatabaseConfig,
|
||||||
|
PartialGlobalConfig,
|
||||||
|
};
|
||||||
|
use std::{
|
||||||
|
net::IpAddr,
|
||||||
|
path::PathBuf,
|
||||||
|
};
|
||||||
|
|
||||||
|
use crate::config::ServerConfig;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Parser)]
|
||||||
|
#[command(version, about, long_about = None)]
|
||||||
|
pub struct Args {
|
||||||
|
#[command(flatten)]
|
||||||
|
pub server: PartialServerConfig,
|
||||||
|
|
||||||
|
#[command(flatten)]
|
||||||
|
pub global: PartialGlobalConfig,
|
||||||
|
|
||||||
|
#[command(flatten)]
|
||||||
|
pub database: PartialDatabaseConfig,
|
||||||
|
|
||||||
|
#[arg(short, long)]
|
||||||
|
pub config_file: Option<PathBuf>,
|
||||||
|
}
|
||||||
|
|
|
@ -1,9 +1,7 @@
|
||||||
use chrono_tz::{Tz, UTC};
|
use crate::error::Error;
|
||||||
use crate::{
|
|
||||||
get_host_time_zone_or_utc,
|
use dpts_core::config::{
|
||||||
DatabaseConfig,
|
DatabaseConfig, GlobalConfig, PartialDatabaseConfig
|
||||||
PartialDatabaseConfig,
|
|
||||||
Error
|
|
||||||
};
|
};
|
||||||
use serde::Deserialize;
|
use serde::Deserialize;
|
||||||
use std::{
|
use std::{
|
||||||
|
@ -13,14 +11,37 @@ use std::{
|
||||||
};
|
};
|
||||||
use tokio::sync::OnceCell;
|
use tokio::sync::OnceCell;
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||||
|
pub struct Config {
|
||||||
|
global: GlobalConfig,
|
||||||
|
database: DatabaseConfig,
|
||||||
|
server: ServerConfig,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl TryFrom<PartialConfig> for Config {
|
||||||
|
type Error = Error;
|
||||||
|
fn try_from(p: PartialConfig) -> Result<Config, Self::Error> {
|
||||||
|
Ok(Config {
|
||||||
|
global: p.global.ok_or(Error::MissingConfig("global".to_string()))?,
|
||||||
|
database: p.database.ok_or(Error::MissingConfig("global".to_string()))?,
|
||||||
|
server: p.server.ok_or(Error::MissingConfig("global".to_string()))?,
|
||||||
|
})
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||||
|
pub struct PartialConfig {
|
||||||
|
global: Option<GlobalConfig>,
|
||||||
|
database: Option<DatabaseConfig>,
|
||||||
|
server: Option<ServerConfig>,
|
||||||
|
}
|
||||||
|
|
||||||
pub static SERVER_CONFIG: OnceServerConfig = OnceServerConfig::const_new();
|
pub static SERVER_CONFIG: OnceServerConfig = OnceServerConfig::const_new();
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||||
pub struct ServerConfig {
|
pub struct ServerConfig {
|
||||||
pub listen_ips: Vec<IpAddr>,
|
pub listen_ips: Vec<IpAddr>,
|
||||||
pub port: u16,
|
pub port: u16,
|
||||||
pub time_zone: Tz,
|
|
||||||
pub database: DatabaseConfig
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ServerConfig {
|
impl ServerConfig {
|
||||||
|
@ -33,8 +54,6 @@ impl TryFrom<PartialServerConfig> for ServerConfig {
|
||||||
Ok(ServerConfig{
|
Ok(ServerConfig{
|
||||||
listen_ips: p.listen_ips.ok_or(Error::MissingConfig("listen_ips".to_string()))?,
|
listen_ips: p.listen_ips.ok_or(Error::MissingConfig("listen_ips".to_string()))?,
|
||||||
port: p.port.ok_or(Error::MissingConfig("port".to_string()))?,
|
port: p.port.ok_or(Error::MissingConfig("port".to_string()))?,
|
||||||
database: p.database.ok_or(Error::MissingConfig("database.*".to_string()))?.try_into()?,
|
|
||||||
time_zone: p.time_zone.ok_or(Error::MissingConfig("time_zone".to_string()))?,
|
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -61,12 +80,13 @@ impl OnceServerConfig {
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
#[derive(Clone, Debug, Deserialize, PartialEq)]
|
||||||
|
#[derive(clap::Args)]
|
||||||
|
|
||||||
pub struct PartialServerConfig {
|
pub struct PartialServerConfig {
|
||||||
|
#[arg(short, long,)]
|
||||||
pub listen_ips: Option<Vec<IpAddr>>,
|
pub listen_ips: Option<Vec<IpAddr>>,
|
||||||
|
#[arg(short, long,)]
|
||||||
pub port: Option<u16>,
|
pub port: Option<u16>,
|
||||||
pub database: Option<PartialDatabaseConfig>,
|
|
||||||
pub time_zone: Option<Tz>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialServerConfig {
|
impl PartialServerConfig {
|
||||||
|
@ -81,8 +101,6 @@ impl Default for PartialServerConfig {
|
||||||
PartialServerConfig {
|
PartialServerConfig {
|
||||||
listen_ips: Some(vec!["127.0.0.1".parse().unwrap(), "::1".parse().unwrap()]),
|
listen_ips: Some(vec!["127.0.0.1".parse().unwrap(), "::1".parse().unwrap()]),
|
||||||
port: Some(3000),
|
port: Some(3000),
|
||||||
database: None,
|
|
||||||
time_zone: Some(get_host_time_zone_or_utc())
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
10
dpts-server/src/error.rs
Normal file
10
dpts-server/src/error.rs
Normal file
|
@ -0,0 +1,10 @@
|
||||||
|
#[derive(thiserror::Error, Debug)]
|
||||||
|
pub enum Error {
|
||||||
|
#[error("Parse int error")]
|
||||||
|
ParseInt(#[from] std::num::ParseIntError),
|
||||||
|
#[error("Parse toml error")]
|
||||||
|
TomlDe(#[from] toml::de::Error),
|
||||||
|
#[error("Missing config value: ({0})")]
|
||||||
|
MissingConfig(String)
|
||||||
|
|
||||||
|
}
|
4
dpts-server/src/lib.rs
Normal file
4
dpts-server/src/lib.rs
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
mod args;
|
||||||
|
mod config;
|
||||||
|
pub mod error;
|
||||||
|
pub use args::Args;
|
|
@ -1,3 +1,8 @@
|
||||||
|
use dpts_server::Args;
|
||||||
|
|
||||||
|
use clap::Parser;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
println!("Hello, world!");
|
let args = Args::parse();
|
||||||
|
println!("{:?}", args);
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,4 +0,0 @@
|
||||||
pub use dpts_csv as csv;
|
|
||||||
pub use dpts_entity as entity;
|
|
||||||
pub use dpts_error as error;
|
|
||||||
pub use dpts_migration as migration;
|
|
Loading…
Add table
Reference in a new issue