use std::borrow::Borrow;
use super::{inner::NeosApiClient, Neos, NeosUnauthenticated, RequestError};
use minreq::{Method, Request, Response};
use time::OffsetDateTime;
#[derive(Clone)]
pub struct NeosAuthenticated {
inner: NeosApiClient,
user_id: crate::id::User,
token: String,
}
impl Neos for NeosAuthenticated {
fn api_request(
&self,
method: Method,
url: &str,
build: &mut dyn FnMut(Request) -> Result<Request, minreq::Error>,
) -> Result<Response, RequestError> {
self.inner.basic_api_request(method, url, &mut |req: Request| {
build(req.with_header(
"Authorization",
"neos ".to_owned() + self.user_id.as_ref() + ":" + &self.token,
))
})
}
}
impl NeosAuthenticated {
#[must_use]
pub fn new(user_agent: String, session: crate::UserSession) -> Self {
Self::from((NeosApiClient::new(user_agent), session))
}
pub fn logout(&self) -> Result<(), RequestError> {
self.api_request(
Method::Delete,
&("userSessions/".to_owned() + self.user_id.as_ref()),
&mut Ok,
)?;
Ok(())
}
pub fn extend_session(&self) -> Result<(), RequestError> {
self.api_request(Method::Patch, "userSessions", &mut Ok)?;
Ok(())
}
pub fn get_friends(
&self,
last_status_update: impl Borrow<Option<OffsetDateTime>>,
) -> Result<Vec<crate::Friend>, RequestError> {
self.get_friends_for(&self.user_id, last_status_update)
}
pub fn get_friends_for(
&self,
user: impl Borrow<crate::id::User>,
last_status_update: impl Borrow<Option<OffsetDateTime>>,
) -> Result<Vec<crate::Friend>, RequestError> {
let response = self.api_request(
Method::Get,
&("users/".to_owned() + user.borrow().as_ref() + "/friends"),
&mut |mut req| {
if let Some(last_status_update) = last_status_update.borrow() {
req = req
.with_param("lastStatusUpdate", last_status_update.to_string());
}
Ok(req)
},
)?;
Ok(response.json()?)
}
pub fn add_friend(
&self,
user_id: impl Borrow<crate::id::User>,
) -> Result<(), RequestError> {
self.api_request(
Method::Put,
&("users/".to_owned()
+ self.user_id.as_ref()
+ "/friends/" + user_id.borrow().as_ref()),
&mut |req| {
req.with_json(&serde_json::json!({
"ownerId": self.user_id.as_ref(),
"friendStatus": crate::FriendStatus::Accepted
}))
},
)?;
Ok(())
}
pub fn remove_friend(
&self,
user_id: impl Borrow<crate::id::User>,
) -> Result<(), RequestError> {
self.api_request(
Method::Delete,
&("users/".to_owned()
+ self.user_id.as_ref()
+ "/friends/" + user_id.borrow().as_ref()),
&mut |req| {
req.with_json(&serde_json::json!({
"ownerId": self.user_id.as_ref(),
"friendStatus": crate::FriendStatus::Ignored
}))
},
)?;
Ok(())
}
pub fn send_message(
&self,
message: impl Borrow<crate::Message>,
) -> Result<(), RequestError> {
let message = message.borrow();
self.api_request(
Method::Post,
&("users/".to_owned() + message.recipient_id.as_ref() + "/messages"),
&mut |req| req.with_json(message),
)?;
Ok(())
}
pub fn get_messages(
&self,
max_amount: u16,
unread_only: bool,
from_time: impl Borrow<Option<OffsetDateTime>>,
user: impl Borrow<Option<crate::id::User>>,
) -> Result<Vec<crate::Message>, RequestError> {
let response = self.api_request(
Method::Get,
&("users/".to_owned() + self.user_id.as_ref() + "/messages"),
&mut |mut req| {
if let Some(from_time) = from_time.borrow() {
req = req.with_param("fromTime", from_time.to_string());
}
if let Some(user) = user.borrow() {
req = req.with_param("user", user.as_ref());
}
if unread_only {
req = req.with_param("unread", "true");
}
Ok(req.with_param("maxItems", max_amount.to_string()))
},
)?;
Ok(response.json()?)
}
#[must_use]
pub fn downgrade(self) -> NeosUnauthenticated {
NeosUnauthenticated::from(self.inner)
}
}
impl From<(NeosApiClient, crate::UserSession)> for NeosAuthenticated {
fn from((inner, user_session): (NeosApiClient, crate::UserSession)) -> Self {
NeosAuthenticated {
inner,
token: user_session.token,
user_id: user_session.user_id,
}
}
}