use super::*;
use helix::RequestGet;
#[derive(PartialEq, Eq, Deserialize, Serialize, Clone, Debug)]
#[cfg_attr(feature = "typed-builder", derive(typed_builder::TypedBuilder))]
#[must_use]
#[non_exhaustive]
pub struct GetShieldModeStatusRequest<'a> {
#[cfg_attr(feature = "typed-builder", builder(setter(into)))]
#[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
pub broadcaster_id: Cow<'a, types::UserIdRef>,
#[cfg_attr(feature = "typed-builder", builder(setter(into)))]
#[cfg_attr(feature = "deser_borrow", serde(borrow = "'a"))]
pub moderator_id: Cow<'a, types::UserIdRef>,
}
impl<'a> GetShieldModeStatusRequest<'a> {
pub fn new(
broadcaster_id: impl types::IntoCow<'a, types::UserIdRef> + 'a,
moderator_id: impl types::IntoCow<'a, types::UserIdRef> + 'a,
) -> Self {
Self {
broadcaster_id: broadcaster_id.into_cow(),
moderator_id: moderator_id.into_cow(),
}
}
}
#[derive(PartialEq, Eq, Serialize, Debug, Clone)]
#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
#[non_exhaustive]
pub struct ShieldModeStatus {
pub is_active: bool,
#[serde(flatten)]
pub last_shield_mode: Option<LastShieldMode>,
}
impl<'de> serde::Deserialize<'de> for ShieldModeStatus {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where D: serde::Deserializer<'de> {
#[derive(Deserialize)]
#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
struct InnerShieldModeStatus {
is_active: bool,
#[serde(deserialize_with = "crate::deserialize_none_from_empty_string")]
moderator_id: Option<types::UserId>,
#[serde(deserialize_with = "crate::deserialize_none_from_empty_string")]
moderator_login: Option<types::UserName>,
#[serde(deserialize_with = "crate::deserialize_none_from_empty_string")]
moderator_name: Option<types::DisplayName>,
#[serde(deserialize_with = "crate::deserialize_none_from_empty_string")]
last_activated_at: Option<types::Timestamp>,
}
let s = InnerShieldModeStatus::deserialize(deserializer)?;
let last = match (
s.moderator_id,
s.moderator_login,
s.moderator_name,
s.last_activated_at,
) {
(
Some(moderator_id),
Some(moderator_login),
Some(moderator_name),
Some(last_activated_at),
) => Some(LastShieldMode {
moderator_id,
moderator_login,
moderator_name,
last_activated_at,
}),
_ => None,
};
Ok(Self {
is_active: s.is_active,
last_shield_mode: last,
})
}
}
#[derive(PartialEq, Eq, Deserialize, Serialize, Debug, Clone)]
#[cfg_attr(feature = "deny_unknown_fields", serde(deny_unknown_fields))]
#[non_exhaustive]
pub struct LastShieldMode {
pub moderator_id: types::UserId,
pub moderator_login: types::UserName,
pub moderator_name: types::DisplayName,
pub last_activated_at: types::Timestamp,
}
impl LastShieldMode {}
impl Request for GetShieldModeStatusRequest<'_> {
type Response = ShieldModeStatus;
const PATH: &'static str = "moderation/shield_mode";
#[cfg(feature = "twitch_oauth2")]
const SCOPE: twitch_oauth2::Validator = twitch_oauth2::validator![any(
twitch_oauth2::Scope::ModeratorReadShieldMode,
twitch_oauth2::Scope::ModeratorManageShieldMode
)];
}
impl RequestGet for GetShieldModeStatusRequest<'_> {
fn parse_inner_response(
request: Option<Self>,
uri: &http::Uri,
response: &str,
status: http::StatusCode,
) -> Result<helix::Response<Self, <Self as Request>::Response>, helix::HelixRequestGetError>
where
Self: Sized,
{
let inner_response: helix::InnerResponse<Vec<_>> = crate::parse_json(response, true)
.map_err(|e| {
helix::HelixRequestGetError::DeserializeError(
response.to_string(),
e,
uri.clone(),
status,
)
})?;
Ok(helix::Response::new(
inner_response.data.into_iter().next().ok_or(
helix::HelixRequestGetError::InvalidResponse {
reason: "expected an entry in `data`",
response: response.to_string(),
status,
uri: uri.clone(),
},
)?,
inner_response.pagination.cursor,
request,
inner_response.total,
inner_response.other,
))
}
}
#[cfg(test)]
#[test]
fn test_request() {
use helix::*;
let req = GetShieldModeStatusRequest::new("12345", "98765");
let data = br#"
{
"data": [
{
"is_active": true,
"moderator_id": "98765",
"moderator_name": "SimplySimple",
"moderator_login": "simplysimple",
"last_activated_at": "2022-07-26T17:16:03.123Z"
}
]
}
"#
.to_vec();
let http_response = http::Response::builder().body(data).unwrap();
let uri = req.get_uri().unwrap();
assert_eq!(
uri.to_string(),
"https://api.twitch.tv/helix/moderation/shield_mode?broadcaster_id=12345&moderator_id=98765"
);
dbg!(GetShieldModeStatusRequest::parse_response(Some(req), &uri, http_response).unwrap());
}
#[cfg(test)]
#[test]
fn test_request_empty() {
use helix::*;
let req = GetShieldModeStatusRequest::new("12345", "98765");
let data = br#"
{
"data": [
{
"is_active": false,
"moderator_id": "",
"moderator_name": "",
"moderator_login": "",
"last_activated_at": ""
}
]
}
"#
.to_vec();
let http_response = http::Response::builder().body(data).unwrap();
let uri = req.get_uri().unwrap();
assert_eq!(
uri.to_string(),
"https://api.twitch.tv/helix/moderation/shield_mode?broadcaster_id=12345&moderator_id=98765"
);
let status =
GetShieldModeStatusRequest::parse_response(Some(req), &uri, http_response).unwrap();
dbg!(&status);
assert!(status.data.last_shield_mode.is_none());
}