add docs and introduce TypedMessage
This commit is contained in:
parent
304fb3592c
commit
ee2949f1b8
|
@ -1,6 +1,6 @@
|
|||
use std::process;
|
||||
|
||||
use kuska_ssb::api::dto::content::Post;
|
||||
use kuska_ssb::api::dto::content::TypedMessage;
|
||||
|
||||
use golgi::error::GolgiError;
|
||||
use golgi::sbot::Sbot;
|
||||
|
@ -11,14 +11,27 @@ async fn run() -> Result<(), GolgiError> {
|
|||
let id = sbot_client.whoami().await?;
|
||||
println!("{}", id);
|
||||
|
||||
let post = Post::new(
|
||||
"glyph from golgi".to_string(),
|
||||
// mentions
|
||||
None,
|
||||
);
|
||||
let name = TypedMessage::About {
|
||||
about: id,
|
||||
name: Some("golgi".to_string()),
|
||||
title: None,
|
||||
branch: None,
|
||||
image: None,
|
||||
description: None,
|
||||
location: None,
|
||||
start_datetime: None,
|
||||
};
|
||||
|
||||
let msg_ref = sbot_client.publish_post(post).await?;
|
||||
println!("{}", msg_ref);
|
||||
let name_msg_ref = sbot_client.publish(name).await?;
|
||||
println!("{}", name_msg_ref);
|
||||
|
||||
let post = TypedMessage::Post {
|
||||
text: "golgi go womp womp".to_string(),
|
||||
mentions: None,
|
||||
};
|
||||
|
||||
let post_msg_ref = sbot_client.publish(post).await?;
|
||||
println!("{}", post_msg_ref);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
|
98
src/error.rs
98
src/error.rs
|
@ -1,37 +1,40 @@
|
|||
/*
|
||||
use async_std::{io::Read, net::TcpStream};
|
||||
use std::fmt::Debug;
|
||||
//! Custom error type for `golgi`.
|
||||
|
||||
use kuska_handshake::async_std::BoxStream;
|
||||
use kuska_sodiumoxide::crypto::sign::ed25519;
|
||||
use kuska_ssb::api::{dto::WhoAmIOut, ApiCaller};
|
||||
use kuska_ssb::discovery;
|
||||
use kuska_ssb::keystore;
|
||||
use kuska_ssb::keystore::OwnedIdentity;
|
||||
use kuska_ssb::rpc::{RecvMsg, RequestNo, RpcReader, RpcWriter};
|
||||
use std::io::Error as IoError;
|
||||
|
||||
type Result<T> = std::result::Result<T, Box<dyn std::error::Error>>;
|
||||
|
||||
pub fn whoami_res_parse(body: &[u8]) -> Result<WhoAmIOut> {
|
||||
Ok(serde_json::from_slice(body)?)
|
||||
}
|
||||
*/
|
||||
use base64::DecodeError;
|
||||
use kuska_handshake::async_std::Error as HandshakeError;
|
||||
use kuska_ssb::api::Error as ApiError;
|
||||
use kuska_ssb::feed::Error as FeedError;
|
||||
use kuska_ssb::rpc::Error as RpcError;
|
||||
use serde_json::Error as JsonError;
|
||||
|
||||
/// A custom error type encapsulating all possible errors for this library.
|
||||
/// `From` implementations are provided for external error types, allowing
|
||||
/// the `?` operator to be used on functions which return `Result<_, GolgiError>`.
|
||||
#[derive(Debug)]
|
||||
pub enum GolgiError {
|
||||
DecodeBase64(base64::DecodeError),
|
||||
/// Failed to decode base64.
|
||||
DecodeBase64(DecodeError),
|
||||
/// IO error with context.
|
||||
Io {
|
||||
source: std::io::Error,
|
||||
/// The underlying IO error.
|
||||
source: IoError,
|
||||
/// Description of the error context.
|
||||
context: String,
|
||||
},
|
||||
Handshake(kuska_handshake::async_std::Error),
|
||||
KuskaApi(kuska_ssb::api::Error),
|
||||
KuskaFeed(kuska_ssb::feed::Error),
|
||||
KuskaRpc(kuska_ssb::rpc::Error),
|
||||
// error message returned from the go-sbot
|
||||
/// Scuttlebutt secret handshake error.
|
||||
Handshake(HandshakeError),
|
||||
/// Kuska SSB API error.
|
||||
Api(ApiError),
|
||||
/// Kuska SSB feed error.
|
||||
Feed(FeedError),
|
||||
/// Kuska SSB RPC error.
|
||||
Rpc(RpcError),
|
||||
/// Go-sbot error.
|
||||
Sbot(String),
|
||||
SerdeJson(serde_json::Error),
|
||||
WhoAmI(String),
|
||||
/// JSON serialization or deserialization error.
|
||||
SerdeJson(JsonError),
|
||||
}
|
||||
|
||||
impl std::error::Error for GolgiError {
|
||||
|
@ -40,12 +43,11 @@ impl std::error::Error for GolgiError {
|
|||
GolgiError::DecodeBase64(ref err) => Some(err),
|
||||
GolgiError::Io { ref source, .. } => Some(source),
|
||||
GolgiError::Handshake(_) => None,
|
||||
GolgiError::KuskaApi(ref err) => Some(err),
|
||||
GolgiError::KuskaFeed(ref err) => Some(err),
|
||||
GolgiError::KuskaRpc(ref err) => Some(err),
|
||||
GolgiError::Api(ref err) => Some(err),
|
||||
GolgiError::Feed(ref err) => Some(err),
|
||||
GolgiError::Rpc(ref err) => Some(err),
|
||||
GolgiError::Sbot(_) => None,
|
||||
GolgiError::SerdeJson(ref err) => Some(err),
|
||||
GolgiError::WhoAmI(_) => None,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -57,50 +59,50 @@ impl std::fmt::Display for GolgiError {
|
|||
GolgiError::DecodeBase64(_) => write!(f, "Failed to decode base64"),
|
||||
GolgiError::Io { ref context, .. } => write!(f, "IO error: {}", context),
|
||||
GolgiError::Handshake(ref err) => write!(f, "{}", err),
|
||||
GolgiError::KuskaApi(_) => write!(f, "SSB API failure"),
|
||||
GolgiError::KuskaFeed(_) => write!(f, "SSB feed error"),
|
||||
GolgiError::Api(ref err) => write!(f, "SSB API failure: {}", err),
|
||||
GolgiError::Feed(ref err) => write!(f, "SSB feed error: {}", err),
|
||||
// TODO: improve this variant with a context message
|
||||
// then have the core display msg be: "SSB RPC error: {}", context
|
||||
GolgiError::KuskaRpc(_) => write!(f, "SSB RPC failure"),
|
||||
GolgiError::Rpc(ref err) => write!(f, "SSB RPC failure: {}", err),
|
||||
GolgiError::Sbot(ref err) => write!(f, "Sbot returned an error response: {}", err),
|
||||
GolgiError::SerdeJson(_) => write!(f, "Failed to serialize JSON slice"),
|
||||
GolgiError::WhoAmI(ref err) => write!(f, "{}", err),
|
||||
//GolgiError::WhoAmI(ref err) => write!(f, "{}", err),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl From<base64::DecodeError> for GolgiError {
|
||||
fn from(err: base64::DecodeError) -> Self {
|
||||
impl From<DecodeError> for GolgiError {
|
||||
fn from(err: DecodeError) -> Self {
|
||||
GolgiError::DecodeBase64(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<kuska_handshake::async_std::Error> for GolgiError {
|
||||
fn from(err: kuska_handshake::async_std::Error) -> Self {
|
||||
impl From<HandshakeError> for GolgiError {
|
||||
fn from(err: HandshakeError) -> Self {
|
||||
GolgiError::Handshake(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<kuska_ssb::api::Error> for GolgiError {
|
||||
fn from(err: kuska_ssb::api::Error) -> Self {
|
||||
GolgiError::KuskaApi(err)
|
||||
impl From<ApiError> for GolgiError {
|
||||
fn from(err: ApiError) -> Self {
|
||||
GolgiError::Api(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<kuska_ssb::feed::Error> for GolgiError {
|
||||
fn from(err: kuska_ssb::feed::Error) -> Self {
|
||||
GolgiError::KuskaFeed(err)
|
||||
impl From<FeedError> for GolgiError {
|
||||
fn from(err: FeedError) -> Self {
|
||||
GolgiError::Feed(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<kuska_ssb::rpc::Error> for GolgiError {
|
||||
fn from(err: kuska_ssb::rpc::Error) -> Self {
|
||||
GolgiError::KuskaRpc(err)
|
||||
impl From<RpcError> for GolgiError {
|
||||
fn from(err: RpcError) -> Self {
|
||||
GolgiError::Rpc(err)
|
||||
}
|
||||
}
|
||||
|
||||
impl From<serde_json::Error> for GolgiError {
|
||||
fn from(err: serde_json::Error) -> Self {
|
||||
impl From<JsonError> for GolgiError {
|
||||
fn from(err: JsonError) -> Self {
|
||||
GolgiError::SerdeJson(err)
|
||||
}
|
||||
}
|
||||
|
|
26
src/lib.rs
26
src/lib.rs
|
@ -1,4 +1,28 @@
|
|||
// #![warn(missing_docs)]
|
||||
#![warn(missing_docs)]
|
||||
|
||||
//! # golgi
|
||||
//!
|
||||
//! _The Golgi complex (aka. Golgi apparatus or Golgi body) packages proteins into membrane-bound vesicles inside the cell before the vesicles are sent to their destination._
|
||||
//!
|
||||
//! -----
|
||||
//!
|
||||
//! Golgi is an experimental Scuttlebutt client which uses the [kuska-ssb](https://github.com/Kuska-ssb) libraries and aims to provide a high-level API for interacting with an sbot instance. Development efforts are currently oriented towards [go-sbot](https://github.com/cryptoscope/ssb) interoperability.
|
||||
//!
|
||||
//! ## Example Usage
|
||||
//!
|
||||
//! ```rust
|
||||
//! use golgi::GolgiError;
|
||||
//! use golgi::sbot::Sbot;
|
||||
//!
|
||||
//! pub async fn run() -> Result<(), GolgiError> {
|
||||
//! let mut sbot_client = Sbot::init(None, None).await?;
|
||||
//!
|
||||
//! let id = sbot_client.whoami().await?;
|
||||
//! println!("{}", id);
|
||||
//!
|
||||
//! Ok(())
|
||||
//! }
|
||||
//! ```
|
||||
|
||||
pub mod error;
|
||||
pub mod sbot;
|
||||
|
|
31
src/sbot.rs
31
src/sbot.rs
|
@ -1,10 +1,16 @@
|
|||
//! Sbot type and associated methods.
|
||||
|
||||
use async_std::net::TcpStream;
|
||||
|
||||
use kuska_handshake::async_std::BoxStream;
|
||||
use kuska_sodiumoxide::crypto::{auth, sign::ed25519};
|
||||
use kuska_ssb::{
|
||||
api::{
|
||||
dto::{content::Post, CreateHistoryStreamIn},
|
||||
dto::{
|
||||
//content::{About, Post},
|
||||
content::TypedMessage,
|
||||
CreateHistoryStreamIn,
|
||||
},
|
||||
ApiCaller,
|
||||
},
|
||||
discovery, keystore,
|
||||
|
@ -15,6 +21,8 @@ use kuska_ssb::{
|
|||
use crate::error::GolgiError;
|
||||
use crate::utils;
|
||||
|
||||
/// The Scuttlebutt identity, keys and configuration parameters for connecting to a local sbot
|
||||
/// instance, as well as handles for calling RPC methods and receiving responses.
|
||||
pub struct Sbot {
|
||||
id: String,
|
||||
public_key: ed25519::PublicKey,
|
||||
|
@ -27,6 +35,9 @@ pub struct Sbot {
|
|||
}
|
||||
|
||||
impl Sbot {
|
||||
/// Initiate a connection with an sbot instance. Define the IP address, port and network key
|
||||
/// for the sbot, then retrieve the public key, private key (secret) and identity from the
|
||||
/// `.ssb-go/secret` file. Open a TCP stream to the sbot and perform the secret handshake. If successful, create a box stream and split it into a writer and reader. Return RPC handles to the sbot as part of the `struct` output.
|
||||
pub async fn init(ip_port: Option<String>, net_id: Option<String>) -> Result<Sbot, GolgiError> {
|
||||
let address;
|
||||
if ip_port.is_none() {
|
||||
|
@ -80,6 +91,7 @@ impl Sbot {
|
|||
})
|
||||
}
|
||||
|
||||
/// Call the `whoami` RPC method and return an `id`.
|
||||
pub async fn whoami(&mut self) -> Result<String, GolgiError> {
|
||||
let req_id = self.client.whoami_req_send().await?;
|
||||
|
||||
|
@ -88,15 +100,32 @@ impl Sbot {
|
|||
.map(|whoami| whoami.id)
|
||||
}
|
||||
|
||||
/// Call the `publish` RPC method and return a message reference.
|
||||
///
|
||||
/// # Arguments
|
||||
///
|
||||
/// * `msg` - A `TypedMessage` `enum` whose variants include `Pub`, `Post`, `Contact`, `About`,
|
||||
/// `Channel` and `Vote`. See the `kuska_ssb` documentation for further details such as field
|
||||
/// names and accepted values for each variant.
|
||||
pub async fn publish(&mut self, msg: TypedMessage) -> Result<String, GolgiError> {
|
||||
let req_id = self.client.publish_req_send(msg).await?;
|
||||
|
||||
utils::get_async(&mut self.rpc_reader, req_id, utils::publish_res_parse).await
|
||||
}
|
||||
|
||||
/*
|
||||
pub async fn publish_post(&mut self, post: Post) -> Result<String, GolgiError> {
|
||||
let req_id = self.client.publish_req_send(post).await?;
|
||||
|
||||
utils::get_async(&mut self.rpc_reader, req_id, utils::publish_res_parse).await
|
||||
}
|
||||
*/
|
||||
|
||||
/// Call the `createHistoryStream` RPC method and print the output.
|
||||
async fn create_history_stream(&mut self, id: String) -> Result<(), GolgiError> {
|
||||
let args = CreateHistoryStreamIn::new(id);
|
||||
let req_id = self.client.create_history_stream_req_send(&args).await?;
|
||||
// TODO: we should return a vector of messages instead of printing them
|
||||
utils::print_source_until_eof(&mut self.rpc_reader, req_id, utils::feed_res_parse).await
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue