diff --git a/Cargo.lock b/Cargo.lock index d230342..212f9ad 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -281,21 +281,6 @@ version = "0.2.21" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "683d7910e743518b0e34f1186f92494becacb047c7b6bf616c96772180fef923" -[[package]] -name = "android-tzdata" -version = "0.1.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e999941b234f3131b00bc13c22d06e8c5ff726d1b6318ac7eb276997bbb4fef0" - -[[package]] -name = "android_system_properties" -version = "0.1.5" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "819e7219dbd41043ac279b19830f2efc897156490d7fd6ea916720117ee66311" -dependencies = [ - "libc", -] - [[package]] name = "anstream" version = "0.6.18" @@ -359,9 +344,9 @@ checksum = "69f7f8c3906b62b754cd5326047894316021dcfe5a194c8ea52bdd94934a3457" [[package]] name = "async-broadcast" -version = "0.7.1" +version = "0.7.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "20cd0e2e25ea8e5f7e9df04578dc6cf5c83577fd09b1a46aaf5c85e1c33f2a7e" +checksum = "435a87a52755b8f27fcf321ac4f04b2802e337c8c4872923137471ec39c37532" dependencies = [ "event-listener", "event-listener-strategy", @@ -749,21 +734,6 @@ version = "0.2.1" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "613afe47fcd5fac7ccf1db93babcb082c5994d996f20b8b159f2ad1658eb5724" -[[package]] -name = "chrono" -version = "0.4.39" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" -dependencies = [ - "android-tzdata", - "iana-time-zone", - "js-sys", - "num-traits", - "serde", - "wasm-bindgen", - "windows-targets 0.52.6", -] - [[package]] name = "cipher" version = "0.4.4" @@ -994,41 +964,6 @@ dependencies = [ "typenum", ] -[[package]] -name = "darling" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6f63b86c8a8826a49b8c21f08a2d07338eec8d900540f8630dc76284be802989" -dependencies = [ - "darling_core", - "darling_macro", -] - -[[package]] -name = "darling_core" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "95133861a8032aaea082871032f5815eb9e98cef03fa916ab4500513994df9e5" -dependencies = [ - "fnv", - "ident_case", - "proc-macro2", - "quote", - "strsim", - "syn 2.0.90", -] - -[[package]] -name = "darling_macro" -version = "0.20.10" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d336a2a514f6ccccaa3e09b02d41d35330c07ddf03a62165fcec10bb561c7806" -dependencies = [ - "darling_core", - "quote", - "syn 2.0.90", -] - [[package]] name = "dashmap" version = "6.1.0" @@ -1228,9 +1163,9 @@ checksum = "a3d8a32ae18130a3c84dd492d4215c3d913c3b07c6b63c2eb3eb7ff1101ab7bf" [[package]] name = "enumflags2" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d232db7f5956f3f14313dc2f87985c58bd2c695ce124c8cdd984e08e15ac133d" +checksum = "ba2f4b465f5318854c6f8dd686ede6c0a9dc67d4b1ac241cf0eb51521a309147" dependencies = [ "enumflags2_derive", "serde", @@ -1238,9 +1173,9 @@ dependencies = [ [[package]] name = "enumflags2_derive" -version = "0.7.10" +version = "0.7.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "de0d48a183585823424a4ce1aa132d174a6a81bd540895822eb4c8373a8e49e8" +checksum = "fc4caf64a58d7a6d65ab00639b046ff54399a39f5f2554728895ace4b297cd79" dependencies = [ "proc-macro2", "quote", @@ -1265,9 +1200,9 @@ dependencies = [ [[package]] name = "event-listener" -version = "5.3.1" +version = "5.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "6032be9bd27023a771701cc49f9f053c751055f71efb2e0ae5c15809093675ba" +checksum = "3492acde4c3fc54c845eaab3eed8bd00c7a7d881f78bfc801e43a93dec1331ae" dependencies = [ "concurrent-queue", "parking", @@ -2641,29 +2576,6 @@ dependencies = [ "tracing", ] -[[package]] -name = "iana-time-zone" -version = "0.1.61" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "235e081f3925a06703c2d0117ea8b91f042756fd6e7a6e5d901e8ca1a996b220" -dependencies = [ - "android_system_properties", - "core-foundation-sys", - "iana-time-zone-haiku", - "js-sys", - "wasm-bindgen", - "windows-core 0.52.0", -] - -[[package]] -name = "iana-time-zone-haiku" -version = "0.1.2" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f31827a206f56af32e590ba56d5d2d085f558508192593743f16b2306495269f" -dependencies = [ - "cc", -] - [[package]] name = "icu_collections" version = "1.5.0" @@ -2782,12 +2694,6 @@ dependencies = [ "syn 2.0.90", ] -[[package]] -name = "ident_case" -version = "1.0.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b9e0384b61958566e926dc50660321d12159025e767c18e043daf26b70104c39" - [[package]] name = "idna" version = "1.0.3" @@ -2823,7 +2729,6 @@ checksum = "bd070e393353796e801d209ad339e89596eb4c8d430d18ede6a1cced8fafbd99" dependencies = [ "autocfg", "hashbrown 0.12.3", - "serde", ] [[package]] @@ -2834,7 +2739,6 @@ checksum = "62f822373a4fe84d4bb149bf54e584a7f4abec90e072ed49cda0edea5b95471f" dependencies = [ "equivalent", "hashbrown 0.15.2", - "serde", ] [[package]] @@ -2955,25 +2859,29 @@ checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "jiff" -version = "0.1.15" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "db69f08d4fb10524cacdb074c10b296299d71274ddbc830a8ee65666867002e9" +checksum = "c607c728e28764fecde611a2764a3a5db19ae21dcec46f292244f5cc5c085a81" dependencies = [ "jiff-tzdb-platform", + "log", + "portable-atomic", + "portable-atomic-util", + "serde", "windows-sys 0.59.0", ] [[package]] name = "jiff-tzdb" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "91335e575850c5c4c673b9bd467b0e025f164ca59d0564f69d0c2ee0ffad4653" +checksum = "cf2cec2f5d266af45a071ece48b1fb89f3b00b2421ac3a5fe10285a6caaa60d3" [[package]] name = "jiff-tzdb-platform" -version = "0.1.1" +version = "0.1.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9835f0060a626fe59f160437bc725491a6af23133ea906500027d1bd2f8f4329" +checksum = "a63c62e404e7b92979d2792352d885a7f8f83fd1d0d31eea582d77b2ceca697e" dependencies = [ "jiff-tzdb", ] @@ -3008,7 +2916,7 @@ dependencies = [ "log", "secret-service", "security-framework 2.11.1", - "security-framework 3.0.1", + "security-framework 3.2.0", "windows-sys 0.59.0", "zbus", ] @@ -3621,7 +3529,6 @@ dependencies = [ "async-compression", "async-stream", "async_zip", - "chrono", "clap", "console", "dirs", @@ -3632,6 +3539,7 @@ dependencies = [ "gix", "indicatif", "inquire", + "jiff", "keyring", "open", "paste", @@ -3642,7 +3550,6 @@ dependencies = [ "semver", "serde", "serde_json", - "serde_with", "sha2", "tempfile", "thiserror 2.0.11", @@ -3669,7 +3576,6 @@ dependencies = [ "actix-web", "async-compression", "async-stream", - "chrono", "constant_time_eq", "convert_case 0.7.1", "dotenvy", @@ -3677,6 +3583,7 @@ dependencies = [ "futures", "git2", "gix", + "jiff", "pesde", "reqwest", "rusty-s3", @@ -3778,6 +3685,15 @@ version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" +[[package]] +name = "portable-atomic-util" +version = "0.2.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d8a2f0d8d040d7848a709caf78912debcc3f33ee4b3cac47d73d1e1069e83507" +dependencies = [ + "portable-atomic", +] + [[package]] name = "powerfmt" version = "0.2.0" @@ -4353,9 +4269,9 @@ dependencies = [ [[package]] name = "security-framework" -version = "3.0.1" +version = "3.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1415a607e92bec364ea2cf9264646dcce0f91e6d65281bd6f2819cca3bf39c8" +checksum = "271720403f46ca04f7ba6f55d438f8bd878d6b8ca0a1046e8228c4145bcbb316" dependencies = [ "bitflags 2.6.0", "core-foundation 0.10.0", @@ -4366,9 +4282,9 @@ dependencies = [ [[package]] name = "security-framework-sys" -version = "2.12.1" +version = "2.14.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "fa39c7303dc58b5543c94d22c1766b0d31f2ee58306363ea622b10bbc075eaa2" +checksum = "49db231d56a190491cb4aeda9527f1ad45345af50b0851622a7adb8c03b01c32" dependencies = [ "core-foundation-sys", "libc", @@ -4578,36 +4494,6 @@ dependencies = [ "serde", ] -[[package]] -name = "serde_with" -version = "3.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d6b6f7f2fcb69f747921f79f3926bd1e203fce4fef62c268dd3abfb6d86029aa" -dependencies = [ - "base64", - "chrono", - "hex", - "indexmap 1.9.3", - "indexmap 2.7.0", - "serde", - "serde_derive", - "serde_json", - "serde_with_macros", - "time", -] - -[[package]] -name = "serde_with_macros" -version = "3.12.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8d00caa5193a3c8362ac2b73be6b9e768aa5a4b2f721d8f4b339600c3cb51f8e" -dependencies = [ - "darling", - "proc-macro2", - "quote", - "syn 2.0.90", -] - [[package]] name = "serde_yaml" version = "0.9.34+deprecated" @@ -5101,6 +4987,7 @@ dependencies = [ "signal-hook-registry", "socket2", "tokio-macros", + "tracing", "windows-sys 0.52.0", ] @@ -6028,6 +5915,7 @@ dependencies = [ "serde_repr", "sha1", "static_assertions", + "tokio", "tracing", "uds_windows", "windows-sys 0.52.0", diff --git a/Cargo.toml b/Cargo.toml index c6b6971..53122a9 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -47,7 +47,6 @@ uninlined_format_args = "warn" [dependencies] serde = { version = "1.0.217", features = ["derive"] } toml = "0.8.19" -serde_with = "3.12.0" gix = { version = "0.70.0", default-features = false, features = ["blocking-http-transport-reqwest-rust-tls", "revparse-regex", "credentials", "parallel"] } semver = { version = "1.0.24", features = ["serde"] } reqwest = { version = "0.12.12", default-features = false, features = ["rustls-tls", "stream", "json"] } @@ -63,7 +62,7 @@ async-stream = "0.3.6" futures = "0.3.31" full_moon = { version = "1.2.0", features = ["luau"] } url = { version = "2.5.4", features = ["serde"] } -chrono = { version = "0.4.39", features = ["serde"] } +jiff = { version = "0.1.28", default-features = false, features = ["serde", "std"] } sha2 = "0.10.8" tempfile = "3.15.0" wax = { version = "0.6.0", default-features = false } @@ -80,7 +79,7 @@ schemars = { git = "https://github.com/daimond113/schemars", rev = "bc7c7d6", fe anyhow = { version = "1.0.95", optional = true } open = { version = "5.3.2", optional = true } -keyring = { version = "3.6.1", features = ["crypto-rust", "windows-native", "apple-native", "async-secret-service", "async-io"], optional = true } +keyring = { version = "3.6.1", features = ["crypto-rust", "windows-native", "apple-native", "async-secret-service", "tokio"], optional = true } console = { version = "0.15.10", optional = true } toml_edit = { version = "0.22.22", optional = true } clap = { version = "4.5.26", features = ["derive"], optional = true } @@ -109,6 +108,7 @@ opt-level = "s" lto = true incremental = true codegen-units = 1 +panic = "abort" [profile.release.package.pesde-registry] # add debug symbols for Sentry stack traces diff --git a/registry/Cargo.toml b/registry/Cargo.toml index e17d8f0..32e5b1e 100644 --- a/registry/Cargo.toml +++ b/registry/Cargo.toml @@ -13,7 +13,7 @@ dotenvy = "0.15.7" thiserror = "2.0.11" tantivy = "0.22.0" semver = "1.0.24" -chrono = { version = "0.4.39", features = ["serde"] } +jiff = { version = "0.1.28", features = ["serde"] } futures = "0.3.31" tokio = "1.43.0" tokio-util = "0.7.13" diff --git a/registry/src/endpoints/publish_version.rs b/registry/src/endpoints/publish_version.rs index b9b31ae..8ccadc6 100644 --- a/registry/src/endpoints/publish_version.rs +++ b/registry/src/endpoints/publish_version.rs @@ -365,7 +365,7 @@ pub async fn publish_package( let new_entry = IndexFileEntry { target: manifest.target.clone(), - published_at: chrono::Utc::now(), + published_at: jiff::Timestamp::now(), engines: manifest.engines.clone(), description: manifest.description.clone(), license: manifest.license.clone(), diff --git a/registry/src/package.rs b/registry/src/package.rs index e848e29..0d0b509 100644 --- a/registry/src/package.rs +++ b/registry/src/package.rs @@ -1,5 +1,4 @@ use crate::AppState; -use chrono::{DateTime, Utc}; use pesde::{ manifest::{ target::{Target, TargetKind}, @@ -115,7 +114,7 @@ impl From for RegistryDocEntry { #[derive(Debug, Serialize)] pub struct PackageResponseInner { - published_at: DateTime, + published_at: jiff::Timestamp, #[serde(skip_serializing_if = "String::is_empty")] license: String, #[serde(skip_serializing_if = "Vec::is_empty")] diff --git a/registry/src/search.rs b/registry/src/search.rs index 4f69448..2a4d069 100644 --- a/registry/src/search.rs +++ b/registry/src/search.rs @@ -132,7 +132,7 @@ pub async fn make_search( scope => pkg_name.scope(), name => pkg_name.name(), description => latest_entry.description.clone().unwrap_or_default(), - published_at => DateTime::from_timestamp_secs(latest_entry.published_at.timestamp()), + published_at => DateTime::from_timestamp_nanos(latest_entry.published_at.as_nanosecond() as i64), )) .unwrap(); } @@ -159,7 +159,7 @@ pub fn update_search_version(app_state: &AppState, name: &PackageName, entry: &I schema.get_field("scope").unwrap() => name.scope(), schema.get_field("name").unwrap() => name.name(), schema.get_field("description").unwrap() => entry.description.clone().unwrap_or_default(), - schema.get_field("published_at").unwrap() => DateTime::from_timestamp_secs(entry.published_at.timestamp()) + schema.get_field("published_at").unwrap() => DateTime::from_timestamp_nanos(entry.published_at.as_nanosecond() as i64) )).unwrap(); search_writer.commit().unwrap(); diff --git a/src/cli/commands/patch.rs b/src/cli/commands/patch.rs index e75c9bc..cb9e6e7 100644 --- a/src/cli/commands/patch.rs +++ b/src/cli/commands/patch.rs @@ -50,7 +50,7 @@ impl PatchCommand { .join("patches") .join(id.name().escaped()) .join(id.version_id().escaped()) - .join(chrono::Utc::now().timestamp().to_string()); + .join(jiff::Timestamp::now().as_second().to_string()); fs::create_dir_all(&directory).await?; source diff --git a/src/cli/config.rs b/src/cli/config.rs index b5b3d07..c6f28cc 100644 --- a/src/cli/config.rs +++ b/src/cli/config.rs @@ -16,7 +16,7 @@ pub struct CliConfig { pub tokens: Tokens, #[serde(default, skip_serializing_if = "Option::is_none")] - pub last_checked_updates: Option<(chrono::DateTime, semver::Version)>, + pub last_checked_updates: Option<(jiff::Timestamp, semver::Version)>, } impl Default for CliConfig { diff --git a/src/cli/version.rs b/src/cli/version.rs index 1c5f1c4..9cfb93c 100644 --- a/src/cli/version.rs +++ b/src/cli/version.rs @@ -12,6 +12,7 @@ use crate::{ use anyhow::Context; use console::Style; use fs_err::tokio as fs; +use jiff::SignedDuration; use pesde::{ engine::{ source::{ @@ -36,7 +37,7 @@ pub fn current_version() -> Version { Version::parse(env!("CARGO_PKG_VERSION")).unwrap() } -const CHECK_INTERVAL: chrono::Duration = chrono::Duration::hours(6); +const CHECK_INTERVAL: SignedDuration = SignedDuration::from_hours(6); pub async fn find_latest_version(reqwest: &reqwest::Client) -> anyhow::Result { let version = EngineSources::pesde() @@ -61,7 +62,7 @@ pub async fn check_for_updates(reqwest: &reqwest::Client) -> anyhow::Result<()> let version = if let Some((_, version)) = config .last_checked_updates - .filter(|(time, _)| chrono::Utc::now() - *time < CHECK_INTERVAL) + .filter(|(time, _)| jiff::Timestamp::now().duration_since(*time) < CHECK_INTERVAL) { tracing::debug!("using cached version"); version @@ -70,7 +71,7 @@ pub async fn check_for_updates(reqwest: &reqwest::Client) -> anyhow::Result<()> let version = find_latest_version(reqwest).await?; write_config(&CliConfig { - last_checked_updates: Some((chrono::Utc::now(), version.clone())), + last_checked_updates: Some((jiff::Timestamp::now(), version.clone())), ..config }) .await?; diff --git a/src/engine/mod.rs b/src/engine/mod.rs index 3dd11e1..b984468 100644 --- a/src/engine/mod.rs +++ b/src/engine/mod.rs @@ -1,14 +1,11 @@ /// Sources of engines pub mod source; -use crate::engine::source::EngineSources; -use serde_with::{DeserializeFromStr, SerializeDisplay}; +use crate::{engine::source::EngineSources, ser_display_deser_fromstr}; use std::{fmt::Display, str::FromStr}; /// All supported engines -#[derive( - SerializeDisplay, DeserializeFromStr, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, -)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schema", schemars(rename_all = "snake_case"))] pub enum EngineKind { @@ -17,6 +14,7 @@ pub enum EngineKind { /// The Lune runtime Lune, } +ser_display_deser_fromstr!(EngineKind); impl Display for EngineKind { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/src/manifest/mod.rs b/src/manifest/mod.rs index 192f1d2..0ca3b1c 100644 --- a/src/manifest/mod.rs +++ b/src/manifest/mod.rs @@ -5,12 +5,12 @@ use crate::{ target::Target, }, names::PackageName, + ser_display_deser_fromstr, source::specifiers::DependencySpecifiers, }; use relative_path::RelativePathBuf; use semver::{Version, VersionReq}; use serde::{Deserialize, Serialize}; -use serde_with::{DeserializeFromStr, SerializeDisplay}; use std::{ collections::{BTreeMap, HashMap}, fmt::Display, @@ -118,10 +118,9 @@ pub struct Manifest { } /// An alias of a dependency -#[derive( - SerializeDisplay, DeserializeFromStr, Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, -)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct Alias(String); +ser_display_deser_fromstr!(Alias); impl Display for Alias { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { diff --git a/src/manifest/overrides.rs b/src/manifest/overrides.rs index 807f008..250c76d 100644 --- a/src/manifest/overrides.rs +++ b/src/manifest/overrides.rs @@ -1,16 +1,14 @@ -use crate::{manifest::Alias, source::specifiers::DependencySpecifiers}; +use crate::{manifest::Alias, ser_display_deser_fromstr, source::specifiers::DependencySpecifiers}; use serde::{Deserialize, Serialize}; -use serde_with::{DeserializeFromStr, SerializeDisplay}; use std::{ fmt::{Display, Formatter}, str::FromStr, }; /// An override key -#[derive( - Debug, DeserializeFromStr, SerializeDisplay, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, -)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct OverrideKey(pub Vec>); +ser_display_deser_fromstr!(OverrideKey); impl FromStr for OverrideKey { type Err = errors::OverrideKeyFromStr; diff --git a/src/manifest/target.rs b/src/manifest/target.rs index fa732c5..92bfde7 100644 --- a/src/manifest/target.rs +++ b/src/manifest/target.rs @@ -1,6 +1,6 @@ +use crate::ser_display_deser_fromstr; use relative_path::{RelativePath, RelativePathBuf}; use serde::{Deserialize, Serialize}; -use serde_with::{DeserializeFromStr, SerializeDisplay}; use std::{ collections::{BTreeMap, BTreeSet}, fmt::{Display, Formatter}, @@ -8,9 +8,7 @@ use std::{ }; /// A kind of target -#[derive( - SerializeDisplay, DeserializeFromStr, Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord, -)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, PartialOrd, Ord)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schema", schemars(rename_all = "snake_case"))] pub enum TargetKind { @@ -23,6 +21,7 @@ pub enum TargetKind { /// A Luau target Luau, } +ser_display_deser_fromstr!(TargetKind); impl Display for TargetKind { fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result { @@ -197,9 +196,7 @@ impl Display for Target { } /// The kind of a Roblox place property -#[derive( - SerializeDisplay, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd, -)] +#[derive(Serialize, Deserialize, Debug, Clone, Copy, PartialEq, Eq, Hash, Ord, PartialOrd)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[serde(rename_all = "snake_case")] pub enum RobloxPlaceKind { diff --git a/src/names.rs b/src/names.rs index cebdb00..41ae042 100644 --- a/src/names.rs +++ b/src/names.rs @@ -1,7 +1,6 @@ +use crate::ser_display_deser_fromstr; use std::{fmt::Display, str::FromStr}; -use serde_with::{DeserializeFromStr, SerializeDisplay}; - /// The invalid part of a package name #[derive(Debug)] pub enum ErrorReason { @@ -21,11 +20,11 @@ impl Display for ErrorReason { } /// A pesde package name -#[derive( - Debug, DeserializeFromStr, SerializeDisplay, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, -)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct PackageName(String, String); +ser_display_deser_fromstr!(PackageName); + impl FromStr for PackageName { type Err = errors::PackageNameError; @@ -110,9 +109,7 @@ impl PackageName { } /// All possible package names -#[derive( - Debug, DeserializeFromStr, SerializeDisplay, Clone, Hash, PartialEq, Eq, PartialOrd, Ord, -)] +#[derive(Debug, Clone, Hash, PartialEq, Eq, PartialOrd, Ord)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schema", schemars(untagged))] pub enum PackageNames { @@ -122,6 +119,7 @@ pub enum PackageNames { #[cfg(feature = "wally-compat")] Wally(wally::WallyPackageName), } +ser_display_deser_fromstr!(PackageNames); impl PackageNames { /// Returns the parts of the package name @@ -202,15 +200,15 @@ impl FromStr for PackageNames { pub mod wally { use std::{fmt::Display, str::FromStr}; - use serde_with::{DeserializeFromStr, SerializeDisplay}; - - use crate::names::{errors, ErrorReason}; + use crate::{ + names::{errors, ErrorReason}, + ser_display_deser_fromstr, + }; /// A Wally package name - #[derive( - Debug, DeserializeFromStr, SerializeDisplay, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, - )] + #[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct WallyPackageName(String, String); + ser_display_deser_fromstr!(WallyPackageName); impl FromStr for WallyPackageName { type Err = errors::WallyPackageNameError; diff --git a/src/source/ids.rs b/src/source/ids.rs index 0364bfb..dfeb16e 100644 --- a/src/source/ids.rs +++ b/src/source/ids.rs @@ -1,13 +1,11 @@ -use crate::{manifest::target::TargetKind, names::PackageNames}; +use crate::{manifest::target::TargetKind, names::PackageNames, ser_display_deser_fromstr}; use semver::Version; -use serde_with::{DeserializeFromStr, SerializeDisplay}; use std::{fmt::Display, str::FromStr}; /// A version ID, which is a combination of a version and a target -#[derive( - Debug, SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, -)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct VersionId(pub(crate) Version, pub(crate) TargetKind); +ser_display_deser_fromstr!(VersionId); impl VersionId { /// Creates a new version ID @@ -92,10 +90,9 @@ impl schemars::JsonSchema for VersionId { } /// A package ID, which is a combination of a name and a version ID -#[derive( - Debug, SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash, PartialOrd, Ord, -)] +#[derive(Debug, Clone, PartialEq, Eq, Hash, PartialOrd, Ord)] pub struct PackageId(pub(crate) PackageNames, pub(crate) VersionId); +ser_display_deser_fromstr!(PackageId); impl PackageId { /// Creates a new package ID diff --git a/src/source/workspace/specifier.rs b/src/source/workspace/specifier.rs index eda38a7..7f97152 100644 --- a/src/source/workspace/specifier.rs +++ b/src/source/workspace/specifier.rs @@ -1,6 +1,8 @@ -use crate::{manifest::target::TargetKind, names::PackageName, source::DependencySpecifier}; +use crate::{ + manifest::target::TargetKind, names::PackageName, ser_display_deser_fromstr, + source::DependencySpecifier, +}; use serde::{Deserialize, Serialize}; -use serde_with::{DeserializeFromStr, SerializeDisplay}; use std::{fmt::Display, str::FromStr}; /// The specifier for a workspace dependency @@ -25,9 +27,7 @@ impl Display for WorkspaceDependencySpecifier { } /// The type of version to use when publishing a package -#[derive( - Debug, SerializeDisplay, DeserializeFromStr, Clone, Copy, PartialEq, Eq, Hash, Default, -)] +#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash, Default)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] pub enum VersionType { /// The "^" version type @@ -44,6 +44,7 @@ pub enum VersionType { #[cfg_attr(feature = "schema", schemars(rename = "*"))] Wildcard, } +ser_display_deser_fromstr!(VersionType); impl Display for VersionType { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { @@ -73,7 +74,7 @@ impl FromStr for VersionType { } /// Either a version type or a version requirement -#[derive(Debug, SerializeDisplay, DeserializeFromStr, Clone, PartialEq, Eq, Hash)] +#[derive(Debug, Clone, PartialEq, Eq, Hash)] #[cfg_attr(feature = "schema", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schema", schemars(untagged))] pub enum VersionTypeOrReq { @@ -83,6 +84,7 @@ pub enum VersionTypeOrReq { #[cfg_attr(feature = "schema", schemars(with = "String"))] Req(semver::VersionReq), } +ser_display_deser_fromstr!(VersionTypeOrReq); impl Default for VersionTypeOrReq { fn default() -> Self { diff --git a/src/util.rs b/src/util.rs index 540a338..e7ad310 100644 --- a/src/util.rs +++ b/src/util.rs @@ -112,3 +112,28 @@ pub async fn remove_empty_dir(path: &Path) -> std::io::Result<()> { Err(e) => Err(e), } } + +/// Implement `Serialize` and `Deserialize` for a type that implements `Display` and `FromStr` +#[macro_export] +macro_rules! ser_display_deser_fromstr { + ($struct_name:ident) => { + impl serde::Serialize for $struct_name { + fn serialize(&self, serializer: S) -> Result + where + S: serde::ser::Serializer, + { + serializer.collect_str(self) + } + } + + impl<'de> serde::Deserialize<'de> for $struct_name { + fn deserialize(deserializer: D) -> Result + where + D: serde::de::Deserializer<'de>, + { + let s = String::deserialize(deserializer)?; + Self::from_str(&s).map_err(serde::de::Error::custom) + } + } + }; +}