#![doc(alias = "TMI")]
use crate::types;
use serde::{Deserialize, Serialize};
#[cfg(all(feature = "client", feature = "tmi"))]
#[cfg_attr(nightly, doc(cfg(all(feature = "client", feature = "tmi"))))] #[derive(Clone)]
pub struct TmiClient<'a, C: crate::HttpClient<'a>> {
pub(crate) client: C,
_pd: std::marker::PhantomData<&'a ()>,
}
#[cfg(all(feature = "tmi", feature = "client"))]
impl<'a, C: crate::HttpClient<'a>> TmiClient<'a, C> {
pub fn with_client(client: C) -> TmiClient<'a, C> {
TmiClient {
client,
_pd: std::marker::PhantomData::default(),
}
}
pub fn new() -> TmiClient<'a, C>
where C: crate::client::ClientDefault<'a> {
let client = C::default_client();
TmiClient::with_client(client)
}
pub fn clone_client(&self) -> C
where C: Clone {
self.client.clone()
}
pub fn get_client(&self) -> &C { &self.client }
pub async fn get_chatters(
&'a self,
broadcaster: &types::UserNameRef,
) -> Result<GetChatters, RequestError<<C as crate::HttpClient<'a>>::Error>> {
let url = format!(
"{}{}{}{}",
crate::TWITCH_TMI_URL.as_str(),
"group/user/",
broadcaster.as_str().replace('#', "").to_ascii_lowercase(),
"/chatters"
);
let req = http::Request::builder()
.uri(url)
.body(Vec::with_capacity(0).into())?;
let resp = self
.client
.req(req)
.await
.map_err(|e| RequestError::RequestError(Box::new(e)))?;
let (parts, mut body) = resp.into_parts();
let resp = http::Response::from_parts(parts, hyper::body::to_bytes(&mut body).await?);
let text = std::str::from_utf8(&resp.body())
.map_err(|e| RequestError::Utf8Error(resp.body().to_vec(), e))?;
crate::parse_json(text, true).map_err(Into::into)
}
}
#[cfg(feature = "client")]
impl<C: crate::HttpClient<'static> + crate::client::ClientDefault<'static>> Default
for TmiClient<'static, C>
{
fn default() -> Self { Self::new() }
}
#[derive(Debug, Serialize, Deserialize)]
pub struct GetChatters {
pub chatter_count: u64,
pub chatters: Chatters,
}
#[derive(Debug, Serialize, Deserialize)]
pub struct Chatters {
pub broadcaster: Vec<types::Nickname>,
pub vips: Vec<types::Nickname>,
pub moderators: Vec<types::Nickname>,
pub staff: Vec<types::Nickname>,
pub admins: Vec<types::Nickname>,
pub global_mods: Vec<types::Nickname>,
pub viewers: Vec<types::Nickname>,
}
pub type UserId = u64;
#[derive(thiserror::Error, Debug, displaydoc::Display)]
pub enum RequestError<RE: std::error::Error + Send + Sync + 'static> {
HttpError(#[from] http::Error),
HyperError(#[from] hyper::Error),
DeserializeError(#[from] crate::DeserError),
RequestError(#[from] Box<RE>),
Utf8Error(Vec<u8>, std::str::Utf8Error),
}