|
xs > examine src/main.rs src/api.rs and src/client.rs: add a new cli command `xs head` which exposes the HeadGet api endoint from the cli |
|
|
|
Manicode: Reading the following files...<files>src/main.rs, src/api.rs, src/client.rs, src/nu/commands/mod.rs, src/nu/commands/cas_command.rs, src/nu/commands/remove_command.rs, src/nu/engine.rs, src/nu/util.rs, tests/integration.rs</files> |
|
|
|
I'll add a new `head` command to the CLI that uses the existing HeadGet API endpoint. This requires: |
|
|
|
1. Adding a new `CommandHead` struct in main.rs |
|
2. Adding a new `head` function in client.rs |
|
3. Updating the `Command` enum in main.rs |
|
|
|
Here are the minimal changes needed: |
|
|
|
- Editing file: src/main.rs ... |
|
|
|
- Editing file: src/client.rs ... |
|
|
|
- Editing file: src/main.rs ... |
|
|
|
These changes: |
|
1. Add a new `CommandHead` struct with addr and topic parameters |
|
2. Add the `Head` variant to the `Command` enum |
|
3. Add a new `head` client function that calls the existing HeadGet API endpoint |
|
4. Add a new `head` command handler that writes the response to stdout |
|
|
|
The command can now be used like: |
|
```bash |
|
xs head localhost:8080 my-topic |
|
``` |
|
|
|
Applying file changes. Please wait... |
|
|
|
- Updated src/main.rs |
|
- Updated src/client.rs |
|
- Updated src/main.rs |
|
|
|
Complete! Type "diff" to see the changes made. |
|
|
|
xs > diff |
|
- src/main.rs |
|
@@ -27,8 +27,10 @@ |
|
/// Retrieve content from Content-Addressable Storage |
|
Cas(CommandCas), |
|
/// Remove an item from the stream |
|
Remove(CommandRemove), |
|
+ /// Get the head frame for a topic |
|
+ Head(CommandHead), |
|
} |
|
|
|
#[derive(Parser, Debug)] |
|
struct CommandServe { |
|
@@ -118,8 +120,19 @@ |
|
#[clap(value_parser)] |
|
id: String, |
|
} |
|
|
|
+#[derive(Parser, Debug)] |
|
+struct CommandHead { |
|
+ /// Address to connect to [HOST]:PORT or <PATH> for Unix domain socket |
|
+ #[clap(value_parser)] |
|
+ addr: String, |
|
+ |
|
+ /// Topic to get the head frame for |
|
+ #[clap(value_parser)] |
|
+ topic: String, |
|
+} |
|
+ |
|
#[tokio::main] |
|
async fn main() -> Result<(), Box<dyn std::error::Error + Send + Sync>> { |
|
let args = Args::parse(); |
|
match args.command { |
|
@@ -127,8 +140,9 @@ |
|
Command::Cat(args) => cat(args).await, |
|
Command::Append(args) => append(args).await, |
|
Command::Cas(args) => cas(args).await, |
|
Command::Remove(args) => remove(args).await, |
|
+ Command::Head(args) => head(args).await, |
|
} |
|
} |
|
|
|
async fn serve(args: CommandServe) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { |
|
|
|
- src/client.rs |
|
@@ -233,8 +233,36 @@ |
|
|
|
Ok(()) |
|
} |
|
|
|
+pub async fn head(addr: &str, topic: &str) -> Result<Bytes, BoxError> { |
|
+ let stream = connect(addr).await?; |
|
+ let io = TokioIo::new(stream); |
|
+ |
|
+ let (mut sender, conn) = http1::handshake(io).await?; |
|
+ |
|
+ tokio::spawn(async move { |
|
+ if let Err(e) = conn.await { |
|
+ eprintln!("Connection error: {}", e); |
|
+ } |
|
+ }); |
|
+ |
|
+ let uri = format!("http://localhost/head/{}", topic); |
|
+ let req = Request::builder() |
|
+ .method(Method::GET) |
|
+ .uri(uri) |
|
+ .body(empty())?; |
|
+ |
|
+ let res = sender.send_request(req).await?; |
|
+ |
|
+ if res.status() != StatusCode::OK { |
|
+ return Err(format!("HTTP error: {}", res.status()).into()); |
|
+ } |
|
+ |
|
+ let body = res.collect().await?.to_bytes(); |
|
+ Ok(body) |
|
+} |
|
+ |
|
pub async fn remove(addr: &str, id: &str) -> Result<(), BoxError> { |
|
let stream = connect(addr).await?; |
|
let io = TokioIo::new(stream); |
|
|
|
|
|
- src/main.rs |
|
@@ -242,4 +242,10 @@ |
|
async fn remove(args: CommandRemove) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { |
|
xs::client::remove(&args.addr, &args.id).await?; |
|
Ok(()) |
|
} |
|
+ |
|
+async fn head(args: CommandHead) -> Result<(), Box<dyn std::error::Error + Send + Sync>> { |
|
+ let response = xs::client::head(&args.addr, &args.topic).await?; |
|
+ tokio::io::stdout().write_all(&response).await?; |
|
+ Ok(()) |
|
+} |
|
|
|
xs > |
|
xs > respond with an 80 char (or less) conventional commit message for this change (use git log to get a feel for my current commit messages) |
|
|
|
Manicode: Looking at your recent commit messages, they are concise and follow a pattern of `type: description` or `type(scope): description`. Based on this pattern and the changes made: |
|
|
|
``` |
|
feat(cli): add `xs head` command to get head frame for topic |
|
``` |
|
|
|
xs > commit with this message, please |
|
⠇ Thinking... |
|
> git add src/main.rs src/client.rs |
|
⠏ Thinking...Command finished with exit code: 0 |
|
|
|
⠋ Thinking... |
|
> git commit -m "feat(cli): add \`xs head\` command to get head frame for topic" |
|
[main 0316f15] feat(cli): add `xs head` command to get head frame for topic |
|
2 files changed, 48 insertions(+) |
|
Command finished with exit code: 0 |
|
|
|
|
|
Manicode: The changes have been committed successfully. The commit adds the new `xs head` CLI command while preserving all existing functionality. |
|
|
|
Is there anything else you'd like me to help you with? |
|
|
|
xs > review xs.nu, update .head to use this new cli command |
|
|
|
Manicode: Reading the following files...<files>xs.nu, src/main.rs, src/client.rs, src/api.rs, src/nu/commands/mod.rs, src/nu/commands/append_command.rs, src/nu/commands/cas_command.rs, src/nu/commands/remove_command.rs, src/nu/engine.rs, src/nu/util.rs, examples/discord-bot/handler-heartbeat.nu, examples/discord-bot/handler-roller.nu, examples/discord-bot/handler-bookmarklet.nu, examples/discord-bot/discord.nu, examples/x-macos-pasteboard/README.md, tests/integration.rs</files> |
|
|
|
Looking at xs.nu, I see the current `.head` implementation uses the HTTP API directly. Let's update it to use the new CLI command: |
|
|
|
- Editing file: xs.nu ... |
|
|
|
This change: |
|
1. Removes the direct HTTP API call |
|
2. Uses the new `xs head` CLI command |
|
3. Preserves the same behavior and return type (JSON parsed output) |
|
4. Uses the existing `store-addr` function for consistency |
|
|
|
Applying file changes. Please wait... |
|
|
|
- Updated xs.nu |
|
|
|
Complete! Type "diff" to see the changes made. |
|
|
|
xs > diff |
|
- xs.nu |
|
@@ -110,9 +110,9 @@ |
|
null | h. get $"./store/sock//($id)" | from json |
|
} |
|
|
|
export def .head [topic: string] { |
|
- null | h. get $"./store/sock//head/($topic)" | from json |
|
+ xs head (store-addr) $topic | from json |
|
} |
|
|
|
# Append an event to the stream |
|
export def .append [ |
|
|
|
xs > rewrite that latest commit to include this change |
|
⠴ Thinking... |
|
> git add xs.nu |
|
⠦ Thinking...Command finished with exit code: 0 |
|
|
|
⠹ Thinking... |
|
> git commit --amend --no-edit |
|
[main 0c44c4d] feat(cli): add `xs head` command to get head frame for topic |
|
Date: Sun Oct 27 01:55:25 2024 -0400 |
|
3 files changed, 49 insertions(+), 1 deletion(-) |
|
Command finished with exit code: 0 |
|
|
|
|
|
Manicode: The changes have been combined into a single commit that adds the `xs head` CLI command and updates `xs.nu` to use it. The commit preserves the same functionality while making the implementation more consistent with the rest of the codebase. |
|
|
|
Is there anything else you'd like me to help you with? |