crypto: Optionally provide JSON Schema

Providing the schema in `radicle-crypto` saves a lot of repetition
in `radicle`, and can be done via an optional dependency.
This commit is contained in:
Lorenz Leutgeb 2025-10-09 23:52:30 +02:00 committed by Fintan Halpenny
parent 82ad52b169
commit faeee9f370
9 changed files with 21 additions and 80 deletions

1
Cargo.lock generated
View File

@ -2959,6 +2959,7 @@ dependencies = [
"qcheck", "qcheck",
"qcheck-macros", "qcheck-macros",
"radicle-ssh", "radicle-ssh",
"schemars",
"serde", "serde",
"signature 2.2.0", "signature 2.2.0",
"sqlite", "sqlite",

View File

@ -25,6 +25,7 @@ multibase = { workspace = true }
qcheck = { workspace = true, optional = true } qcheck = { workspace = true, optional = true }
git-ref-format-core = { workspace = true, optional = true } git-ref-format-core = { workspace = true, optional = true }
radicle-ssh = { workspace = true, optional = true } radicle-ssh = { workspace = true, optional = true }
schemars = { workspace = true, optional = true, features = ["derive", "std"] }
serde = { workspace = true, features = ["derive", "std"] } serde = { workspace = true, features = ["derive", "std"] }
signature = { workspace = true } signature = { workspace = true }
sqlite = { workspace = true, features = ["bundled"], optional = true } sqlite = { workspace = true, features = ["bundled"], optional = true }

View File

@ -158,6 +158,20 @@ impl TryFrom<String> for Signature {
/// The public/verification key. /// The public/verification key.
#[derive(Hash, Serialize, Deserialize, PartialEq, Eq, Copy, Clone)] #[derive(Hash, Serialize, Deserialize, PartialEq, Eq, Copy, Clone)]
#[serde(into = "String", try_from = "String")] #[serde(into = "String", try_from = "String")]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
#[cfg_attr(
feature = "schemars",
schemars(
title = "Ed25519",
description = "An Ed25519 public key in multibase encoding.",
extend("examples" = [
"z6MkrLMMsiPWUcNPHcRajuMi9mDfYckSoJyPwwnknocNYPm7",
"z6MkvUJtYD9dHDJfpevWRT98mzDDpdAtmUjwyDSkyqksUr7C",
"z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
"z6MkkfM3tPXNPrPevKr3uSiQtHPuwnNhu2yUVjgd2jXVsVz5",
]),
),
)]
pub struct PublicKey(pub ed25519::PublicKey); pub struct PublicKey(pub ed25519::PublicKey);
#[cfg(feature = "cyphernet")] #[cfg(feature = "cyphernet")]

View File

@ -83,10 +83,7 @@ fn print_schema() -> io::Result<()> {
#[schemars(untagged)] #[schemars(untagged)]
#[allow(dead_code)] #[allow(dead_code)]
enum CommandResult { enum CommandResult {
Nid( Nid(radicle::node::NodeId),
#[schemars(with = "radicle::schemars_ext::crypto::PublicKey")]
radicle::node::NodeId,
),
Config(Box<radicle::node::Config>), Config(Box<radicle::node::Config>),
ListenAddrs(ListenAddrs), ListenAddrs(ListenAddrs),
ConnectResult(radicle::node::ConnectResult), ConnectResult(radicle::node::ConnectResult),

View File

@ -20,6 +20,7 @@ qcheck = [
schemars = [ schemars = [
"radicle-oid/schemars", "radicle-oid/schemars",
"radicle-core/schemars", "radicle-core/schemars",
"radicle-crypto/schemars",
"radicle-localtime/schemars", "radicle-localtime/schemars",
"dep:schemars" "dep:schemars"
] ]

View File

@ -553,10 +553,6 @@ impl std::fmt::Display for Link {
#[derive(Debug, Clone, Serialize, Deserialize)] #[derive(Debug, Clone, Serialize, Deserialize)]
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Session { pub struct Session {
#[cfg_attr(
feature = "schemars",
schemars(with = "crate::schemars_ext::crypto::PublicKey")
)]
pub nid: NodeId, pub nid: NodeId,
pub link: Link, pub link: Link,
pub addr: Address, pub addr: Address,
@ -576,10 +572,6 @@ impl Session {
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct Seed { pub struct Seed {
/// The Node ID. /// The Node ID.
#[cfg_attr(
feature = "schemars",
schemars(with = "crate::schemars_ext::crypto::PublicKey")
)]
pub nid: NodeId, pub nid: NodeId,
/// Known addresses for this seed. /// Known addresses for this seed.
pub addrs: Vec<KnownAddress>, pub addrs: Vec<KnownAddress>,
@ -700,10 +692,6 @@ impl From<Vec<Seed>> for Seeds {
pub enum FetchResult { pub enum FetchResult {
Success { Success {
updated: Vec<RefUpdate>, updated: Vec<RefUpdate>,
#[cfg_attr(
feature = "schemars",
schemars(with = "HashSet<crate::schemars_ext::crypto::PublicKey>")
)]
namespaces: HashSet<NodeId>, namespaces: HashSet<NodeId>,
clone: bool, clone: bool,
}, },

View File

@ -40,10 +40,6 @@ pub enum Command {
rid: RepoId, rid: RepoId,
/// The namespaces for which references should be announced. /// The namespaces for which references should be announced.
#[cfg_attr(
feature = "schemars",
schemars(with = "HashSet<crate::schemars_ext::crypto::PublicKey>")
)]
namespaces: HashSet<PublicKey>, namespaces: HashSet<PublicKey>,
}, },
@ -69,13 +65,7 @@ pub enum Command {
/// Disconnect from a node. /// Disconnect from a node.
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
Disconnect { Disconnect { nid: NodeId },
#[cfg_attr(
feature = "schemars",
schemars(with = "crate::schemars_ext::crypto::PublicKey")
)]
nid: NodeId,
},
/// Look up seeds for the given repository in the routing table. /// Look up seeds for the given repository in the routing table.
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
@ -91,10 +81,6 @@ pub enum Command {
rid: RepoId, rid: RepoId,
/// The namespaces for which references should be announced. /// The namespaces for which references should be announced.
#[cfg_attr(
feature = "schemars",
schemars(with = "HashSet<crate::schemars_ext::crypto::PublicKey>")
)]
namespaces: HashSet<PublicKey>, namespaces: HashSet<PublicKey>,
}, },
@ -102,22 +88,12 @@ pub enum Command {
Sessions, Sessions,
/// Get a specific peer session. /// Get a specific peer session.
Session { Session { nid: NodeId },
#[cfg_attr(
feature = "schemars",
schemars(with = "crate::schemars_ext::crypto::PublicKey")
)]
nid: NodeId,
},
/// Fetch the given repository from the network. /// Fetch the given repository from the network.
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
Fetch { Fetch {
rid: RepoId, rid: RepoId,
#[cfg_attr(
feature = "schemars",
schemars(with = "crate::schemars_ext::crypto::PublicKey")
)]
nid: NodeId, nid: NodeId,
timeout: time::Duration, timeout: time::Duration,
}, },
@ -136,23 +112,13 @@ pub enum Command {
/// Follow the given node. /// Follow the given node.
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
Follow { Follow {
#[cfg_attr(
feature = "schemars",
schemars(with = "crate::schemars_ext::crypto::PublicKey")
)]
nid: NodeId, nid: NodeId,
alias: Option<super::Alias>, alias: Option<super::Alias>,
}, },
/// Unfollow the given node. /// Unfollow the given node.
#[serde(rename_all = "camelCase")] #[serde(rename_all = "camelCase")]
Unfollow { Unfollow { nid: NodeId },
#[cfg_attr(
feature = "schemars",
schemars(with = "crate::schemars_ext::crypto::PublicKey")
)]
nid: NodeId,
},
/// Get the node's status. /// Get the node's status.
Status, Status,

View File

@ -4,29 +4,6 @@
use schemars::JsonSchema; use schemars::JsonSchema;
pub mod crypto {
use super::*;
/// See [`crate::node::NodeId`]
/// See [`crate::storage::RemoteId`]
/// See [`::crypto::PublicKey`]
///
/// An Ed25519 public key in multibase encoding.
///
/// `MULTIBASE(base58-btc, MULTICODEC(public-key-type, raw-public-key-bytes))`
#[derive(JsonSchema)]
#[schemars(
title = "NodeId",
description = "An Ed25519 public key in multibase encoding.",
extend("examples" = [
"z6MkrLMMsiPWUcNPHcRajuMi9mDfYckSoJyPwwnknocNYPm7",
"z6MkvUJtYD9dHDJfpevWRT98mzDDpdAtmUjwyDSkyqksUr7C",
"z6MknSLrJoTcukLrE435hVNQT4JUhbvWLX4kUzqkEStBU8Vi",
"z6MkkfM3tPXNPrPevKr3uSiQtHPuwnNhu2yUVjgd2jXVsVz5",
]),
)]
pub struct PublicKey(String);
}
pub(crate) mod log { pub(crate) mod log {
use super::*; use super::*;

View File

@ -376,10 +376,6 @@ impl<V> Deref for SignedRefs<V> {
#[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))] #[cfg_attr(feature = "schemars", derive(schemars::JsonSchema))]
pub struct RefsAt { pub struct RefsAt {
/// The remote namespace of the `rad/sigrefs`. /// The remote namespace of the `rad/sigrefs`.
#[cfg_attr(
feature = "schemars",
schemars(with = "crate::schemars_ext::crypto::PublicKey")
)]
pub remote: RemoteId, pub remote: RemoteId,
/// The commit SHA that `rad/sigrefs` points to. /// The commit SHA that `rad/sigrefs` points to.
pub at: Oid, pub at: Oid,