Bootstrap geth Rust workspace

This commit is contained in:
Eric Wendland 2026-05-15 15:08:20 +02:00
commit 26f81ff1ef
73 changed files with 4835 additions and 0 deletions

View file

@ -0,0 +1,14 @@
[package]
name = "geth-control"
version = "0.1.0"
edition.workspace = true
rust-version.workspace = true
license.workspace = true
[dependencies]
serde.workspace = true
serde_json.workspace = true
thiserror.workspace = true
geth-auth = { path = "../geth-auth" }
geth-resource = { path = "../geth-resource" }
geth-types = { path = "../geth-types" }

View file

@ -0,0 +1,164 @@
use geth_auth::AuthExplanation;
use geth_resource::ResourceDescriptor;
use geth_types::BlobHash;
use serde::{Deserialize, Serialize};
use std::path::PathBuf;
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "kebab-case")]
pub enum ControlRequest {
Status,
NodeId,
ResourceList,
ResourceCreate {
kind: String,
name: String,
},
CasAdd {
path: PathBuf,
},
CasGet {
hash: BlobHash,
out: PathBuf,
},
CasHash {
path: PathBuf,
},
CasHas {
hash: BlobHash,
},
CasList,
KeychainStatus,
AuthExplain {
subject: String,
resource: String,
capability: String,
},
ModuleStub {
module: String,
command: String,
},
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
#[serde(tag = "type", rename_all = "kebab-case")]
pub enum ControlResponse {
Status(StatusResponse),
NodeId(NodeIdResponse),
ResourceList {
resources: Vec<ResourceDescriptor>,
},
ResourceCreated {
resource: ResourceDescriptor,
},
CasAdded {
hash: BlobHash,
size_bytes: u64,
},
CasGot {
hash: BlobHash,
out: PathBuf,
size_bytes: u64,
},
CasHash {
hash: BlobHash,
},
CasHas {
hash: BlobHash,
present: bool,
},
CasList {
blobs: Vec<CasBlob>,
},
KeychainStatus(KeychainStatusResponse),
AuthExplain(AuthExplanation),
NotImplemented {
module: String,
command: String,
},
Error {
message: String,
},
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct StatusResponse {
pub home: PathBuf,
pub socket: PathBuf,
pub agent_id: String,
pub node_id: String,
pub iroh: String,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct NodeIdResponse {
pub agent_id: String,
pub node_id: String,
pub endpoint_id: Option<String>,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct KeychainStatusResponse {
pub initialized: bool,
pub admin_keys: usize,
pub users: usize,
pub devices: usize,
pub nodes: usize,
}
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize)]
pub struct CasBlob {
pub hash: BlobHash,
pub size_bytes: u64,
}
#[derive(Debug, thiserror::Error)]
pub enum ControlError {
#[error("json error: {0}")]
Json(#[from] serde_json::Error),
}
pub fn encode_request(request: &ControlRequest) -> Result<String, ControlError> {
let mut line = serde_json::to_string(request)?;
line.push('\n');
Ok(line)
}
pub fn decode_request(line: &str) -> Result<ControlRequest, ControlError> {
serde_json::from_str(line).map_err(ControlError::from)
}
pub fn encode_response(response: &ControlResponse) -> Result<String, ControlError> {
let mut line = serde_json::to_string(response)?;
line.push('\n');
Ok(line)
}
pub fn decode_response(line: &str) -> Result<ControlResponse, ControlError> {
serde_json::from_str(line).map_err(ControlError::from)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn control_request_response_serialization_roundtrip() {
let request = ControlRequest::CasHas {
hash: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef".into(),
};
assert_eq!(
decode_request(&encode_request(&request).expect("encode")).expect("decode"),
request
);
let response = ControlResponse::CasHas {
hash: "0123456789abcdef0123456789abcdef0123456789abcdef0123456789abcdef".into(),
present: true,
};
assert_eq!(
decode_response(&encode_response(&response).expect("encode")).expect("decode"),
response
);
}
}