Working create_history_stream
This commit is contained in:
parent
58d133b5c8
commit
8ad65f785d
|
@ -0,0 +1,97 @@
|
||||||
|
use std::process;
|
||||||
|
|
||||||
|
use golgi::error::GolgiError;
|
||||||
|
|
||||||
|
use golgi::sbot::Sbot;
|
||||||
|
use async_std::stream::StreamExt;
|
||||||
|
use futures::pin_mut;
|
||||||
|
|
||||||
|
|
||||||
|
async fn run() -> Result<(), GolgiError> {
|
||||||
|
let mut sbot_client = Sbot::init(None, None).await?;
|
||||||
|
|
||||||
|
let id = sbot_client.whoami().await?;
|
||||||
|
println!("{}", id);
|
||||||
|
//
|
||||||
|
// let name = SsbMessageContent::About {
|
||||||
|
// about: id,
|
||||||
|
// name: Some("golgi".to_string()),
|
||||||
|
// title: None,
|
||||||
|
// branch: None,
|
||||||
|
// image: None,
|
||||||
|
// description: None,
|
||||||
|
// location: None,
|
||||||
|
// start_datetime: None,
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// let name_msg_ref = sbot_client.publish(name).await?;
|
||||||
|
// println!("{}", name_msg_ref);
|
||||||
|
//
|
||||||
|
// let post = SsbMessageContent::Post {
|
||||||
|
// text: "golgi go womp womp".to_string(),
|
||||||
|
// mentions: None,
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// let post_msg_ref = sbot_client.publish(post).await?;
|
||||||
|
// println!("{}", post_msg_ref);
|
||||||
|
//
|
||||||
|
// let post_msg_ref = sbot_client.publish_description("this is a description").await?;
|
||||||
|
// println!("description: {}", post_msg_ref);
|
||||||
|
|
||||||
|
let author = "@L/z54cbc8V1kL1/MiBhpEKuN3QJkSoZYNaukny3ghIs=.ed25519";
|
||||||
|
|
||||||
|
// let query = SubsetQuery::Author{
|
||||||
|
// op: "author".to_string(),
|
||||||
|
// feed: author
|
||||||
|
// };
|
||||||
|
//
|
||||||
|
// let kvts = sbot_client.get_subset(query).await?;
|
||||||
|
//
|
||||||
|
// for kvt in kvts {
|
||||||
|
// println!("kvt: {:?}", kvt);
|
||||||
|
// }
|
||||||
|
|
||||||
|
// let about_messages = sbot_client.get_about_messages(author).await?;
|
||||||
|
// for msg in about_messages {
|
||||||
|
// println!("msg: {:?}", msg);
|
||||||
|
// }
|
||||||
|
//
|
||||||
|
// sbot_client.publish_name("this is my new name").await?;
|
||||||
|
// let name = sbot_client.get_name(author).await?;
|
||||||
|
// println!("name: {:?}", name);
|
||||||
|
//
|
||||||
|
// // sbot_client.publish_description("this is test description 99").await?;
|
||||||
|
//
|
||||||
|
// let description = sbot_client.get_description(author).await?;
|
||||||
|
// println!("desc: {:?}", description);
|
||||||
|
|
||||||
|
//
|
||||||
|
// let description2 = sbot_client.get_latest_about_message(author, "description").await?;
|
||||||
|
// println!("desc2: {:?}", description2);
|
||||||
|
|
||||||
|
let mut history_stream = sbot_client.create_history_stream(author.to_string()).await?;
|
||||||
|
pin_mut!(history_stream); // needed for iteration
|
||||||
|
|
||||||
|
while let Some(res) = history_stream.next().await {
|
||||||
|
match res {
|
||||||
|
Ok(value) => {
|
||||||
|
println!("value: {:?}", value);
|
||||||
|
},
|
||||||
|
Err(err) => {
|
||||||
|
println!("err: {:?}", err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
println!("exit loop");
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
|
#[async_std::main]
|
||||||
|
async fn main() {
|
||||||
|
if let Err(e) = run().await {
|
||||||
|
eprintln!("Application error: {}", e);
|
||||||
|
process::exit(1);
|
||||||
|
}
|
||||||
|
}
|
70
src/sbot.rs
70
src/sbot.rs
|
@ -228,58 +228,68 @@ impl Sbot {
|
||||||
self.get_latest_about_message(ssb_id, "description").await
|
self.get_latest_about_message(ssb_id, "description").await
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Call the `createHistoryStream` RPC method and return a vector
|
/// Call the `createHistoryStream` RPC method
|
||||||
/// of SsbMessageValue.
|
/// and return a Stream of Result<SsbMessageValue, GolgiError>
|
||||||
pub async fn create_history_stream(
|
pub async fn create_history_stream<'a>(
|
||||||
&mut self,
|
&'a mut self,
|
||||||
id: String,
|
id: String,
|
||||||
) -> Result<i32, GolgiError> {
|
) -> Result<impl Stream<Item = Result<SsbMessageValue, GolgiError>> + 'a, GolgiError> {
|
||||||
let args = CreateHistoryStreamIn::new(id);
|
let args = CreateHistoryStreamIn::new(id);
|
||||||
let req_id = self.client.create_history_stream_req_send(&args).await?;
|
let req_id = self.client.create_history_stream_req_send(&args).await?;
|
||||||
let source_stream = self.get_source_stream(req_id, utils::ssb_message_res_parse);
|
let history_stream = self.get_source_stream(req_id, utils::ssb_message_res_parse);
|
||||||
pin_mut!(source_stream); // needed for iteration
|
Ok(history_stream)
|
||||||
|
|
||||||
while let Some(res) = source_stream.next().await {
|
|
||||||
match res {
|
|
||||||
Ok(value) => {
|
|
||||||
println!("value: {:?}", value);
|
|
||||||
},
|
|
||||||
Err(err) => {
|
|
||||||
println!("err: {:?}", err);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
/// Takes in an rpc request number, and a handling function (parsing results of type T),
|
||||||
println!("exit loop");
|
/// and produces an async_std::stream::Stream
|
||||||
Ok(2)
|
/// of results of type T where the handling functions is called
|
||||||
// utils::get_source_until_eof(&mut self.rpc_reader, req_id, utils::ssb_message_res_parse).await
|
/// on all rpc_reader responses which match the request number
|
||||||
}
|
///
|
||||||
|
/// # Arguments
|
||||||
pub fn get_source_stream<'a, F, T>(&'a mut self, req_no: RequestNo, f: F) -> impl Stream<Item = Result<RequestNo, GolgiError>> + 'a
|
///
|
||||||
|
/// * `req_no` - A `RequestNo` of the response to listen for
|
||||||
|
/// * `f` - A function which takes in an array of u8 and returns a Result<T, GolgiError>.
|
||||||
|
/// This is a function which parses the response from the RpcReader. T is a generic type,
|
||||||
|
/// so this parse function can return multiple possible types (String, json, custom struct etc.)
|
||||||
|
pub fn get_source_stream<'a, F, T>(&'a mut self, req_no: RequestNo, f: F) -> impl Stream<Item = Result<T, GolgiError>> + 'a
|
||||||
where
|
where
|
||||||
F: Fn(&[u8]) -> Result<T, GolgiError> + 'a,
|
F: Fn(&[u8]) -> Result<T, GolgiError> + 'a,
|
||||||
T: Debug + serde::Deserialize<'a>,
|
T: Debug + serde::Deserialize<'a> + 'a,
|
||||||
{
|
{
|
||||||
let s = stream! {
|
// we use the async_stream::stream macro to allow for creating a stream which calls async functions
|
||||||
|
// see https://users.rust-lang.org/t/how-to-create-async-std-stream-which-calls-async-function-in-poll-next/69760
|
||||||
|
let source_stream = stream! {
|
||||||
loop {
|
loop {
|
||||||
|
// get the next message from the rpc_reader
|
||||||
let (id, msg) = &self.rpc_reader.recv().await?;
|
let (id, msg) = &self.rpc_reader.recv().await?;
|
||||||
let x : i32 = id.clone();
|
let x : i32 = id.clone();
|
||||||
|
// check if the next message from rpc_reader matches the req_no we are looking for
|
||||||
|
// if it matches, then this rpc response is for the given request
|
||||||
|
// and if it doesn't match, then we ignore it
|
||||||
if x == req_no {
|
if x == req_no {
|
||||||
match msg {
|
match msg {
|
||||||
RecvMsg::RpcResponse(_type, body) => {
|
RecvMsg::RpcResponse(_type, body) => {
|
||||||
let display = f(&body)?;
|
// parse an item of type T from the message body using the provided
|
||||||
println!("display: {:?}", display);
|
// function for parsing
|
||||||
yield Ok(x)
|
let item = f(&body)?;
|
||||||
|
// return Ok(item) as the next value in the stream
|
||||||
|
yield Ok(item)
|
||||||
}
|
}
|
||||||
RecvMsg::ErrorResponse(message) => {
|
RecvMsg::ErrorResponse(message) => {
|
||||||
|
// if an error is received
|
||||||
|
// return an Err(err) as the next value in the stream
|
||||||
yield Err(GolgiError::Sbot(message.to_string()));
|
yield Err(GolgiError::Sbot(message.to_string()));
|
||||||
}
|
}
|
||||||
|
// if we find a CancelStreamResponse
|
||||||
|
// this is the end of the stream
|
||||||
RecvMsg::CancelStreamRespose() => break,
|
RecvMsg::CancelStreamRespose() => break,
|
||||||
_ => break
|
// if we find an unknown response, we just continue the loop
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
s
|
// finally return the stream object
|
||||||
|
source_stream
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue