A Rust project for overlaying your stream.place chat in OBS

refactor: split into smaller files in lib

ethanholz.com 98e2c385 d31de52a

verified
+72 -68
+23
src/lib/chat_message.rs
··· 1 + use maud::{Markup, Render, html}; 2 + use serde::{Deserialize, Serialize}; 3 + 4 + #[derive(Debug, Deserialize, Serialize)] 5 + pub struct ChatMessage { 6 + handle: String, 7 + text: String, 8 + } 9 + 10 + impl ChatMessage { 11 + pub fn new(handle: String, text: String) -> Self { 12 + Self { handle, text } 13 + } 14 + } 15 + 16 + impl Render for ChatMessage { 17 + fn render(&self) -> Markup { 18 + html! { 19 + div class="handle" { (self.handle) }; 20 + div class="message" { (self.text) }; 21 + } 22 + } 23 + }
+44
src/lib/handle_resolver.rs
··· 1 + use jacquard::{CowStr, prelude::IdentityResolver, types::did::Did}; 2 + use jacquard_identity::{ 3 + JacquardResolver, 4 + resolver::{PlcSource, ResolverOptions}, 5 + }; 6 + 7 + pub struct JacquardHandleResolver { 8 + resolver: JacquardResolver, 9 + } 10 + 11 + impl JacquardHandleResolver { 12 + pub fn new() -> Self { 13 + let opts = ResolverOptions { 14 + plc_source: PlcSource::slingshot_default(), 15 + public_fallback_for_handle: true, 16 + validate_doc_id: true, 17 + ..Default::default() 18 + }; 19 + Self { 20 + resolver: JacquardResolver::new(reqwest::Client::new(), opts).with_system_dns(), 21 + } 22 + } 23 + } 24 + 25 + impl Default for JacquardHandleResolver { 26 + fn default() -> Self { 27 + Self::new() 28 + } 29 + } 30 + 31 + #[async_trait::async_trait] 32 + impl HandleResolver for JacquardHandleResolver { 33 + async fn resolve(&self, did: &Did<'_>) -> miette::Result<CowStr<'static>> { 34 + // DID Doc 35 + let out = self.resolver.resolve_did_doc_owned(did).await?; 36 + // Get first handle 37 + Ok(out.also_known_as.unwrap()[0].clone()) 38 + } 39 + } 40 + 41 + #[async_trait::async_trait] 42 + pub trait HandleResolver { 43 + async fn resolve(&self, did: &Did<'_>) -> miette::Result<CowStr<'static>>; 44 + }
+2 -44
src/lib/lib.rs
··· 1 - use jacquard::{CowStr, prelude::IdentityResolver, types::did::Did}; 2 - use jacquard_identity::{ 3 - JacquardResolver, 4 - resolver::{PlcSource, ResolverOptions}, 5 - }; 6 - 7 - pub struct JacquardHandleResolver { 8 - resolver: JacquardResolver, 9 - } 10 - 11 - impl JacquardHandleResolver { 12 - pub fn new() -> Self { 13 - let opts = ResolverOptions { 14 - plc_source: PlcSource::slingshot_default(), 15 - public_fallback_for_handle: true, 16 - validate_doc_id: true, 17 - ..Default::default() 18 - }; 19 - Self { 20 - resolver: JacquardResolver::new(reqwest::Client::new(), opts).with_system_dns(), 21 - } 22 - } 23 - } 24 - 25 - impl Default for JacquardHandleResolver { 26 - fn default() -> Self { 27 - Self::new() 28 - } 29 - } 30 - 31 - #[async_trait::async_trait] 32 - impl HandleResolver for JacquardHandleResolver { 33 - async fn resolve(&self, did: &Did<'_>) -> miette::Result<CowStr<'static>> { 34 - // DID Doc 35 - let out = self.resolver.resolve_did_doc_owned(did).await?; 36 - // Get first handle 37 - Ok(out.also_known_as.unwrap()[0].clone()) 38 - } 39 - } 40 - 41 - #[async_trait::async_trait] 42 - pub trait HandleResolver { 43 - async fn resolve(&self, did: &Did<'_>) -> miette::Result<CowStr<'static>>; 44 - } 1 + pub mod chat_message; 2 + pub mod handle_resolver;
+3 -24
src/main.rs
··· 5 5 }; 6 6 use jacquard_api::place_stream::chat::message::{Message, MessageRecord}; 7 7 use jacquard_common::xrpc::subscription::TungsteniteSubscriptionClient; 8 - use maud::{Markup, Render, html}; 8 + use maud::Render; 9 9 use miette::IntoDiagnostic; 10 10 use n0_future::StreamExt; 11 - use serde::{Deserialize, Serialize}; 12 - use streamplace_chat_lib::{HandleResolver, JacquardHandleResolver}; 11 + use streamplace_chat_lib::chat_message::ChatMessage; 12 + use streamplace_chat_lib::handle_resolver::{HandleResolver, JacquardHandleResolver}; 13 13 use url::Url; 14 - 15 - #[derive(Debug, Deserialize, Serialize)] 16 - struct ChatMessage { 17 - handle: String, 18 - text: String, 19 - } 20 - 21 - impl ChatMessage { 22 - fn new(handle: String, text: String) -> Self { 23 - Self { handle, text } 24 - } 25 - } 26 - 27 - impl Render for ChatMessage { 28 - fn render(&self) -> Markup { 29 - html! { 30 - div class="handle" { (self.handle) }; 31 - div class="message" { (self.text) }; 32 - } 33 - } 34 - } 35 14 36 15 async fn handle_message<R>(msg: &JetstreamMessage<'_>, resolver: &R) -> Option<String> 37 16 where