Skip to main content

kaish_client/
traits.rs

1//! Common trait for kernel clients.
2
3use std::collections::HashMap;
4
5use async_trait::async_trait;
6use thiserror::Error;
7
8use kaish_kernel::ast::Value;
9use kaish_kernel::interpreter::ExecResult;
10
11/// Result type for client operations.
12pub type ClientResult<T> = Result<T, ClientError>;
13
14/// Errors that can occur when using a kernel client.
15#[derive(Debug, Error)]
16pub enum ClientError {
17    /// Connection to the kernel failed.
18    #[error("connection error: {0}")]
19    Connection(String),
20
21    /// The kernel returned an error during execution.
22    #[error("execution error: {0}")]
23    Execution(String),
24
25    /// I/O error.
26    #[error("io error: {0}")]
27    Io(#[from] std::io::Error),
28
29    /// UTF-8 decoding error.
30    #[error("utf8 error: {0}")]
31    Utf8(#[from] std::str::Utf8Error),
32
33    /// The kernel is not connected.
34    #[error("not connected")]
35    NotConnected,
36
37    /// Other errors.
38    #[error("{0}")]
39    Other(#[from] anyhow::Error),
40}
41
42/// Common interface for interacting with a kaish kernel.
43///
44/// Both `EmbeddedClient` and custom client implementations can implement this trait,
45/// allowing code to work with any client type.
46#[async_trait(?Send)]
47pub trait KernelClient {
48    /// Execute kaish source code.
49    ///
50    /// Returns the result of the last statement executed.
51    async fn execute(&self, input: &str) -> ClientResult<ExecResult>;
52
53    /// Execute kaish source code with a transient overlay of exported variables.
54    ///
55    /// The overlay vars are visible (and exported to subprocesses) for the
56    /// duration of this call only, then removed. Names already exported in
57    /// the persistent state retain their outer value on return.
58    async fn execute_with_vars(
59        &self,
60        input: &str,
61        vars: HashMap<String, Value>,
62    ) -> ClientResult<ExecResult>;
63
64    /// Get a variable value.
65    async fn get_var(&self, name: &str) -> ClientResult<Option<Value>>;
66
67    /// Set a variable value.
68    async fn set_var(&self, name: &str, value: Value) -> ClientResult<()>;
69
70    /// List all variables.
71    async fn list_vars(&self) -> ClientResult<Vec<(String, Value)>>;
72
73    /// Get the current working directory.
74    async fn cwd(&self) -> ClientResult<String>;
75
76    /// Set the current working directory.
77    async fn set_cwd(&self, path: &str) -> ClientResult<()>;
78
79    /// Get the last execution result ($?).
80    async fn last_result(&self) -> ClientResult<ExecResult>;
81
82    /// Reset the kernel to initial state.
83    async fn reset(&self) -> ClientResult<()>;
84
85    /// Ping the kernel (health check).
86    async fn ping(&self) -> ClientResult<String>;
87
88    /// Shutdown the kernel.
89    async fn shutdown(&self) -> ClientResult<()>;
90
91    /// Read a blob by ID.
92    ///
93    /// Returns the blob contents as raw bytes.
94    async fn read_blob(&self, id: &str) -> ClientResult<Vec<u8>>;
95
96    /// Write a blob and return its ID.
97    ///
98    /// The blob is stored in `/v/blobs/{id}` and can be referenced via BlobRef.
99    async fn write_blob(&self, content_type: &str, data: &[u8]) -> ClientResult<String>;
100
101    /// Delete a blob by ID.
102    ///
103    /// Returns true if the blob was deleted, false if it didn't exist.
104    async fn delete_blob(&self, id: &str) -> ClientResult<bool>;
105}