diff --git a/Cargo.lock b/Cargo.lock index 69c2c6b8..bb5de26b 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -637,7 +637,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "0dc92fb57ca44df6db8059111ab3af99a63d5d0f8375d9972e319a379c6bab76" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "subtle", "zeroize", ] @@ -649,7 +649,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "1bfb12502f3fc46cca1bb51ac28df9d618d813cdc3d2f25b9fe775a34af26bb3" dependencies = [ "generic-array", - "rand_core", + "rand_core 0.6.4", "typenum", ] @@ -878,7 +878,7 @@ dependencies = [ "generic-array", "group", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sec1", "subtle", "zeroize", @@ -1006,7 +1006,7 @@ version = "0.13.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "ded41244b729663b1e574f1b4fb731469f69f79c17667b5d776b16cda0479449" dependencies = [ - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -1044,6 +1044,12 @@ dependencies = [ "serde", ] +[[package]] +name = "fnv" +version = "1.0.7" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "3f9eec918d3f24069decb9af1554cad7c880e2da24a9afd88aca000531ab82c1" + [[package]] name = "form_urlencoded" version = "1.2.1" @@ -1675,7 +1681,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f0f9ef7462f7c099f518d754361858f86d8a07af53ba9af0fe635bbccb151a63" dependencies = [ "ff", - "rand_core", + "rand_core 0.6.4", "subtle", ] @@ -2347,7 +2353,7 @@ dependencies = [ "num-integer", "num-iter", "num-traits", - "rand", + "rand 0.8.5", "smallvec", "zeroize", ] @@ -2493,7 +2499,7 @@ dependencies = [ "ecdsa", "elliptic-curve", "primeorder", - "rand_core", + "rand_core 0.6.4", "sha2", ] @@ -2724,13 +2730,32 @@ dependencies = [ "parking_lot", ] +[[package]] +name = "proptest" +version = "1.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "bee689443a2bd0a16ab0348b52ee43e3b2d1b1f931c8aa5c9f8de4c86fbe8c40" +dependencies = [ + "bit-set", + "bit-vec", + "bitflags 2.9.1", + "num-traits", + "rand 0.9.2", + "rand_chacha 0.9.0", + "rand_xorshift", + "regex-syntax 0.8.5", + "rusty-fork", + "tempfile", + "unarray", +] + [[package]] name = "qcheck" version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "b439bd4242da51d62d18c95e6a6add749346756b0d1a587dfd0cc22fa6b5f3f0" dependencies = [ - "rand", + "rand 0.8.5", ] [[package]] @@ -2744,6 +2769,12 @@ dependencies = [ "syn 1.0.109", ] +[[package]] +name = "quick-error" +version = "1.2.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "a1d01941d82fa2ab50be1e79e6714289dd7cde78eba4c074bc5a4374f650dfe0" + [[package]] name = "quick-xml" version = "0.38.1" @@ -2895,6 +2926,24 @@ dependencies = [ "thiserror 2.0.17", ] +[[package]] +name = "radicle-core" +version = "0.1.0" +dependencies = [ + "git2", + "gix-hash", + "multibase", + "proptest", + "qcheck", + "radicle-git-ref-format", + "radicle-oid", + "schemars", + "serde", + "serde_json", + "sqlite", + "thiserror 2.0.17", +] + [[package]] name = "radicle-crypto" version = "0.14.0" @@ -3158,8 +3207,18 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404" dependencies = [ "libc", - "rand_chacha", - "rand_core", + "rand_chacha 0.3.1", + "rand_core 0.6.4", +] + +[[package]] +name = "rand" +version = "0.9.2" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6db2770f06117d490610c7488547d543617b21bfa07796d7a12f6f1bd53850d1" +dependencies = [ + "rand_chacha 0.9.0", + "rand_core 0.9.3", ] [[package]] @@ -3169,7 +3228,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88" dependencies = [ "ppv-lite86", - "rand_core", + "rand_core 0.6.4", +] + +[[package]] +name = "rand_chacha" +version = "0.9.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb" +dependencies = [ + "ppv-lite86", + "rand_core 0.9.3", ] [[package]] @@ -3181,6 +3250,24 @@ dependencies = [ "getrandom 0.2.15", ] +[[package]] +name = "rand_core" +version = "0.9.3" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38" +dependencies = [ + "getrandom 0.3.3", +] + +[[package]] +name = "rand_xorshift" +version = "0.4.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "513962919efc330f829edb2535844d1b912b0fbe2ca165d613e4e8788bb05a5a" +dependencies = [ + "rand_core 0.9.3", +] + [[package]] name = "redox_syscall" version = "0.4.1" @@ -3300,7 +3387,7 @@ dependencies = [ "num-traits", "pkcs1", "pkcs8", - "rand_core", + "rand_core 0.6.4", "sha2", "signature 2.2.0", "spki", @@ -3346,6 +3433,18 @@ version = "1.0.20" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "eded382c5f5f786b989652c49544c4877d9f015cc22e145a5ea8ea66c2921cd2" +[[package]] +name = "rusty-fork" +version = "0.3.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "cc6bf79ff24e648f6da1f8d1f011e9cac26491b619e6b9280f2b47f1774e6ee2" +dependencies = [ + "fnv", + "quick-error", + "tempfile", + "wait-timeout", +] + [[package]] name = "ryu" version = "1.0.17" @@ -3630,7 +3729,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "77549399552de45a898a580c1b41d445bf730df867cc44e6c0233bbc4b8329de" dependencies = [ "digest", - "rand_core", + "rand_core 0.6.4", ] [[package]] @@ -3789,7 +3888,7 @@ dependencies = [ "p256", "p384", "p521", - "rand_core", + "rand_core 0.6.4", "rsa", "sec1", "sha2", @@ -4376,6 +4475,12 @@ version = "1.17.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "42ff0bf0c66b8238c6f3b578df37d0b7848e55df8577b3f74f92a69acceeb825" +[[package]] +name = "unarray" +version = "0.1.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "eaea85b334db583fe3274d12b4cd1880032beab409c0d774be044d4480ab9a94" + [[package]] name = "unicode-display-width" version = "0.3.0" @@ -4543,6 +4648,15 @@ version = "0.8.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "5c3082ca00d5a5ef149bb8b555a72ae84c9c59f7250f013ac822ac2e49b19c64" +[[package]] +name = "wait-timeout" +version = "0.2.1" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "09ac3b126d3914f9849036f826e054cbabdc8519970b8998ddaf3b5bd3c65f11" +dependencies = [ + "libc", +] + [[package]] name = "walkdir" version = "2.5.0" @@ -4984,7 +5098,7 @@ checksum = "1ccf671d62d1bd0c913d9059e69bb4a6b51f7a4c899ab83c62d921e35f206053" dependencies = [ "defer-heavy", "log", - "rand", + "rand 0.8.5", "sync-ptr", "windows", ] diff --git a/Cargo.toml b/Cargo.toml index 21e0514c..e456fb30 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -38,6 +38,7 @@ log = "0.4.17" multibase = "0.9.1" nonempty = "0.9.0" pretty_assertions = "1.3.0" +proptest = "1.9" qcheck = { version = "1", default-features = false } qcheck-macros = { version = "1", default-features = false } radicle = { version = "0.20", path = "crates/radicle" } @@ -65,7 +66,7 @@ signature = "2.2" snapbox = "0.4.3" sqlite = "0.32.0" tempfile = "3.3.0" -thiserror = "2" +thiserror = { version = "2", default-features = false } winpipe = "0.1.1" zeroize = "1.5.7" diff --git a/crates/radicle-cli-test/Cargo.toml b/crates/radicle-cli-test/Cargo.toml index 0dc9e9eb..60c15811 100644 --- a/crates/radicle-cli-test/Cargo.toml +++ b/crates/radicle-cli-test/Cargo.toml @@ -18,4 +18,4 @@ pretty_assertions = { workspace = true } radicle = { workspace = true, features = ["logger", "test"]} shlex = { workspace = true } snapbox = { workspace = true } -thiserror = { workspace = true } \ No newline at end of file +thiserror = { workspace = true, default-features = true } \ No newline at end of file diff --git a/crates/radicle-cli/Cargo.toml b/crates/radicle-cli/Cargo.toml index 402afdfc..e147155d 100644 --- a/crates/radicle-cli/Cargo.toml +++ b/crates/radicle-cli/Cargo.toml @@ -35,7 +35,7 @@ serde = { workspace = true } serde_json = { workspace = true } shlex = { workspace = true } tempfile = { workspace = true } -thiserror = { workspace = true } +thiserror = { workspace = true, default-features = true } timeago = { version = "0.4.2", default-features = false } tree-sitter = "0.24.4" tree-sitter-bash = "0.23.3" diff --git a/crates/radicle-cob/Cargo.toml b/crates/radicle-cob/Cargo.toml index 59c216e5..029a41fc 100644 --- a/crates/radicle-cob/Cargo.toml +++ b/crates/radicle-cob/Cargo.toml @@ -32,7 +32,7 @@ radicle-oid = { workspace = true, features = ["git2", "serde", "std"] } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true } signature = { workspace = true } -thiserror = { workspace = true } +thiserror = { workspace = true, default-features = true } [dev-dependencies] fastrand = { workspace = true } diff --git a/crates/radicle-core/Cargo.toml b/crates/radicle-core/Cargo.toml new file mode 100644 index 00000000..63d20755 --- /dev/null +++ b/crates/radicle-core/Cargo.toml @@ -0,0 +1,37 @@ +[package] +name = "radicle-core" +description = "Radicle core data type definitions" +homepage.workspace = true +repository.workspace = true +version = "0.1.0" +edition.workspace = true +license.workspace = true +keywords = ["radicle", "git", "data types"] +rust-version.workspace = true + +# For documentation of features refer to the module documentation in `./lib.rs` +[features] +default = ["std"] +git2 = ["dep:git2", "radicle-oid/git2"] +gix = ["dep:gix-hash", "radicle-oid/gix"] +std = ["radicle-oid/std", "thiserror/std", "schemars/std", "serde/std"] + +[dependencies] +git2 = { workspace = true, optional = true } +gix-hash = { workspace = true, optional = true } +multibase = { workspace = true } +proptest = { workspace = true, optional = true } +qcheck = { workspace = true, optional = true } +radicle-git-ref-format = { workspace = true, optional = true } +radicle-oid = { workspace = true, default-features = false, features = ["sha1"] } +schemars = { workspace = true, optional = true, default-features = false, features = ["derive"] } +serde = { workspace = true, optional = true, default-features = false } +sqlite = { workspace = true, optional = true } +thiserror = { workspace = true, default-features = false } + +[dev-dependencies] +proptest = { workspace = true } +serde_json = { workspace = true } + +[lints] +workspace = true diff --git a/crates/radicle-core/src/lib.rs b/crates/radicle-core/src/lib.rs new file mode 100644 index 00000000..3fe21ac8 --- /dev/null +++ b/crates/radicle-core/src/lib.rs @@ -0,0 +1,75 @@ +#![no_std] + +//! This a crate for defining core data type for the Radicle protocol, such as +//! [`RepoId`]. +//! +//! # Feature Flags +//! +//! The only default feature is `std`. +//! +//! ## `std` +//! +//! [`OsString`]: ::doc_std::ffi::OsString +//! +//! Provides implementation of [`TryFrom`]. +//! +//! Enabled by default, since it is expected that most dependents will use the +//! standard library. +//! +//! ## `git2` +//! +//! [`git2::Oid`]: ::git2::Oid +//! +//! Provides conversion from a [`git2::Oid`] to a [`RepoId`]. +//! +//! ## `gix` +//! +//! [`ObjectId`]: ::gix_hash::ObjectId +//! +//! Provides conversion from a [`ObjectId`] to a [`RepoId`]. +//! +//! ## `radicle-git-ref-format` +//! +//! Provides conversions from data types defined in `radicle-core` into valid +//! reference components and/or strings. +//! +//! ## `serde` +//! +//! [`Serialize`]: ::serde::ser::Serialize +//! [`Deserialize`]: ::serde::de::Deserialize +//! +//! Provides implementations of [`Serialize`] and [`Deserialize`]. +//! +//! ## `schemars` +//! +//! [`JsonSchema`]: ::schemars::JsonSchema +//! +//! Provides implementations of [`JsonSchema`]. +//! +//! ## `proptest` +//! +//! [`proptest::Strategy`]: ::proptest::strategy::Strategy +//! +//! Provides functions for generating different types of [`proptest::Strategy`]. +//! +//! ## `qcheck` +//! +//! [`qcheck::Arbitrary`]: ::qcheck::Arbitrary +//! +//! Provides implementations of [`qcheck::Arbitrary`]. +//! +//! ## `sqlite` +//! +//! [`sqlite::BindableWithIndex`]: ::sqlite::BindableWithIndex +//! [`sqlite::Value`]: ::sqlite::Value +//! +//! Provides implementations of [`sqlite::BindableWithIndex`] and `TryFrom` +//! implementations from the [`sqlite::Value`] type to the domain type. + +#[cfg(doc)] +extern crate std as doc_std; + +extern crate alloc; + +pub mod repo; +pub use repo::RepoId; diff --git a/crates/radicle-core/src/repo.rs b/crates/radicle-core/src/repo.rs new file mode 100644 index 00000000..82a637b6 --- /dev/null +++ b/crates/radicle-core/src/repo.rs @@ -0,0 +1,294 @@ +use alloc::string::String; +use alloc::string::ToString as _; +use alloc::vec::Vec; + +use radicle_oid::Oid; +use thiserror::Error; + +/// Radicle identifier prefix. +pub const RAD_PREFIX: &str = "rad:"; + +#[derive(Error, Debug)] +pub enum IdError { + #[error(transparent)] + Multibase(#[from] multibase::Error), + #[error("invalid length: expected {expected} bytes, got {actual} bytes")] + Length { expected: usize, actual: usize }, +} + +/// A repository identifier. +#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord)] +#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] +pub struct RepoId( + #[cfg_attr(feature = "schemars", schemars( + with = "String", + description = "A repository identifier. Starts with \"rad:\", followed by a multibase Base58 encoded Git object identifier.", + regex(pattern = r"rad:z[1-9a-km-zA-HJ-NP-Z]+"), + length(min = 5), + example = &"rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5", + ))] + Oid, +); + +impl core::fmt::Display for RepoId { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + f.write_str(self.urn().as_str()) + } +} + +impl core::fmt::Debug for RepoId { + fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result { + write!(f, "RepoId({self})") + } +} + +impl RepoId { + /// Format the identifier as a human-readable URN. + /// + /// Eg. `rad:z3XncAdkZjeK9mQS5Sdc4qhw98BUX`. + /// + pub fn urn(&self) -> String { + RAD_PREFIX.to_string() + &self.canonical() + } + + /// Parse an identifier from the human-readable URN format. + /// Accepts strings without the radicle prefix as well, + /// for convenience. + pub fn from_urn(s: &str) -> Result { + let s = s.strip_prefix(RAD_PREFIX).unwrap_or(s); + let id = Self::from_canonical(s)?; + + Ok(id) + } + + /// Format the identifier as a multibase string. + /// + /// Eg. `z3XncAdkZjeK9mQS5Sdc4qhw98BUX`. + /// + pub fn canonical(&self) -> String { + multibase::encode(multibase::Base::Base58Btc, AsRef::<[u8]>::as_ref(&self.0)) + } + + pub fn from_canonical(input: &str) -> Result { + const EXPECTED_LEN: usize = 20; + let (_, bytes) = multibase::decode(input)?; + let bytes: [u8; EXPECTED_LEN] = + bytes.try_into().map_err(|bytes: Vec| IdError::Length { + expected: EXPECTED_LEN, + actual: bytes.len(), + })?; + Ok(Self(Oid::from_sha1(bytes))) + } +} + +impl core::str::FromStr for RepoId { + type Err = IdError; + + fn from_str(s: &str) -> Result { + Self::from_urn(s) + } +} + +#[cfg(feature = "std")] +mod std_impls { + extern crate std; + + use super::{IdError, RepoId}; + + use std::ffi::OsString; + + impl TryFrom for RepoId { + type Error = IdError; + + fn try_from(value: OsString) -> Result { + let string = value.to_string_lossy(); + Self::from_canonical(&string) + } + } + + impl std::hash::Hash for RepoId { + fn hash(&self, state: &mut H) { + self.0.hash(state) + } + } +} + +impl From for RepoId { + fn from(oid: Oid) -> Self { + Self(oid) + } +} + +impl core::ops::Deref for RepoId { + type Target = Oid; + + fn deref(&self) -> &Self::Target { + &self.0 + } +} + +#[cfg(feature = "git2")] +mod git2_impls { + use super::RepoId; + + impl From for RepoId { + fn from(oid: git2::Oid) -> Self { + Self(oid.into()) + } + } +} + +#[cfg(feature = "gix")] +mod gix_impls { + use super::RepoId; + + impl From for RepoId { + fn from(oid: gix_hash::ObjectId) -> Self { + Self(oid.into()) + } + } +} + +#[cfg(feature = "radicle-git-ref-format")] +mod radicle_git_ref_format_impls { + use alloc::string::ToString; + + use radicle_git_ref_format::{Component, RefString}; + + use super::RepoId; + + impl From<&RepoId> for Component<'_> { + fn from(id: &RepoId) -> Self { + let refstr = RefString::try_from(id.0.to_string()) + .expect("repository id's are valid ref strings"); + Component::from_refstr(refstr).expect("repository id's are valid refname components") + } + } +} + +#[cfg(feature = "serde")] +mod serde_impls { + use alloc::string::String; + + use serde::{de, Deserialize, Deserializer, Serialize}; + + use super::RepoId; + + impl Serialize for RepoId { + fn serialize(&self, serializer: S) -> Result + where + S: serde::Serializer, + { + serializer.collect_str(&self.urn()) + } + } + + impl<'de> Deserialize<'de> for RepoId { + fn deserialize(deserializer: D) -> Result + where + D: Deserializer<'de>, + { + String::deserialize(deserializer)? + .parse() + .map_err(de::Error::custom) + } + } + + #[cfg(test)] + mod test { + use proptest::proptest; + + use super::super::*; + + fn prop_roundtrip_serde_json(rid: RepoId) { + let encoded = serde_json::to_string(&rid).unwrap(); + let decoded = serde_json::from_str(&encoded).unwrap(); + + assert_eq!(rid, decoded); + } + + proptest! { + #[test] + fn assert_prop_roundtrip_serde_json(rid in arbitrary::rid()) { + prop_roundtrip_serde_json(rid) + } + } + } +} + +#[cfg(feature = "sqlite")] +mod sqlite_impls { + use alloc::format; + use alloc::string::ToString; + + use super::RepoId; + + use sqlite::{BindableWithIndex, Error, ParameterIndex, Statement, Value}; + + impl TryFrom<&Value> for RepoId { + type Error = Error; + + fn try_from(value: &Value) -> Result { + match value { + Value::String(id) => RepoId::from_urn(id).map_err(|e| Error { + code: None, + message: Some(e.to_string()), + }), + _ => Err(Error { + code: None, + message: Some(format!("sql: invalid type `{:?}` for id", value.kind())), + }), + } + } + } + + impl BindableWithIndex for &RepoId { + fn bind(self, stmt: &mut Statement<'_>, i: I) -> sqlite::Result<()> { + self.urn().as_str().bind(stmt, i) + } + } +} + +#[cfg(any(test, feature = "proptest"))] +pub mod arbitrary { + use proptest::prelude::Strategy; + + use super::RepoId; + + pub fn rid() -> impl Strategy { + proptest::array::uniform20(proptest::num::u8::ANY) + .prop_map(|bytes| RepoId::from(radicle_oid::Oid::from_sha1(bytes))) + } +} + +#[cfg(feature = "qcheck")] +impl qcheck::Arbitrary for RepoId { + fn arbitrary(g: &mut qcheck::Gen) -> Self { + let bytes = <[u8; 20]>::arbitrary(g); + let oid = radicle_oid::Oid::from_sha1(bytes); + + RepoId::from(oid) + } +} + +#[cfg(test)] +#[allow(clippy::unwrap_used)] +mod test { + use super::*; + use proptest::proptest; + + fn prop_roundtrip_parse(rid: RepoId) { + use core::str::FromStr as _; + let encoded = rid.to_string(); + let decoded = RepoId::from_str(&encoded).unwrap(); + + assert_eq!(rid, decoded); + } + + proptest! { + #[test] + fn assert_prop_roundtrip_parse(rid in arbitrary::rid()) { + prop_roundtrip_parse(rid) + } + } +} diff --git a/crates/radicle-crypto/Cargo.toml b/crates/radicle-crypto/Cargo.toml index 2315128f..58f945e0 100644 --- a/crates/radicle-crypto/Cargo.toml +++ b/crates/radicle-crypto/Cargo.toml @@ -29,7 +29,7 @@ serde = { workspace = true, features = ["derive", "std"] } signature = { workspace = true } sqlite = { workspace = true, features = ["bundled"], optional = true } ssh-key = { version = "0.6.3", default-features = false, features = ["std", "encryption", "getrandom"], optional = true } -thiserror = { workspace = true } +thiserror = { workspace = true, default-features = true } zeroize = { workspace = true } [dev-dependencies] diff --git a/crates/radicle-fetch/Cargo.toml b/crates/radicle-fetch/Cargo.toml index e6aa11e9..f4dfa136 100644 --- a/crates/radicle-fetch/Cargo.toml +++ b/crates/radicle-fetch/Cargo.toml @@ -22,4 +22,4 @@ nonempty = { workspace = true } radicle = { workspace = true } radicle-oid = { workspace = true, features = ["gix"] } radicle-git-ref-format = { workspace = true, features = ["bstr"] } -thiserror = { workspace = true } \ No newline at end of file +thiserror = { workspace = true, default-features = true } \ No newline at end of file diff --git a/crates/radicle-git-metadata/Cargo.toml b/crates/radicle-git-metadata/Cargo.toml index ab58b3f0..86b175ac 100644 --- a/crates/radicle-git-metadata/Cargo.toml +++ b/crates/radicle-git-metadata/Cargo.toml @@ -10,4 +10,4 @@ keywords = ["radicle", "git", "metadata"] rust-version.workspace = true [dependencies] -thiserror = { workspace = true } \ No newline at end of file +thiserror = { workspace = true, default-features = true } \ No newline at end of file diff --git a/crates/radicle-node/Cargo.toml b/crates/radicle-node/Cargo.toml index a9b6aa94..1ff3e213 100644 --- a/crates/radicle-node/Cargo.toml +++ b/crates/radicle-node/Cargo.toml @@ -41,7 +41,7 @@ snapbox = { workspace = true, optional = true } socket2 = { version = "0.5.7", features = ["all"], optional = true } structured-logger = { version = "1.0.4", optional = true } tempfile = { workspace = true } -thiserror = { workspace = true } +thiserror = { workspace = true, default-features = true } [target.'cfg(target_os = "linux")'.dependencies] radicle-systemd = { workspace = true, optional = true } diff --git a/crates/radicle-protocol/Cargo.toml b/crates/radicle-protocol/Cargo.toml index 2d085895..40cc183c 100644 --- a/crates/radicle-protocol/Cargo.toml +++ b/crates/radicle-protocol/Cargo.toml @@ -27,7 +27,7 @@ sqlite = { workspace = true, features = ["bundled"] } scrypt = { version = "0.11.0", default-features = false } serde = { workspace = true, features = ["derive"] } serde_json = { workspace = true, features = ["preserve_order"] } -thiserror = { workspace = true } +thiserror = { workspace = true, default-features = true } [dev-dependencies] paste = "1.0.15" diff --git a/crates/radicle-remote-helper/Cargo.toml b/crates/radicle-remote-helper/Cargo.toml index 41895685..411c005f 100644 --- a/crates/radicle-remote-helper/Cargo.toml +++ b/crates/radicle-remote-helper/Cargo.toml @@ -19,4 +19,4 @@ log = { workspace = true } radicle = { workspace = true } radicle-cli = { workspace = true } radicle-crypto = { workspace = true } -thiserror = { workspace = true } \ No newline at end of file +thiserror = { workspace = true, default-features = true } \ No newline at end of file diff --git a/crates/radicle-ssh/Cargo.toml b/crates/radicle-ssh/Cargo.toml index 392de1b7..17c32abd 100644 --- a/crates/radicle-ssh/Cargo.toml +++ b/crates/radicle-ssh/Cargo.toml @@ -14,7 +14,7 @@ edition.workspace = true rust-version.workspace = true [dependencies] -thiserror = { workspace = true } +thiserror = { workspace = true, default-features = true } zeroize = { workspace = true } [target.'cfg(windows)'.dependencies] diff --git a/crates/radicle-term/Cargo.toml b/crates/radicle-term/Cargo.toml index 512e4358..a128c0bb 100644 --- a/crates/radicle-term/Cargo.toml +++ b/crates/radicle-term/Cargo.toml @@ -20,7 +20,7 @@ inquire = { version = "0.7.4", default-features = false, features = [ "crossterm", "editor", ] } -thiserror = { workspace = true } +thiserror = { workspace = true, default-features = true } unicode-display-width = "0.3.0" unicode-segmentation = "1.7.1" zeroize = { workspace = true } diff --git a/crates/radicle/Cargo.toml b/crates/radicle/Cargo.toml index 75eeb03f..1a41d54a 100644 --- a/crates/radicle/Cargo.toml +++ b/crates/radicle/Cargo.toml @@ -45,7 +45,7 @@ serde-untagged = "0.1.7" siphasher = "1.0.0" sqlite = { workspace = true, features = ["bundled"] } tempfile = { workspace = true, optional = true } -thiserror = { workspace = true } +thiserror = { workspace = true, default-features = true } unicode-normalization = { version = "0.1" } [target.'cfg(unix)'.dependencies]