use iroh::{EndpointAddr, EndpointId};
use iroh_blobs::Hash;
use irpc::{channel::{mpsc, oneshot}, rpc_requests};
use serde::{Deserialize, Serialize};
use crate::{
form::{AuthForm, SubspaceForm, TimestampForm},
interest::{CapSelector, CapabilityPack, DelegateTo},
proto::{
data_model::{
self, serde_encoding::SerdeAuthorisedEntry, AuthorisedEntry, Entry, NamespaceId, Path,
SubspaceId,
},
grouping::{self, Area, Range3d},
keys::{NamespaceKind, UserId},
meadowcap::{self, AccessMode, SecretKey},
},
session::{
intents::{serde_encoding::Event, IntentUpdate},
SessionInit,
},
store::traits::{StoreEvent, SubscribeParams},
};
pub type RpcError = serde_error::Error;
pub type RpcResult<T> = std::result::Result<T, RpcError>;
#[allow(missing_docs)]
#[derive(strum::Display, Debug, Serialize, Deserialize)]
#[rpc_requests(message = RpcMessage)]
pub enum Request {
#[rpc(tx = oneshot::Sender<RpcResult<IngestEntrySuccess>>)]
IngestEntry(IngestEntryRequest),
#[rpc(tx = oneshot::Sender<RpcResult<InsertEntrySuccess>>)]
InsertEntry(InsertEntryRequest),
#[rpc(tx = oneshot::Sender<RpcResult<InsertSecretResponse>>)]
InsertSecret(InsertSecretRequest),
#[rpc(tx = mpsc::Sender<RpcResult<GetEntriesResponse>>)]
GetEntries(GetEntriesRequest),
#[rpc(tx = oneshot::Sender<RpcResult<GetEntryResponse>>)]
GetEntry(GetEntryRequest),
#[rpc(tx = oneshot::Sender<RpcResult<CreateNamespaceResponse>>)]
CreateNamespace(CreateNamespaceRequest),
#[rpc(tx = oneshot::Sender<RpcResult<CreateUserResponse>>)]
CreateUser(CreateUserRequest),
#[rpc(tx = oneshot::Sender<RpcResult<DelegateCapsResponse>>)]
DelegateCaps(DelegateCapsRequest),
#[rpc(tx = oneshot::Sender<RpcResult<ImportCapsResponse>>)]
ImportCaps(ImportCapsRequest),
#[rpc(tx = mpsc::Sender<RpcResult<SyncWithPeerResponse>>, rx = mpsc::Receiver<SyncWithPeerUpdate>)]
SyncWithPeer(SyncWithPeerRequest),
#[rpc(tx = mpsc::Sender<RpcResult<StoreEvent>>)]
Subscribe(SubscribeRequest),
#[rpc(tx = oneshot::Sender<RpcResult<EndpointAddr>>)]
Addr(AddrRequest),
#[rpc(tx = oneshot::Sender<RpcResult<()>>)]
AddAddr(AddAddrRequest),
}
#[derive(Debug, Serialize, Deserialize)]
pub struct IngestEntryRequest {
#[serde(with = "data_model::serde_encoding::authorised_entry")]
pub authorised_entry: AuthorisedEntry,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct InsertEntryRequest {
pub entry: FullEntryForm,
pub auth: AuthForm,
}
#[derive(Debug, Serialize, Deserialize)]
pub enum InsertEntrySuccess {
Inserted(#[serde(with = "data_model::serde_encoding::authorised_entry")] AuthorisedEntry),
Obsolete,
}
#[derive(Debug, Serialize, Deserialize)]
pub enum IngestEntrySuccess {
Inserted,
Obsolete,
}
impl InsertEntrySuccess {
pub fn inserted(self) -> Result<AuthorisedEntry, EntryObsoleteError> {
match self {
Self::Inserted(entry) => Ok(entry),
Self::Obsolete => Err(EntryObsoleteError),
}
}
}
#[derive(Debug, thiserror::Error)]
#[error("The entry was not inserted because a newer entry exists.")]
pub struct EntryObsoleteError;
#[derive(Debug, Serialize, Deserialize)]
pub struct InsertSecretRequest {
pub secret: SecretKey,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct InsertSecretResponse;
#[derive(Debug, Serialize, Deserialize)]
pub struct GetEntriesRequest {
pub namespace: NamespaceId,
#[serde(with = "grouping::serde_encoding::range_3d")]
pub range: Range3d,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct GetEntriesResponse(
#[serde(with = "data_model::serde_encoding::authorised_entry")] pub AuthorisedEntry,
);
#[derive(Debug, Serialize, Deserialize)]
pub struct GetEntryRequest {
pub namespace: NamespaceId,
pub subspace: SubspaceId,
#[serde(with = "data_model::serde_encoding::path")]
pub path: Path,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct GetEntryResponse(pub Option<SerdeAuthorisedEntry>);
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateNamespaceRequest {
pub kind: NamespaceKind,
pub owner: UserId,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateNamespaceResponse(pub NamespaceId);
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateUserRequest;
#[derive(Debug, Serialize, Deserialize)]
pub struct CreateUserResponse(pub UserId);
#[derive(Debug, Serialize, Deserialize)]
pub struct DelegateCapsRequest {
pub from: CapSelector,
#[serde(with = "meadowcap::serde_encoding::access_mode")]
pub access_mode: AccessMode,
pub to: DelegateTo,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct DelegateCapsResponse(pub Vec<CapabilityPack>);
#[derive(Debug, Serialize, Deserialize)]
pub struct ImportCapsRequest {
pub caps: Vec<CapabilityPack>,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct ImportCapsResponse;
#[derive(Debug, Serialize, Deserialize)]
pub struct SyncWithPeerRequest {
pub peer: EndpointId,
pub init: SessionInit,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SyncWithPeerUpdate(pub IntentUpdate);
#[derive(Debug, Serialize, Deserialize)]
pub enum SyncWithPeerResponse {
Started,
Event(Event),
}
#[derive(Debug, Serialize, Deserialize)]
pub struct SubscribeRequest {
pub namespace: NamespaceId,
#[serde(with = "grouping::serde_encoding::area")]
pub area: Area,
pub params: SubscribeParams,
pub initial_progress_id: Option<u64>,
}
#[derive(Debug, Serialize, Deserialize)]
pub enum EntryOrForm {
Entry(#[serde(with = "data_model::serde_encoding::entry")] Entry),
Form(FullEntryForm),
}
impl From<EntryOrForm> for crate::form::EntryOrForm {
fn from(value: EntryOrForm) -> Self {
match value {
EntryOrForm::Entry(entry) => Self::Entry(entry),
EntryOrForm::Form(form) => Self::Form(form.into()),
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub struct FullEntryForm {
pub namespace_id: NamespaceId,
pub subspace_id: SubspaceForm,
#[serde(with = "data_model::serde_encoding::path")]
pub path: Path,
pub timestamp: TimestampForm,
pub payload: PayloadForm,
}
impl From<FullEntryForm> for crate::form::EntryForm {
fn from(value: FullEntryForm) -> Self {
Self {
namespace_id: value.namespace_id,
subspace_id: value.subspace_id,
path: value.path,
timestamp: value.timestamp,
payload: value.payload.into(),
}
}
}
#[derive(Debug, Serialize, Deserialize)]
pub enum PayloadForm {
Checked(Hash),
Unchecked(Hash, u64),
}
impl From<PayloadForm> for crate::form::PayloadForm {
fn from(value: PayloadForm) -> Self {
match value {
PayloadForm::Checked(hash) => Self::Hash(hash),
PayloadForm::Unchecked(hash, len) => Self::HashUnchecked(hash, len),
}
}
}
#[derive(Serialize, Deserialize, Debug)]
pub struct AddrRequest;
#[derive(Serialize, Deserialize, Debug)]
pub struct AddAddrRequest {
pub addr: EndpointAddr,
}