Radish alpha
h
Radicle Heartwood Protocol & Stack
Radicle
Git (anonymous pull)
Log in to clone via SSH
radicle-schemars: Add crate for utility binary
Lorenz Leutgeb committed 11 months ago
commit 4cd0782f2e442c76cc433c292cdfda5523d70bf6
parent fcd1acd1dd927d9df372a8dc47332d0ffdb16820
4 files changed +144 -0
modified Cargo.lock
@@ -2822,6 +2822,17 @@ dependencies = [
]

[[package]]
+
name = "radicle-schemars"
+
version = "0.1.0"
+
dependencies = [
+
 "once_cell",
+
 "radicle",
+
 "schemars",
+
 "serde",
+
 "serde_json",
+
]
+

+
[[package]]
name = "radicle-signals"
version = "0.11.0"
dependencies = [
modified Cargo.toml
@@ -12,6 +12,7 @@ members = [
  "radicle-remote-helper",
  "radicle-ssh",
  "radicle-tools",
+
  "radicle-schemars",
  "radicle-signals",
  "radicle-systemd",
]
added radicle-schemars/Cargo.toml
@@ -0,0 +1,24 @@
+
[package]
+
name = "radicle-schemars"
+
description = "Utility to print JSON Schemas from the `radicle` crate"
+
homepage = "https://radicle.xyz"
+
repository = "https://app.radicle.xyz/seeds/seed.radicle.xyz/rad:z3gqcJUoA1n9HaHKufZs5FCSGazv5"
+
license = "MIT OR Apache-2.0"
+
edition = "2021"
+
version = "0.1.0"
+
rust-version.workspace = true
+

+
[[bin]]
+
name = "radicle-schemars"
+
path = "src/main.rs"
+

+
[dependencies]
+
once_cell = { version = "1.13" }
+
schemars = { workspace = true }
+
serde = { version = "1.0" }
+
serde_json = { version = "1" }
+

+
[dependencies.radicle]
+
version = "0"
+
path = "../radicle"
+
features = ["schemars"]

\ No newline at end of file
added radicle-schemars/src/main.rs
@@ -0,0 +1,108 @@
+
use std::io;
+
use std::net;
+

+
use once_cell::sync::Lazy;
+
use schemars::{generate::*, *};
+

+
const SCHEMA_COMMAND: &str = "radicle::node::Command";
+
const SCHEMA_COMMAND_RESULT: &str = "radicle::node::CommandResult";
+
const SCHEMA_PROFILE_CONFIG: &str = "radicle::profile::Config";
+

+
const SCHEMAS: &[&str] = &[SCHEMA_COMMAND, SCHEMA_COMMAND_RESULT, SCHEMA_PROFILE_CONFIG];
+

+
pub static ERROR_MSG: Lazy<String> = Lazy::new(|| {
+
    let schemas = SCHEMAS.to_vec().join("\", \"");
+
    format!("Expected exactly one of the following schema names: [\"{schemas}\"].")
+
});
+

+
enum Schema {
+
    Command,
+
    CommandResult,
+
    ProfileConfig,
+
}
+

+
impl std::str::FromStr for Schema {
+
    type Err = io::Error;
+

+
    fn from_str(s: &str) -> Result<Self, Self::Err> {
+
        match s {
+
            SCHEMA_COMMAND => Ok(Self::Command),
+
            SCHEMA_COMMAND_RESULT => Ok(Self::CommandResult),
+
            SCHEMA_PROFILE_CONFIG => Ok(Self::ProfileConfig),
+
            schema => Err(io::Error::new(
+
                io::ErrorKind::InvalidInput,
+
                format!("{schema}: {}", *ERROR_MSG),
+
            )),
+
        }
+
    }
+
}
+

+
impl Schema {
+
    fn from_args(mut args: std::env::Args) -> io::Result<Self> {
+
        let name = args.nth(1).ok_or_else(|| {
+
            io::Error::new(
+
                io::ErrorKind::InvalidInput,
+
                format!("No schema given. {}", *ERROR_MSG),
+
            )
+
        })?;
+
        name.parse()
+
    }
+
}
+

+
fn main() {
+
    if let Err(e) = print_schema() {
+
        eprintln!("{}", e);
+
        std::process::exit(1);
+
    }
+
}
+

+
fn print_schema() -> io::Result<()> {
+
    let args = std::env::args();
+

+
    let name = Schema::from_args(args)?;
+

+
    let schema = match name {
+
        Schema::Command => {
+
            let settings = SchemaSettings::default().for_serialize();
+
            let generator = settings.into_generator();
+

+
            generator.into_root_schema_for::<radicle::node::Command>()
+
        }
+
        Schema::CommandResult => {
+
            #[derive(JsonSchema)]
+
            #[allow(dead_code)]
+
            struct ListenAddrs(Vec<net::SocketAddr>);
+

+
            #[derive(JsonSchema)]
+
            #[allow(dead_code)]
+
            struct Error {
+
                error: String,
+
            }
+

+
            #[derive(JsonSchema)]
+
            #[schemars(untagged)]
+
            #[allow(dead_code)]
+
            enum CommandResult {
+
                Nid(
+
                    #[schemars(with = "radicle::schemars_ext::crypto::PublicKey")]
+
                    radicle::node::NodeId,
+
                ),
+
                Config(radicle::node::Config),
+
                ListenAddrs(ListenAddrs),
+
                ConnectResult(radicle::node::ConnectResult),
+
                Success(radicle::node::Success),
+
                Seeds(radicle::node::Seeds),
+
                FetchResult(radicle::node::FetchResult),
+
                RefsAt(radicle::storage::refs::RefsAt),
+
                Sessions(Vec<radicle::node::Session>),
+
                Session(Option<radicle::node::Session>),
+
                Error(Error),
+
            }
+
            schema_for!(CommandResult)
+
        }
+
        Schema::ProfileConfig => schemars::schema_for!(radicle::profile::Config),
+
    };
+

+
    serde_json::to_writer_pretty(std::io::stdout(), &schema)?;
+
    Ok(())
+
}