From 4b3484e7d31fee81e94e2bd2a67b916f6bfbb52e Mon Sep 17 00:00:00 2001 From: fluo10 Date: Thu, 8 May 2025 06:33:08 +0900 Subject: [PATCH] Add user command --- Cargo.lock | 181 +++++++++++++++++- Cargo.toml | 1 + dpts-cli/src/error.rs | 20 -- dpts-cli/src/init.rs | 25 +-- dpts-cli/src/main.rs | 5 +- dpts-cli/src/user.rs | 45 +++++ dpts-client/Cargo.toml | 1 + dpts-client/src/config/mod.rs | 66 +++++-- dpts-client/src/error.rs | 10 - dpts-client/src/lib.rs | 3 +- dpts-core/Cargo.toml | 1 + dpts-core/src/config/global.rs | 4 +- dpts-core/src/entity/mod.rs | 1 + dpts-core/src/entity/user.rs | 26 ++- dpts-core/src/error.rs | 28 ++- dpts-core/src/graphql/mod.rs | 6 +- dpts-core/src/graphql/mutation.rs | 10 - dpts-core/src/graphql/query.rs | 18 -- dpts-core/src/graphql/user.rs | 32 ++-- .../src/{graphql.rs => graphql/mod.rs} | 13 +- dpts-server/src/graphql/mutation.rs | 16 ++ dpts-server/src/graphql/query.rs | 22 +++ dpts-server/src/lib.rs | 2 +- dpts-server/src/main.rs | 5 +- 24 files changed, 418 insertions(+), 123 deletions(-) delete mode 100644 dpts-cli/src/error.rs create mode 100644 dpts-cli/src/user.rs delete mode 100644 dpts-client/src/error.rs delete mode 100644 dpts-core/src/graphql/mutation.rs delete mode 100644 dpts-core/src/graphql/query.rs rename dpts-server/src/{graphql.rs => graphql/mod.rs} (76%) create mode 100644 dpts-server/src/graphql/mutation.rs create mode 100644 dpts-server/src/graphql/query.rs diff --git a/Cargo.lock b/Cargo.lock index 7056365..1a30cac 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -486,6 +486,12 @@ version = "1.7.3" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "89e25b6adfb930f02d1981565a6e5d9c547ac15a96606256d3b59040e5cd4ca3" +[[package]] +name = "beef" +version = "0.5.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3a8241f3ebb85c056b509d4327ad0358fbbba6ffb340bf388f26350aeda225b1" + [[package]] name = "bitflags" version = "2.9.0" @@ -618,7 +624,7 @@ dependencies = [ "anstream", "anstyle", "clap_lex", - "strsim", + "strsim 0.11.1", ] [[package]] @@ -746,6 +752,59 @@ dependencies = [ "memchr", ] +[[package]] +name = "cynic" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c99c59968c8aa7f90d84240ab6ded4d3864125ce36b5b044554542cebc974946" +dependencies = [ + "cynic-proc-macros", + "ref-cast", + "serde", + "static_assertions", + "thiserror 1.0.69", +] + +[[package]] +name = "cynic-codegen" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "332695dddff7f260dfda1e97502b6440d443816f576994548b7751494991d2e3" +dependencies = [ + "cynic-parser", + "darling", + "once_cell", + "ouroboros", + "proc-macro2", + "quote", + "strsim 0.10.0", + "syn 2.0.100", + "thiserror 1.0.69", +] + +[[package]] +name = "cynic-parser" +version = "0.9.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cbb0f21f2f8d3134c2e887a16564c165694231f48b6ae2769193299081ecf662" +dependencies = [ + "indexmap", + "lalrpop-util", + "logos", +] + +[[package]] +name = "cynic-proc-macros" +version = "3.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a7880789c425a73aff3ba286b2a9c794f330d4770769a42a1493d6175e4606c1" +dependencies = [ + "cynic-codegen", + "darling", + "quote", + "syn 2.0.100", +] + [[package]] name = "darling" version = "0.20.11" @@ -766,7 +825,7 @@ dependencies = [ "ident_case", "proc-macro2", "quote", - "strsim", + "strsim 0.11.1", "syn 2.0.100", ] @@ -810,6 +869,27 @@ dependencies = [ "subtle", ] +[[package]] +name = "dirs" +version = "6.0.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c3e8aa94d75141228480295a7d0e7feb620b1a5ad9f12bc40be62411e38cce4e" +dependencies = [ + "dirs-sys", +] + +[[package]] +name = "dirs-sys" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e01a3366d27ee9890022452ee61b2b63a67e6f13f58900b651ff5665f0bb1fab" +dependencies = [ + "libc", + "option-ext", + "redox_users", + "windows-sys 0.59.0", +] + [[package]] name = "displaydoc" version = "0.2.5" @@ -852,6 +932,7 @@ version = "0.1.0" dependencies = [ "chrono-tz", "clap", + "dirs", "dpts-core", "serde", "thiserror 2.0.12", @@ -869,6 +950,7 @@ dependencies = [ "chrono-tz", "clap", "csv", + "cynic", "dotenv", "dpts-migration", "iana-time-zone", @@ -1602,6 +1684,15 @@ dependencies = [ "log", ] +[[package]] +name = "lalrpop-util" +version = "0.22.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "e8d05b3fe34b8bd562c338db725dfa9beb9451a48f65f129ccb9538b48d2c93b" +dependencies = [ + "rustversion", +] + [[package]] name = "lazy_static" version = "1.5.0" @@ -1623,6 +1714,16 @@ version = "0.2.13" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "c9627da5196e5d8ed0b0495e61e518847578da83483c37288316d9b2e03a7f72" +[[package]] +name = "libredox" +version = "0.1.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "c0ff37bd590ca25063e35af745c343cb7a0271906fb7b37e4813e8f79f00268d" +dependencies = [ + "bitflags", + "libc", +] + [[package]] name = "libsqlite3-sys" version = "0.30.1" @@ -1671,6 +1772,39 @@ dependencies = [ "value-bag", ] +[[package]] +name = "logos" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7251356ef8cb7aec833ddf598c6cb24d17b689d20b993f9d11a3d764e34e6458" +dependencies = [ + "logos-derive", +] + +[[package]] +name = "logos-codegen" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "59f80069600c0d66734f5ff52cc42f2dabd6b29d205f333d61fd7832e9e9963f" +dependencies = [ + "beef", + "fnv", + "lazy_static", + "proc-macro2", + "quote", + "regex-syntax 0.8.5", + "syn 2.0.100", +] + +[[package]] +name = "logos-derive" +version = "0.14.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "24fb722b06a9dc12adb0963ed585f19fc61dc5413e6a9be9422ef92c091e731d" +dependencies = [ + "logos-codegen", +] + [[package]] name = "matchers" version = "0.1.0" @@ -1868,6 +2002,12 @@ dependencies = [ "vcpkg", ] +[[package]] +name = "option-ext" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "04744f49eae99ab78e0d5c0b603ab218f515ea8cfe5a456d7629ad883a3b6e7d" + [[package]] name = "ordered-float" version = "4.6.0" @@ -2258,6 +2398,37 @@ dependencies = [ "bitflags", ] +[[package]] +name = "redox_users" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "dd6f9d3d47bdd2ad6945c5015a226ec6155d0bcdfd8f7cd29f86b71f8de99d2b" +dependencies = [ + "getrandom 0.2.16", + "libredox", + "thiserror 2.0.12", +] + +[[package]] +name = "ref-cast" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4a0ae411dbe946a674d89546582cea4ba2bb8defac896622d6496f14c23ba5cf" +dependencies = [ + "ref-cast-impl", +] + +[[package]] +name = "ref-cast-impl" +version = "1.0.24" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "1165225c21bff1f3bbce98f5a1f889949bc902d3575308cc7b0de30b4f6d27c7" +dependencies = [ + "proc-macro2", + "quote", + "syn 2.0.100", +] + [[package]] name = "regex" version = "1.11.1" @@ -2980,6 +3151,12 @@ dependencies = [ "unicode-properties", ] +[[package]] +name = "strsim" +version = "0.10.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "73473c0e59e6d5812c5dfe2a064a6444949f089e20eec9a2e5506596494e4623" + [[package]] name = "strsim" version = "0.11.1" diff --git a/Cargo.toml b/Cargo.toml index 91ff2f7..6be57ce 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -11,6 +11,7 @@ dpts-server = { path = "dpts-server" } chrono = {version = "0.4", features = ["serde"]} chrono-tz = {version = "0.10.3", features = ["serde"]} clap = {version = "4.5", features = ["derive"]} +dirs = "6.0.0" dotenv = "0.15.0" serde = { version = "1.0", features = ["derive"] } thiserror = "2.0.12" diff --git a/dpts-cli/src/error.rs b/dpts-cli/src/error.rs deleted file mode 100644 index c834783..0000000 --- a/dpts-cli/src/error.rs +++ /dev/null @@ -1,20 +0,0 @@ -#[derive(thiserror::Error, Debug)] -pub enum Error { - #[error("Parse int error")] - ParseInt(#[from] std::num::ParseIntError), - #[error("Missing config value: ({0})")] - MissingConfig(String), - #[error("Parse toml error")] - TomlDe(#[from] toml::de::Error), - -} - -impl From for Error { - fn from(e: dpts_client::error::Error) -> Self { - match e { - dpts_client::error::Error::TomlDe(x)=> Self::TomlDe(x), - dpts_client::error::Error::ParseInt(x) => Self::ParseInt(x), - dpts_client::error::Error::MissingConfig(x) => Self::MissingConfig(x), - } - } -} diff --git a/dpts-cli/src/init.rs b/dpts-cli/src/init.rs index 1bb50fe..aa665e5 100644 --- a/dpts-cli/src/init.rs +++ b/dpts-cli/src/init.rs @@ -3,11 +3,7 @@ use chrono_tz::Tz; use crate::error::Error; use dpts_client::auth::try_login; use dpts_client::config::{ - Config, - ClientConfig, - ClientRemoteStorageConfig, - ClientStorageConfig, - PartialGlobalConfig + ClientConfig, ClientRemoteStorageConfig, ClientStorageConfig, Config, GlobalConfig, PartialGlobalConfig }; #[derive(Args, Clone, Debug)] @@ -17,10 +13,10 @@ pub struct InitArgs { } impl InitArgs { - pub fn run(self) -> Result<(), Error> { + pub async fn run(self) -> Result<(), Error> { match self.command { - InitCommand::Local(x) => x.run(), - InitCommand::Remote(x) => x.run(), + InitCommand::Local(x) => x.run().await, + InitCommand::Remote(x) => x.run().await, } } } @@ -33,11 +29,14 @@ enum InitCommand { #[derive(Args, Clone, Debug)] pub struct InitLocalArgs { + #[arg(short, long)] pub time_zone: Option, + #[arg(short, long)] + pub force: bool } impl InitLocalArgs { - pub fn run(self) -> Result<(), Error> { + pub async fn run(self) -> Result<(), Error> { unimplemented!() } } @@ -51,13 +50,15 @@ pub struct InitRemoteArgs { pub password: String, #[arg(short, long)] pub time_zone: Option, + #[arg(short, long)] + pub force: bool, } impl InitRemoteArgs { - pub fn run(self) -> Result<(), Error> { + pub async fn run(self) -> Result<(), Error> { let token: String = try_login(&self.user_name, &self.password, &self.endpoint)?; let config: Config = Config{ - global: PartialGlobalConfig { + global: GlobalConfig { time_zone: self.time_zone.clone() }, client: ClientConfig { @@ -67,6 +68,6 @@ impl InitRemoteArgs { }), } }; - todo!() // Write config + config.write_to_default_toml().await } } diff --git a/dpts-cli/src/main.rs b/dpts-cli/src/main.rs index aafd4ba..b8ac6a6 100644 --- a/dpts-cli/src/main.rs +++ b/dpts-cli/src/main.rs @@ -1,8 +1,9 @@ //mod label; -pub mod error; mod init; mod record; +mod user; +pub use dpts_client::error; //use label::LabelArgs; @@ -33,7 +34,7 @@ async fn main() -> Result<(), Error> { let cli = Cli::parse(); match cli.command { //Some(Commands::Add(x)) => x.run(), - Command::Init(x) => x.run(), + Command::Init(x) => x.run().await, //Some(Commands::Label(x)) => x.run(), Command::Record(x) => x.run(), diff --git a/dpts-cli/src/user.rs b/dpts-cli/src/user.rs new file mode 100644 index 0000000..18fefe1 --- /dev/null +++ b/dpts-cli/src/user.rs @@ -0,0 +1,45 @@ +use clap::{Args, Subcommand}; +use crate::error::Error; +use dpts_client::config::Config; + + +#[derive(Args, Clone, Debug)] +pub struct UserArgs { + #[command(subcommand)] + pub command: UserCommand, +} + +impl UserArgs { + pub async fn run(self) -> Result<(), Error> { + Config::read_from_default_toml().await?.set_global(); + match self.command { + UserCommand::Add(x) => x.add().await, + UserCommand::List => todo!(), + UserCommand::Modify(x) => x.modify().await, + } + } +} +#[derive(Clone, Debug, Subcommand)] + +enum UserCommand { + List, + Add(UserDataArgs), + Modify(UserDataArgs) +} + +#[derive(Args, Clone, Debug)] +pub struct UserDataArgs { + #[arg(short, long)] + pub user_name: String, + #[arg(short, long)] + pub password: String, +} + +impl UserDataArgs { + pub async fn add(self) -> Result<(), Error> { + todo!() + } + pub async fn modify(self) -> Result<(), Error> { + todo!() + } +} diff --git a/dpts-client/Cargo.toml b/dpts-client/Cargo.toml index d2e4e34..9e7099f 100644 --- a/dpts-client/Cargo.toml +++ b/dpts-client/Cargo.toml @@ -10,6 +10,7 @@ clap = ["dep:clap"] [dependencies] chrono-tz.workspace = true clap = { workspace = true, optional = true } +dirs.workspace = true dpts-core.workspace = true serde.workspace = true thiserror.workspace = true diff --git a/dpts-client/src/config/mod.rs b/dpts-client/src/config/mod.rs index 9c22367..50aef53 100644 --- a/dpts-client/src/config/mod.rs +++ b/dpts-client/src/config/mod.rs @@ -1,27 +1,72 @@ mod storage; +use std::{fmt::{Display, Formatter}, path::{Path, PathBuf}, str::FromStr}; + pub use dpts_core::config::*; pub use storage::*; - - use crate::error::Error; use serde::{ Deserialize, Serialize }; -use tokio::sync::OnceCell; +use tokio::{fs::{self, File}, io::AsyncWriteExt, sync::OnceCell}; + +pub static DEFAULT_CONFIG_FILE_NAME: &str = "dpts_client.toml"; +pub static DEFAULT_CONFIG_DIR_NAME: &str = "dpts"; pub static CLIENT_CONFIG: OnceCell = OnceCell::const_new(); +pub fn get_default_config_file_path() -> Result { + let config_dir = dirs::config_dir().ok_or(Error::DefaultConfigDir)?; + Ok(config_dir.join(DEFAULT_CONFIG_DIR_NAME).join(DEFAULT_CONFIG_FILE_NAME)) +} + #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct Config { pub client: ClientConfig, - pub global: PartialGlobalConfig, + pub global: GlobalConfig, } +impl Config { + pub async fn read_from_default_toml() -> Result { + Ok(Self::read_from_toml(&get_default_config_file_path()?).await?) + } + pub async fn write_to_default_toml(&self) -> Result<(), Error> { + Ok(self.write_to_toml(&get_default_config_file_path()?).await?) + } + pub async fn write_to_toml(&self, p: &Path) -> Result<(), Error> { + let toml = self.to_toml()?; + let mut file = File::create(p).await?; + file.write_all(toml.as_bytes()).await?; + Ok(()) + } + pub async fn read_from_toml(p: &Path) -> Result { + let raw = fs::read_to_string(p).await?; + Ok(Self::from_toml(&raw)?) + } + pub fn from_toml(s: &str) -> Result { + Ok(toml::from_str(s)?) + } + pub fn to_toml(&self) -> Result { + Ok(toml::to_string(self)?) + } + pub fn set_global(self) -> Result<(), Error> { + CLIENT_CONFIG.set(self.client)?; + GLOBAL_CONFIG.set(self.global)?; + Ok(()) + } + pub fn from_global() -> Result { + Ok(Self { + client: CLIENT_CONFIG.get().ok_or(Error::UninitializedOnceCell("CLIENT_CONFIG".to_string()))?.clone(), + global: GLOBAL_CONFIG.get().ok_or(Error::UninitializedOnceCell("GLOBAL_CONFIG".to_string()))?.clone(), + }) + } +} + + #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct ClientConfig { pub storage: ClientStorageConfig, @@ -47,19 +92,19 @@ storage = "local" client: ClientConfig{ storage: ClientStorageConfig::Local, }, - global: PartialGlobalConfig { time_zone: None }, + global: GlobalConfig { time_zone: None }, } }).await } #[tokio::test] async fn deserialize_local_storage_client_config() { - let config: Config = toml::from_str(LOCAL_STORAGE_CONFIG_TOML).unwrap(); + let config: Config = Config::from_toml(LOCAL_STORAGE_CONFIG_TOML).unwrap(); assert_eq!(&config, get_local_storage_client_config_struct().await); } #[tokio::test] async fn serialize_local_storage_client_config() { - assert_eq!(LOCAL_STORAGE_CONFIG_TOML, toml::to_string(get_local_storage_client_config_struct().await).unwrap()); + assert_eq!(LOCAL_STORAGE_CONFIG_TOML, get_local_storage_client_config_struct().await.to_toml().unwrap()); } const REMOTE_STORAGE_CONFIG_TOML: &str = r#"[client.storage.remote] @@ -80,19 +125,18 @@ time_zone = "UTC" access_key: "test".to_string(), }) }, - global: PartialGlobalConfig { time_zone: Some(UTC) } + global: GlobalConfig { time_zone: Some(UTC) } } }).await } #[tokio::test] - async fn deserialize_remote_storage_client_config() { - let config: Config = toml::from_str(REMOTE_STORAGE_CONFIG_TOML).unwrap(); + async fn deserialize_remote_storage_client_config() { let config: Config = Config::from_toml(REMOTE_STORAGE_CONFIG_TOML).unwrap(); assert_eq!(&config, get_remote_storage_client_config_struct().await); } #[tokio::test] async fn serialize_remote_storage_client_config() { - assert_eq!(REMOTE_STORAGE_CONFIG_TOML, toml::to_string(get_remote_storage_client_config_struct().await).unwrap()); + assert_eq!(REMOTE_STORAGE_CONFIG_TOML, get_remote_storage_client_config_struct().await.to_toml().unwrap()); } } diff --git a/dpts-client/src/error.rs b/dpts-client/src/error.rs deleted file mode 100644 index 1c8363f..0000000 --- a/dpts-client/src/error.rs +++ /dev/null @@ -1,10 +0,0 @@ -#[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) - -} diff --git a/dpts-client/src/lib.rs b/dpts-client/src/lib.rs index db8ca9f..1fe99a2 100644 --- a/dpts-client/src/lib.rs +++ b/dpts-client/src/lib.rs @@ -1,8 +1,7 @@ pub mod auth; pub mod config; -pub mod error; -use error::Error; +pub use dpts_core::error; diff --git a/dpts-core/Cargo.toml b/dpts-core/Cargo.toml index 1220be9..e33fe51 100644 --- a/dpts-core/Cargo.toml +++ b/dpts-core/Cargo.toml @@ -16,6 +16,7 @@ chrono = {workspace = true} chrono-tz.workspace = true clap = { workspace = true, optional = true } csv = "1.3.1" +cynic = "3.10.0" dotenv = {workspace = true} dpts-migration = { workspace = true } iana-time-zone = "0.1.63" diff --git a/dpts-core/src/config/global.rs b/dpts-core/src/config/global.rs index 9378664..37a6fd0 100644 --- a/dpts-core/src/config/global.rs +++ b/dpts-core/src/config/global.rs @@ -9,14 +9,14 @@ use crate::Error; #[derive(Clone, Debug, Deserialize, PartialEq, Serialize)] pub struct GlobalConfig { - pub time_zone: Tz, + pub time_zone: Option, } impl TryFrom for GlobalConfig{ type Error = Error; fn try_from(p: PartialGlobalConfig) -> Result { Ok(GlobalConfig{ - time_zone: p.time_zone.ok_or(Error::MissingConfig("time_zone".to_string()))?, + time_zone: p.time_zone, }) } } diff --git a/dpts-core/src/entity/mod.rs b/dpts-core/src/entity/mod.rs index 1292db7..7461782 100644 --- a/dpts-core/src/entity/mod.rs +++ b/dpts-core/src/entity/mod.rs @@ -5,6 +5,7 @@ mod user; pub use user::{ ActiveModel as UserActiveModel, + Column as UserColumn, Entity as UserEntity, Model as UserModel, }; diff --git a/dpts-core/src/entity/user.rs b/dpts-core/src/entity/user.rs index 5ae0363..27b18b7 100644 --- a/dpts-core/src/entity/user.rs +++ b/dpts-core/src/entity/user.rs @@ -2,6 +2,9 @@ use async_graphql::SimpleObject; use chrono::{DateTime, FixedOffset,}; use sea_orm::entity::prelude::*; use serde::{Deserialize, Serialize}; +use crate::error::Error; + +use crate::DATABASE_CONNECTION; #[derive(Clone, Debug, PartialEq, DeriveEntityModel, Serialize, SimpleObject, Deserialize)] #[sea_orm(table_name = "user")] @@ -17,6 +20,22 @@ pub struct Model { pub updated_at: DateTimeWithTimeZone, } +impl Entity { + pub async fn find_by_name(user_name: &str) -> Result, Error> { + Ok(Entity::find() + .filter(Column::LoginName.contains(user_name)) + .one(DATABASE_CONNECTION.get().unwrap()) + .await? + ) + } + pub async fn find_all() -> Result, Error> { + Ok(Entity::find() + .all(DATABASE_CONNECTION.get().unwrap()) + .await? + ) + } +} + #[derive(Copy, Clone, Debug, DeriveRelation, EnumIter)] pub enum Relation { #[sea_orm(has_many = "super::record_header::Entity")] @@ -36,5 +55,10 @@ impl Related for Model { Relation::RecordTag.def() } } +impl ActiveModel { + pub async fn create_user(login_name: &str, password: &str) -> Result{ + todo!() + } +} +impl ActiveModelBehavior for ActiveModel {} -impl ActiveModelBehavior for ActiveModel {} \ No newline at end of file diff --git a/dpts-core/src/error.rs b/dpts-core/src/error.rs index 1c8363f..05657ca 100644 --- a/dpts-core/src/error.rs +++ b/dpts-core/src/error.rs @@ -1,10 +1,32 @@ #[derive(thiserror::Error, Debug)] pub enum Error { + #[error("IO error")] + Io(#[from] std::io::Error), #[error("Parse int error")] ParseInt(#[from] std::num::ParseIntError), - #[error("Parse toml error")] + #[error("Deserialize toml error")] TomlDe(#[from] toml::de::Error), + #[error("Serialize toml error")] + TomlSer(#[from] toml::ser::Error), #[error("Missing config value: ({0})")] - MissingConfig(String) - + MissingConfig(String), + #[error("Cannot get default config directory")] + DefaultConfigDir, + #[error("Uninitialized global var: {0}")] + UninitializedOnceCell(String), + #[error("Once cell is initializing: {0}")] + InitializingOnceCell(String), + #[error("Once cell is already Initialized: {0}")] + AlreadyInitializedOnceCell(String), + #[error("DB Error: {0}")] + Db(#[from]sea_orm::DbErr), +} + +impl From> for Error{ + fn from(e: tokio::sync::SetError) -> Self { + match e { + tokio::sync::SetError::AlreadyInitializedError(_) => Self::AlreadyInitializedOnceCell(std::any::type_name::().to_string()), + tokio::sync::SetError::InitializingError(_) => Self::InitializingOnceCell(std::any::type_name::().to_string()) + } + } } diff --git a/dpts-core/src/graphql/mod.rs b/dpts-core/src/graphql/mod.rs index 805ba9f..846cabf 100644 --- a/dpts-core/src/graphql/mod.rs +++ b/dpts-core/src/graphql/mod.rs @@ -1,10 +1,6 @@ -mod mutation; -mod query; mod record_detail; mod record_header; mod record_tag; mod user; -pub use mutation::Mutation; -pub use query::Query; -pub use user::UserObject; \ No newline at end of file +pub use user::PartialUser; \ No newline at end of file diff --git a/dpts-core/src/graphql/mutation.rs b/dpts-core/src/graphql/mutation.rs deleted file mode 100644 index dd6dbe7..0000000 --- a/dpts-core/src/graphql/mutation.rs +++ /dev/null @@ -1,10 +0,0 @@ -use async_graphql::*; - -pub struct Mutation; - -#[Object] -impl Mutation { - async fn login(&self, username:String, password: String) -> Result { - todo!() - } -} \ No newline at end of file diff --git a/dpts-core/src/graphql/query.rs b/dpts-core/src/graphql/query.rs deleted file mode 100644 index eb65b68..0000000 --- a/dpts-core/src/graphql/query.rs +++ /dev/null @@ -1,18 +0,0 @@ -use async_graphql::{ - *, - http::GraphiQLSource, -}; -use axum::{ - response::{Html, IntoResponse}, - routing::get, - Router, -}; -use super::user::UserObject; -pub struct Query; - -#[Object] -impl Query { - pub async fn user(&self, username: String) -> Result> { - todo!() - } -} \ No newline at end of file diff --git a/dpts-core/src/graphql/user.rs b/dpts-core/src/graphql/user.rs index a98d30e..243e0d9 100644 --- a/dpts-core/src/graphql/user.rs +++ b/dpts-core/src/graphql/user.rs @@ -1,27 +1,27 @@ use async_graphql::*; use chrono::{DateTime, FixedOffset}; +use crate::entity::UserModel; -pub struct UserObject { - pub id: i32, + +#[derive(SimpleObject)] +pub struct PartialUser { + pub id: Option, pub login_name: Option, pub created_at: Option>, pub updated_at: Option>, } -#[Object] -impl UserObject { - async fn id(&self) -> i32 { - todo!() - } - async fn login_name(&self) -> Option { - todo!() - } - async fn created_at(&self) -> Option> { - todo!() - } - async fn updated_at(&self) -> Option> { - todo!() - } +#[derive(SimpleObject)] +pub struct Users{ + users: Vec } +pub struct CreateUser { + login_name: String, + password: String, +} +pub struct ModifyUser { + login_name: Option, + password: Option, +} diff --git a/dpts-server/src/graphql.rs b/dpts-server/src/graphql/mod.rs similarity index 76% rename from dpts-server/src/graphql.rs rename to dpts-server/src/graphql/mod.rs index 9bf1d5f..aa70971 100644 --- a/dpts-server/src/graphql.rs +++ b/dpts-server/src/graphql/mod.rs @@ -1,10 +1,15 @@ +mod mutation; +mod query; + +pub use dpts_core::graphql::*; + +pub use mutation::Mutation; +pub use query::Query; + use async_graphql::{EmptySubscription, Schema}; use async_graphql_axum::GraphQL; use axum::{routing::get, Router}; -use dpts_core::graphql::{ - Query, - Mutation, -}; + pub fn build_schema() -> Schema{ Schema::build(Query, Mutation, EmptySubscription).finish() diff --git a/dpts-server/src/graphql/mutation.rs b/dpts-server/src/graphql/mutation.rs new file mode 100644 index 0000000..3d0b780 --- /dev/null +++ b/dpts-server/src/graphql/mutation.rs @@ -0,0 +1,16 @@ +use async_graphql::*; +use dpts_core::entity::UserModel; + +use crate::{auth::try_hash_password, entity::UserActiveModel}; + +pub struct Mutation; + +#[Object] +impl Mutation { + async fn login(&self, username:String, password: String) -> Result { + todo!() + } + async fn create_user(&self, username:String, password: String) -> Result { + todo!() + } +} \ No newline at end of file diff --git a/dpts-server/src/graphql/query.rs b/dpts-server/src/graphql/query.rs new file mode 100644 index 0000000..e1af075 --- /dev/null +++ b/dpts-server/src/graphql/query.rs @@ -0,0 +1,22 @@ +use async_graphql::{ + *, + http::GraphiQLSource, +}; +use axum::{ + response::{Html, IntoResponse}, + routing::get, + Router, +}; +use crate::{entity::{UserEntity, UserModel},}; + +pub struct Query; + +#[Object] +impl Query { + pub async fn user(&self, user_name: String) -> Result> { + Ok(UserEntity::find_by_name(&user_name).await?) + } + pub async fn users(&self) -> Result> { + Ok(UserEntity::find_all().await?) + } +} \ No newline at end of file diff --git a/dpts-server/src/lib.rs b/dpts-server/src/lib.rs index de54b36..9380797 100644 --- a/dpts-server/src/lib.rs +++ b/dpts-server/src/lib.rs @@ -12,7 +12,7 @@ use async_graphql_axum::{ }; use axum::{routing::get, Router}; use crate::graphql::build_service; - +use dpts_core::entity as entity; pub fn build_app() -> Router { diff --git a/dpts-server/src/main.rs b/dpts-server/src/main.rs index b5ec49f..e20b32d 100644 --- a/dpts-server/src/main.rs +++ b/dpts-server/src/main.rs @@ -1,9 +1,6 @@ use async_graphql::{http::{playground_source, GraphQLPlaygroundConfig}, *}; use async_graphql_axum::GraphQL; -use dpts_core::graphql::{ - Mutation, - Query, -}; + use dpts_server::{build_app, Args}; use axum::{response::{Html, IntoResponse}, routing::get, Router}; use clap::Parser;