From c2d14bdb7e1665b80cb3536893c0fecc0d67f895 Mon Sep 17 00:00:00 2001 From: Zeek Date: Fri, 4 Nov 2022 06:27:04 -0400 Subject: [PATCH 1/3] template --- Cargo.lock | 42 +++++------------------------------ Cargo.toml | 3 ++- src/cli.rs | 59 +++++++++++++++++++++++++++++++++++++++++++++++++ src/main.rs | 63 ++++++++++++++++++++++++++++++++++++++++------------- 4 files changed, 115 insertions(+), 52 deletions(-) create mode 100644 src/cli.rs diff --git a/Cargo.lock b/Cargo.lock index b39da7c..73d1688 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -13,12 +13,6 @@ dependencies = [ "winapi", ] -[[package]] -name = "autocfg" -version = "1.1.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "d468802bab17cbc0cc575e9b053f41e72aa36bfa6b7f55e3529ffa43161b97fa" - [[package]] name = "bitflags" version = "1.3.2" @@ -27,26 +21,24 @@ checksum = "bef38d45163c2f1dde094a7dfd33ccf595c92905c8f8f4fdc18d06fb1037718a" [[package]] name = "clap" -version = "3.2.22" +version = "4.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "86447ad904c7fb335a790c9d7fe3d0d971dc523b8ccd1561a520de9a85302750" +checksum = "335867764ed2de42325fafe6d18b8af74ba97ee0c590fa016f157535b42ab04b" dependencies = [ "atty", "bitflags", "clap_derive", "clap_lex", - "indexmap", "once_cell", "strsim", "termcolor", - "textwrap", ] [[package]] name = "clap_derive" -version = "3.2.18" +version = "4.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ea0c8bce528c4be4da13ea6fead8965e95b6073585a2f05204bd8f4119f82a65" +checksum = "16a1b0f6422af32d5da0c58e2703320f379216ee70198241c84173a8c5ac28f3" dependencies = [ "heck", "proc-macro-error", @@ -57,19 +49,13 @@ dependencies = [ [[package]] name = "clap_lex" -version = "0.2.4" +version = "0.3.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2850f2f5a82cbf437dd5af4d49848fbdfc27c157c3d010345776f952765261c5" +checksum = "0d4198f73e42b4936b35b5bb248d81d2b595ecb170da0bac7655c54eedfa8da8" dependencies = [ "os_str_bytes", ] -[[package]] -name = "hashbrown" -version = "0.12.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8a9ee70c43aaf417c914396645a0fa852624801b24ebb7ae78fe8272889ac888" - [[package]] name = "heck" version = "0.4.0" @@ -85,16 +71,6 @@ dependencies = [ "libc", ] -[[package]] -name = "indexmap" -version = "1.9.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "10a35a97730320ffe8e2d410b5d3b69279b98d2c14bdb8b70ea89ecf7888d41e" -dependencies = [ - "autocfg", - "hashbrown", -] - [[package]] name = "libc" version = "0.2.133" @@ -181,12 +157,6 @@ dependencies = [ "winapi-util", ] -[[package]] -name = "textwrap" -version = "0.15.1" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "949517c0cf1bf4ee812e2e07e08ab448e3ae0d23472aee8a06c985f0c8815b16" - [[package]] name = "trustgraph-rust-cli" version = "0.1.0" diff --git a/Cargo.toml b/Cargo.toml index c91d4ea..4f9ea7a 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,9 +1,10 @@ [package] name = "trustgraph-rust-cli" +author ="Author" version = "0.1.0" edition = "2021" # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html [dependencies] -clap = { version = "3.2.22", features = ["derive"] } +clap = { version = "4.0.15", features = ["derive"] } diff --git a/src/cli.rs b/src/cli.rs new file mode 100644 index 0000000..5b05e99 --- /dev/null +++ b/src/cli.rs @@ -0,0 +1,59 @@ + + +use std::path::PathBuf; + +use clap::{Args, Parser, Subcommand}; + + + +#[derive(Debug, Parser)] +#[command(name = "trust")] +#[command(author, version, about, long_about = None)] +pub struct Cli { + #[command(subcommand)] + pub command: Commands, +} + +#[derive(Debug, Subcommand)] +pub enum Commands { + /// Doc comment goes here + #[command(arg_required_else_help = true)] + A { + a: String, + }, + + #[command(arg_required_else_help = true)] + B { + b: String, + }, + #[command(arg_required_else_help = true)] + C { + #[arg(required = true)] + c: Vec, + }, + D(D), +} + +#[derive(Debug, Args)] +#[command(subcommand_precedence_over_arg = true)] +struct D { + #[command(subcommand)] + command: Option, + + #[command(flatten)] + push: ExampleStruct, +} + +#[derive(Debug, Subcommand)] +enum ExampleSubCommands { + X(ExampleStruct), + Y { w: Option }, + Z { v: Option }, +} + +#[derive(Debug, Args)] +struct ExampleStruct { + #[arg(short, long)] + message: Option, +} + diff --git a/src/main.rs b/src/main.rs index 7117689..33001d7 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,8 +1,8 @@ +use clap::error::ErrorKind; use clap::Parser; -/// Simple program to greet a person -#[derive(Parser, Debug)] -#[clap(author, version, about, long_about = None)] +mod cli; +use cli::{Cli, Commands}; /* TODO next: @@ -21,20 +21,53 @@ use clap::Parser; */ -struct Args { - /// Name of the person to greet - #[clap(short, long, value_parser)] - name: String, - /// Number of times to greet - #[clap(short, long, value_parser, default_value_t = 1)] - count: u8, -} fn main() { - let args = Args::parse(); + let args = Cli::parse(); + + match args.command { + Commands::A { a } => { + println!("Cloning {}", a); + }, + } + - for _ in 0..args.count { - println!("Hello {}!", args.name) - } } + + +//// + +// // You can check the value provided by positional arguments, or option arguments +// if let Some(name) = cli.name.as_deref() { +// println!("Value for name: {}", name); +// } + +// if let Some(config_path) = cli.config.as_deref() { +// println!("Value for config: {}", config_path.display()); +// } + +// // You can see how many times a particular flag or argument occurred +// // Note, only flags can have multiple occurrences +// match cli.debug { +// 0 => println!("Debug mode is off"), +// 1 => println!("Debug mode is kind of on"), +// 2 => println!("Debug mode is on"), +// _ => println!("Don't be crazy"), +// } + +// // You can check for the existence of subcommands, and if found use their +// // matches just as you would the top level cmd +// match &cli.command { +// Some(Commands::Test { list }) => { +// if *list { +// println!("Printing testing lists..."); +// } else { +// println!("Not printing testing lists..."); +// } +// } +// None => {} +// } + +// // Continued program logic goes here... +// } From b20b3765931f2efd5ed9ae68981173200fce7e63 Mon Sep 17 00:00:00 2001 From: Zeek Date: Fri, 18 Nov 2022 18:19:31 -0500 Subject: [PATCH 2/3] trust claim and graph commands --- Cargo.lock | 45 +++++++++++++++++++ Cargo.toml | 2 + src/cli.rs | 124 +++++++++++++++++++++++++++++++++++++--------------- src/main.rs | 108 ++++++++++++++++++++++++++++----------------- 4 files changed, 205 insertions(+), 74 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index 73d1688..2bddafc 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -71,6 +71,12 @@ dependencies = [ "libc", ] +[[package]] +name = "itoa" +version = "1.0.4" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4217ad341ebadf8d8e724e264f13e593e0648f5b3e94b3896a5df283be015ecc" + [[package]] name = "libc" version = "0.2.133" @@ -131,6 +137,43 @@ dependencies = [ "proc-macro2", ] +[[package]] +name = "ryu" +version = "1.0.11" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4501abdff3ae82a1c1b477a17252eb69cee9e66eb915c1abaa4f44d873df9f09" + +[[package]] +name = "serde" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "d193d69bae983fc11a79df82342761dfbf28a99fc8d203dca4c3c1b590948965" +dependencies = [ + "serde_derive", +] + +[[package]] +name = "serde_derive" +version = "1.0.147" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4f1d362ca8fc9c3e3a7484440752472d68a6caa98f1ab81d99b5dfe517cec852" +dependencies = [ + "proc-macro2", + "quote", + "syn", +] + +[[package]] +name = "serde_json" +version = "1.0.87" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "6ce777b7b150d76b9cf60d28b55f5847135a003f7d7350c6be7a773508ce7d45" +dependencies = [ + "itoa", + "ryu", + "serde", +] + [[package]] name = "strsim" version = "0.10.0" @@ -162,6 +205,8 @@ name = "trustgraph-rust-cli" version = "0.1.0" dependencies = [ "clap", + "serde", + "serde_json", ] [[package]] diff --git a/Cargo.toml b/Cargo.toml index 4f9ea7a..8fd6b05 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -8,3 +8,5 @@ edition = "2021" [dependencies] clap = { version = "4.0.15", features = ["derive"] } +serde = { version = "1", features = ["derive"] } +serde_json = "1" \ No newline at end of file diff --git a/src/cli.rs b/src/cli.rs index 5b05e99..9fc89a3 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,59 +1,113 @@ +use serde::{Serialize, Deserialize}; +// use std::path::PathBuf; - -use std::path::PathBuf; - -use clap::{Args, Parser, Subcommand}; +use clap::{Args, Parser, Subcommand, ValueEnum}; #[derive(Debug, Parser)] #[command(name = "trust")] -#[command(author, version, about, long_about = None)] +#[clap(author, version, about = "TrustGraph CLI", long_about = None)] pub struct Cli { + // #[arg(value_enum)] + // pub config: Option, #[command(subcommand)] - pub command: Commands, + pub command: Option, } +// #[derive(Debug, Args)] +// enum ConfigSettings { + +// } + #[derive(Debug, Subcommand)] pub enum Commands { - /// Doc comment goes here - #[command(arg_required_else_help = true)] - A { - a: String, - }, #[command(arg_required_else_help = true)] - B { - b: String, + Claim { + /// DID or URL of claim creator + #[arg(short, long, required = true)] + creator: String, + /// DID or URL of claim target + #[arg(short ='t', long, required = true)] + target: String, + /// Rating tags (at least 1 tag is required) + #[arg(long, required = true, num_args(1..2))] + tags: String, + /// Rating description + #[arg(short, long)] + description: Option, + /// Extra data (can be used multiple times) + // #[arg(short, long, action = clap::ArgAction::Count)] + // extra: Option, + /// Rating weight in the range 0..1 + #[arg(short, long)] + value: Option, + /// Signing algorithm + #[arg(short, long, default_value_t = String::from("EcdsaKoblitzSignature2016"))] + algorithm: String, + /// Private key + #[arg(short, long, required = true)] + private_key: String, + /// OpenTrustClaim | Reputon | TrustAtom | TrustClaim + #[arg(long, value_enum)] + target_format: TargetFormat, + /// Stdout | File | IPFS + #[arg(short, long, value_enum)] + write: WriteTo, }, + #[command(arg_required_else_help = true)] - C { - #[arg(required = true)] - c: Vec, - }, - D(D), -} + Graph { + #[command(subcommand)] + subcommand: Option, -#[derive(Debug, Args)] -#[command(subcommand_precedence_over_arg = true)] -struct D { - #[command(subcommand)] - command: Option, + /// Perspective (identity) through which trust network is seen + #[arg(short, long)] + perspective: String, + /// DID or URL of claim creator + #[arg(short, long)] + creator: String, + /// DID or URL of claim target + #[arg(short = 't', long)] + target: String, + /// Filter by tags + #[arg(long, num_args(1..2))] + tags: String, + /// Crawls trust ratings to specified depth + #[arg(short, long, default_value_t = 1)] + depth: i8, + /// Min trust rating 0..1 + #[arg(long)] + min_value: Option, + /// Max trust rating 0..1 + #[arg(long)] + max_value: Option, - #[command(flatten)] - push: ExampleStruct, + }, + } -#[derive(Debug, Subcommand)] -enum ExampleSubCommands { - X(ExampleStruct), - Y { w: Option }, - Z { v: Option }, +#[derive(Debug, Clone, Subcommand, ValueEnum)] +pub enum GraphCommands { + /// Summarize claims / build analysis + Summarize, + /// Trust level relative to depth, eg: [1, 0.5 0.33] + Falloff, } -#[derive(Debug, Args)] -struct ExampleStruct { - #[arg(short, long)] - message: Option, + +#[derive(Debug, Clone, Serialize, Deserialize, ValueEnum)] +pub enum TargetFormat { + OpenTrustClaim, + Reputon, + TrustAtom, + TrustClaim, } +#[derive(Debug, Clone, Serialize, Deserialize, ValueEnum)] +pub enum WriteTo { + Stdout, + File, + Ipfs, +} diff --git a/src/main.rs b/src/main.rs index 33001d7..e283237 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,4 +1,5 @@ -use clap::error::ErrorKind; +use serde_json::json; +// use clap::error::ErrorKind; use clap::Parser; mod cli; @@ -26,48 +27,77 @@ use cli::{Cli, Commands}; fn main() { let args = Cli::parse(); - match args.command { - Commands::A { a } => { - println!("Cloning {}", a); + match &args.command { + Some(Commands::Claim { + creator, + target, + tags, + description, + // extra, + value, + algorithm, + private_key, + target_format, + write, + }) => { + + let john = json!({ + + "@context": "https://raw.githubusercontent.com/trustgraph/trustgraph-schema/gh-pages/TrustClaim.jsonld", + "type": target_format, + "issuer": creator, + "issued": "2017-03-04T02:05:07-08:00", + "claim": { + "@context": "https://schema.org/", + "type": "Review", + "itemReviewed": target, + "author": creator, + "keywords": tags, + "reviewRating": { + "@context": "https://schema.org/", + "type": "Rating", + "bestRating": 1, + "worstRating": 0, + "ratingValue": value, + "description": description + } + }, + "signature": { + "type": format!("sec: {}", algorithm), + "http://purl.org/dc/terms/created": { + "type": "http://www.w3.org/2001/XMLSchema#dateTime", + "@value": "2017-03-04T10:05:07Z" + }, + "http://purl.org/dc/terms/creator": { + "id": "EcdsaKoblitz-public-key:020d79074ef137d4f338c2e6bef2a49c618109eccf1cd01ccc3286634789baef4b" + }, + "sec:domain": "example.com", + "signature:Value": "IEd/NpCGX7cRe4wc1xh3o4X/y37pY4tOdt8WbYnaGw/Gbr2Oz7GqtkbYE8dxfxjFFYCrISPJGbBNFyaiVBAb6bs=" + } + + }); }, + Some(Commands::Graph { + subcommand, + perspective, + creator, + target, + tags, + depth, + min_value, + max_value, + }) => { + // TODO: Graph command methods + }, + None => {} // Default method or throw error? } } -//// - -// // You can check the value provided by positional arguments, or option arguments -// if let Some(name) = cli.name.as_deref() { -// println!("Value for name: {}", name); -// } - -// if let Some(config_path) = cli.config.as_deref() { -// println!("Value for config: {}", config_path.display()); -// } - -// // You can see how many times a particular flag or argument occurred -// // Note, only flags can have multiple occurrences -// match cli.debug { -// 0 => println!("Debug mode is off"), -// 1 => println!("Debug mode is kind of on"), -// 2 => println!("Debug mode is on"), -// _ => println!("Don't be crazy"), -// } - -// // You can check for the existence of subcommands, and if found use their -// // matches just as you would the top level cmd -// match &cli.command { -// Some(Commands::Test { list }) => { -// if *list { -// println!("Printing testing lists..."); -// } else { -// println!("Not printing testing lists..."); -// } -// } -// None => {} -// } - -// // Continued program logic goes here... -// } +#[test] +fn verify_cli() { + use clap::CommandFactory; + Cli::command().debug_assert() +} \ No newline at end of file From 52bf8a23d73b18b4cb597e36088f07c184146a9e Mon Sep 17 00:00:00 2001 From: Zeek Date: Wed, 22 Mar 2023 00:23:06 -0600 Subject: [PATCH 3/3] mark optional flags --- src/cli.rs | 33 ++++++++++++------------ src/main.rs | 74 ++++++++++++++++++++++++++--------------------------- 2 files changed, 54 insertions(+), 53 deletions(-) diff --git a/src/cli.rs b/src/cli.rs index 9fc89a3..cfe4e2b 100644 --- a/src/cli.rs +++ b/src/cli.rs @@ -1,7 +1,8 @@ use serde::{Serialize, Deserialize}; -// use std::path::PathBuf; -use clap::{Args, Parser, Subcommand, ValueEnum}; + + +use clap::{Parser, Subcommand, ValueEnum}; @@ -25,15 +26,15 @@ pub enum Commands { #[command(arg_required_else_help = true)] Claim { - /// DID or URL of claim creator - #[arg(short, long, required = true)] - creator: String, /// DID or URL of claim target #[arg(short ='t', long, required = true)] target: String, + /// DID or URL of claim creator + #[arg(short, long, required = true)] + creator: Option, /// Rating tags (at least 1 tag is required) #[arg(long, required = true, num_args(1..2))] - tags: String, + tags: Option, /// Rating description #[arg(short, long)] description: Option, @@ -44,17 +45,17 @@ pub enum Commands { #[arg(short, long)] value: Option, /// Signing algorithm - #[arg(short, long, default_value_t = String::from("EcdsaKoblitzSignature2016"))] - algorithm: String, + // #[arg(short, long, default_value = Some(String::from("EcdsaKoblitzSignature2016")))] // TODO: fix formatting error + // algorithm: Option, /// Private key #[arg(short, long, required = true)] - private_key: String, + private_key: Option, /// OpenTrustClaim | Reputon | TrustAtom | TrustClaim #[arg(long, value_enum)] - target_format: TargetFormat, + target_format: Option, /// Stdout | File | IPFS #[arg(short, long, value_enum)] - write: WriteTo, + write: Option, }, #[command(arg_required_else_help = true)] @@ -67,16 +68,16 @@ pub enum Commands { perspective: String, /// DID or URL of claim creator #[arg(short, long)] - creator: String, + creator: Option, /// DID or URL of claim target #[arg(short = 't', long)] - target: String, + target: Option, /// Filter by tags #[arg(long, num_args(1..2))] - tags: String, + tags: Option, /// Crawls trust ratings to specified depth - #[arg(short, long, default_value_t = 1)] - depth: i8, + #[arg(short, long)] + depth: Option, /// Min trust rating 0..1 #[arg(long)] min_value: Option, diff --git a/src/main.rs b/src/main.rs index e283237..67d94c9 100644 --- a/src/main.rs +++ b/src/main.rs @@ -29,53 +29,53 @@ fn main() { match &args.command { Some(Commands::Claim { - creator, target, + creator, tags, description, // extra, value, - algorithm, + // algorithm, private_key, target_format, write, }) => { - let john = json!({ - - "@context": "https://raw.githubusercontent.com/trustgraph/trustgraph-schema/gh-pages/TrustClaim.jsonld", - "type": target_format, - "issuer": creator, - "issued": "2017-03-04T02:05:07-08:00", - "claim": { - "@context": "https://schema.org/", - "type": "Review", - "itemReviewed": target, - "author": creator, - "keywords": tags, - "reviewRating": { - "@context": "https://schema.org/", - "type": "Rating", - "bestRating": 1, - "worstRating": 0, - "ratingValue": value, - "description": description - } - }, - "signature": { - "type": format!("sec: {}", algorithm), - "http://purl.org/dc/terms/created": { - "type": "http://www.w3.org/2001/XMLSchema#dateTime", - "@value": "2017-03-04T10:05:07Z" - }, - "http://purl.org/dc/terms/creator": { - "id": "EcdsaKoblitz-public-key:020d79074ef137d4f338c2e6bef2a49c618109eccf1cd01ccc3286634789baef4b" - }, - "sec:domain": "example.com", - "signature:Value": "IEd/NpCGX7cRe4wc1xh3o4X/y37pY4tOdt8WbYnaGw/Gbr2Oz7GqtkbYE8dxfxjFFYCrISPJGbBNFyaiVBAb6bs=" - } - - }); + // let json = json!({ + + // "@context": "https://raw.githubusercontent.com/trustgraph/trustgraph-schema/gh-pages/TrustClaim.jsonld", + // "type": target_format, + // "issuer": creator, + // "issued": "2017-03-04T02:05:07-08:00", + // "claim": { + // "@context": "https://schema.org/", + // "type": "Review", + // "itemReviewed": target, + // "author": creator, + // "keywords": tags, + // "reviewRating": { + // "@context": "https://schema.org/", + // "type": "Rating", + // "bestRating": 1, + // "worstRating": 0, + // "ratingValue": value, + // "description": description + // } + // }, + // "signature": { + // "type": "EcdsaKoblitzSignature2016".to_string(), + // "http://purl.org/dc/terms/created": { + // "type": "http://www.w3.org/2001/XMLSchema#dateTime", + // "@value": "2017-03-04T10:05:07Z" + // }, + // "http://purl.org/dc/terms/creator": { + // "id": "EcdsaKoblitz-public-key:020d79074ef137d4f338c2e6bef2a49c618109eccf1cd01ccc3286634789baef4b" + // }, + // "sec:domain": "example.com", + // "signature:Value": "IEd/NpCGX7cRe4wc1xh3o4X/y37pY4tOdt8WbYnaGw/Gbr2Oz7GqtkbYE8dxfxjFFYCrISPJGbBNFyaiVBAb6bs=" + // } + + // }); }, Some(Commands::Graph { subcommand,