Skip to main content

freenet_stdlib/
client_api.rs

1//! A node client API. Intended to be used from applications (web or otherwise) using the
2//! node capabilities to execute contract, delegate, etc. instructions and communicating
3//! over the network.
4//!
5//! Communication, independent of the transport, revolves around the [`ClientRequest`]
6//! and [`HostResponse`] types.
7//!
8//! Currently the clients available are:
9//! - `websocket`:
10//!   - `regular` (native): Using TCP transport directly, for native applications programmed in Rust.
11//!   - `browser` (wasm): Via wasm-bindgen (and by extension web-sys).
12//!     (In order to use this client from JS/Typescript refer to the Typescript std lib).
13mod client_events;
14
15#[cfg(all(any(unix, windows), feature = "net"))]
16mod regular;
17#[cfg(all(any(unix, windows), feature = "net"))]
18pub use regular::*;
19
20#[cfg(all(target_family = "wasm", feature = "net"))]
21mod browser;
22#[cfg(all(target_family = "wasm", feature = "net"))]
23pub use browser::*;
24
25#[cfg(feature = "net")]
26pub mod streaming;
27
28pub use client_events::*;
29
30#[cfg(feature = "net")]
31type HostResult = Result<HostResponse, ClientError>;
32
33#[derive(thiserror::Error, Debug)]
34#[non_exhaustive]
35pub enum Error {
36    #[error(transparent)]
37    Deserialization(#[from] bincode::Error),
38    #[error("channel closed")]
39    ChannelClosed,
40    #[cfg(all(any(unix, windows), feature = "net"))]
41    #[error(transparent)]
42    ConnectionError(#[from] tokio_tungstenite::tungstenite::Error),
43    #[cfg(all(target_family = "wasm", feature = "net"))]
44    #[error("request error: {0}")]
45    ConnectionError(serde_json::Value),
46    #[error("connection closed")]
47    ConnectionClosed,
48    #[error("unhandled error: {0}")]
49    OtherError(Box<dyn std::error::Error + Send + Sync>),
50}
51
52pub trait TryFromFbs<T>: Sized {
53    fn try_decode_fbs(value: T) -> Result<Self, WsApiError>;
54}
55
56#[derive(thiserror::Error, Debug)]
57#[non_exhaustive]
58pub enum WsApiError {
59    #[error("Unsupported contract version")]
60    UnsupportedContractVersion,
61    #[error("Failed unpacking contract container")]
62    UnpackingContractContainerError(Box<dyn std::error::Error + Send + Sync + 'static>),
63    #[error("Failed decoding message from client request: {cause}")]
64    DeserError { cause: String },
65}
66
67impl WsApiError {
68    pub fn deserialization(cause: String) -> Self {
69        Self::DeserError { cause }
70    }
71
72    pub fn into_fbs_bytes(self) -> Vec<u8> {
73        use crate::generated::host_response::{
74            finish_host_response_buffer, Error, ErrorArgs, HostResponse, HostResponseArgs,
75            HostResponseType,
76        };
77        let mut builder = flatbuffers::FlatBufferBuilder::new();
78        let as_msg = format!("{self}");
79        let msg_offset = builder.create_string(&as_msg);
80        let err_offset = Error::create(
81            &mut builder,
82            &ErrorArgs {
83                msg: Some(msg_offset),
84            },
85        );
86        let res = HostResponse::create(
87            &mut builder,
88            &HostResponseArgs {
89                response_type: HostResponseType::Error,
90                response: Some(err_offset.as_union_value()),
91            },
92        );
93        finish_host_response_buffer(&mut builder, res);
94        builder.finished_data().to_vec()
95    }
96}