diff --git a/Cargo.lock b/Cargo.lock index 8552108..afafcc9 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -232,6 +232,12 @@ dependencies = [ "backtrace", ] +[[package]] +name = "base16ct" +version = "0.2.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "4c7f02d4ea65f2c1853089ffd8d2787bdbc63de2f0d29dedbcf8ccdfa0ccd4cf" + [[package]] name = "base64" version = "0.21.7" @@ -276,9 +282,9 @@ checksum = "1fd0f2584146f6f2ef48085050886acf353beff7305ebd1ae69500e27c67f64b" [[package]] name = "bytes" -version = "1.8.0" +version = "1.9.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9ac0150caa2ae65ca5bd83f25c7de183dea78d4d366469f148435e2acfbad0da" +checksum = "325918d6fe32f23b19878fe4b34794ae41fc19ddbe53b10571a4874d44ffd39b" [[package]] name = "cc" @@ -1514,6 +1520,7 @@ name = "s2" version = "0.3.0" dependencies = [ "async-stream", + "base16ct", "clap", "color-print", "colored", diff --git a/Cargo.toml b/Cargo.toml index f9954a6..23f4308 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -6,6 +6,7 @@ license = "Apache-2.0" [dependencies] async-stream = "0.3.6" +base16ct = { version = "0.2.0", features = ["alloc"] } clap = { version = "4.5.20", features = ["derive"] } color-print = "0.3.6" colored = "2.1.0" diff --git a/src/main.rs b/src/main.rs index bc3a910..3a4d8e3 100644 --- a/src/main.rs +++ b/src/main.rs @@ -13,8 +13,8 @@ use stream::{RecordStream, StreamService}; use streamstore::{ client::{BasinClient, Client, ClientConfig, S2Endpoints, StreamClient}, types::{ - BasinInfo, BasinName, CommandRecord, FencingToken, MeteredBytes as _, ReadOutput, - StreamInfo, + BasinInfo, BasinName, CommandRecord, ConvertError, FencingToken, MeteredBytes as _, + ReadOutput, StreamInfo, }, HeaderValue, }; @@ -200,7 +200,7 @@ enum Commands { trim_point: u64, /// Enforce fencing token specified in hex. - #[arg(short = 'f', long)] + #[arg(short = 'f', long, value_parser = parse_fencing_token)] fencing_token: Option, /// Enforce that the sequence number issued to the first record matches. @@ -224,10 +224,11 @@ enum Commands { /// New fencing token specified in hex. /// It may be upto 16 bytes, and can be empty. + #[arg(value_parser = parse_fencing_token)] new_fencing_token: FencingToken, /// Enforce existing fencing token, specified in hex. - #[arg(short = 'f', long)] + #[arg(short = 'f', long, value_parser = parse_fencing_token)] fencing_token: Option, /// Enforce that the sequence number issued to this command matches. @@ -246,7 +247,7 @@ enum Commands { stream: String, /// Enforce fencing token specified in hex. - #[arg(short = 'f', long)] + #[arg(short = 'f', long, value_parser = parse_fencing_token)] fencing_token: Option, /// Enforce that the sequence number issued to the first record matches. @@ -358,6 +359,12 @@ fn parse_records_output_source(s: &str) -> Result { } } +fn parse_fencing_token(s: &str) -> Result { + base16ct::mixed::decode_vec(s) + .map_err(|_| "invalid hex")? + .try_into() +} + fn client_config(auth_token: String) -> Result { let endpoints = S2Endpoints::from_env().map_err(S2CliError::EndpointsFromEnv)?; let client_config = ClientConfig::new(auth_token.to_string())