golgi/examples/streams.rs

162 lines
5.1 KiB
Rust
Raw Normal View History

2022-01-04 19:09:49 +00:00
use std::process;
2022-01-05 18:58:48 +00:00
use async_std::stream::StreamExt;
2022-02-15 08:26:51 +00:00
use futures::TryStreamExt;
2022-01-04 19:09:49 +00:00
2022-02-08 09:54:21 +00:00
use golgi::{
2022-02-16 12:16:57 +00:00
api::get_subset::{SubsetQuery, SubsetQueryOptions},
2022-02-08 09:54:21 +00:00
messages::{SsbMessageContentType, SsbMessageValue},
sbot::Keystore,
2022-02-08 09:54:21 +00:00
GolgiError, Sbot,
};
2022-01-04 19:09:49 +00:00
2022-02-15 08:26:51 +00:00
// Golgi is an asynchronous library so we must call it from within an
// async function. The `GolgiError` type encapsulates all possible
// error variants for the library.
2022-01-04 19:09:49 +00:00
async fn run() -> Result<(), GolgiError> {
// Attempt to initialise a connection to an sbot instance using the
// secret file at the Patchwork path and the default IP address, port
// and network key (aka. capabilities key).
let mut sbot_client = Sbot::init(Keystore::Patchwork, None, None).await?;
2022-01-04 19:09:49 +00:00
2022-02-15 08:26:51 +00:00
// Call the `whoami` RPC method to retrieve the public key for the sbot
// identity. This is our 'local' public key.
2022-01-04 19:09:49 +00:00
let id = sbot_client.whoami().await?;
2022-02-15 08:26:51 +00:00
// Print the public key (identity) to `stdout`.
2022-01-05 20:08:51 +00:00
println!("whoami: {}", id);
2022-01-04 19:09:49 +00:00
2022-01-05 20:08:51 +00:00
let author = id.clone();
2022-01-04 19:09:49 +00:00
2022-02-16 12:16:57 +00:00
/* HISTORY STREAM EXAMPLE */
2022-02-15 08:26:51 +00:00
// Create an ordered stream of all messages authored by the `author`
// identity.
2022-01-05 18:58:48 +00:00
let history_stream = sbot_client
.create_history_stream(author.to_string())
.await?;
2022-01-04 19:09:49 +00:00
2022-02-15 08:26:51 +00:00
// Pin the stream to the stack to allow polling of the `future`.
futures::pin_mut!(history_stream);
2022-01-04 19:58:08 +00:00
println!("looping through stream");
2022-02-15 08:26:51 +00:00
// Iterate through each element in the stream and match on the `Result`.
// In this case, each element has type `Result<SsbMessageValue, GolgiError>`.
2022-01-04 19:09:49 +00:00
while let Some(res) = history_stream.next().await {
match res {
Ok(value) => {
2022-02-15 08:26:51 +00:00
// Print the `SsbMessageValue` of this element to `stdout`.
2022-01-04 19:09:49 +00:00
println!("value: {:?}", value);
2022-01-05 18:58:48 +00:00
}
2022-01-04 19:09:49 +00:00
Err(err) => {
2022-02-15 08:26:51 +00:00
// Print the `GolgiError` of this element to `stderr`.
eprintln!("err: {:?}", err);
2022-01-04 19:09:49 +00:00
}
}
2022-01-04 19:58:08 +00:00
}
2022-02-15 08:26:51 +00:00
2022-01-04 19:58:08 +00:00
println!("reached end of stream");
2022-01-04 19:09:49 +00:00
2022-02-15 08:26:51 +00:00
// Create an ordered stream of all messages authored by the `author`
// identity.
2022-01-05 18:58:48 +00:00
let history_stream = sbot_client
.create_history_stream(author.to_string())
.await?;
2022-02-15 08:26:51 +00:00
// Collect the stream elements into a `Vec<SsbMessageValue>` using
// `try_collect`. A `GolgiError` will be returned from the `run`
// function if any element contains an error.
2022-01-05 18:58:48 +00:00
let results: Vec<SsbMessageValue> = history_stream.try_collect().await?;
2022-02-15 08:26:51 +00:00
// Loop through the `SsbMessageValue` elements, printing each one
// to `stdout`.
2022-01-05 15:58:07 +00:00
for x in results {
println!("x: {:?}", x);
}
2022-02-15 08:26:51 +00:00
// Create an ordered stream of all messages authored by the `author`
// identity.
2022-01-05 18:58:48 +00:00
let history_stream = sbot_client
.create_history_stream(author.to_string())
.await?;
2022-02-15 08:26:51 +00:00
// Iterate through the elements in the stream and use `map` to convert
// each `SsbMessageValue` element into a tuple of
// `(String, SsbMessageContentType)`. This is an example of stream
// conversion.
2022-01-05 18:58:48 +00:00
let type_stream = history_stream.map(|msg| match msg {
Ok(val) => {
let message_type = val.get_message_type()?;
let tuple: (String, SsbMessageContentType) = (val.signature, message_type);
Ok(tuple)
2022-01-05 15:58:07 +00:00
}
2022-01-05 18:58:48 +00:00
Err(err) => Err(err),
2022-01-05 15:58:07 +00:00
});
2022-02-15 08:26:51 +00:00
// Pin the stream to the stack to allow polling of the `future`.
futures::pin_mut!(type_stream);
2022-01-05 15:58:07 +00:00
println!("looping through type stream");
2022-02-15 08:26:51 +00:00
// Iterate through each element in the stream and match on the `Result`.
// In this case, each element has type
// `Result<(String, SsbMessageContentType), GolgiError>`.
2022-01-05 15:58:07 +00:00
while let Some(res) = type_stream.next().await {
match res {
Ok(value) => {
println!("value: {:?}", value);
2022-01-05 18:58:48 +00:00
}
2022-01-05 15:58:07 +00:00
Err(err) => {
println!("err: {:?}", err);
}
}
}
2022-02-15 08:26:51 +00:00
2022-01-05 15:58:07 +00:00
println!("reached end of type stream");
2022-02-16 12:16:57 +00:00
/* SUBSET STREAM EXAMPLE */
// Compose a subset query for `post` message types.
let post_query = SubsetQuery::Type {
op: "type".to_string(),
string: "post".to_string(),
};
// Define the options for the query.
let post_query_opts = SubsetQueryOptions {
descending: Some(true),
keys: None,
page_limit: Some(5),
};
// Return 5 `post` type messages from any author in descending order.
let query_stream = sbot_client
.get_subset_stream(post_query, Some(post_query_opts))
.await?;
println!("looping through post query stream");
// Iterate over the stream and pretty-print each returned message
// value while ignoring any errors.
query_stream.for_each(|msg| match msg {
Ok(val) => println!("{:#?}", val),
Err(_) => (),
});
println!("reached end of post query stream");
2022-01-04 20:00:25 +00:00
Ok(())
2022-01-04 19:09:49 +00:00
}
2022-02-15 08:26:51 +00:00
// Enable an async main function and execute the `run()` function,
// catching any errors and printing them to `stderr` before exiting the
// process.
2022-01-04 19:09:49 +00:00
#[async_std::main]
async fn main() {
if let Err(e) = run().await {
eprintln!("Application error: {}", e);
process::exit(1);
}
}