use super::{FromUpdate, RequestBuilder, Update};
use crate::{responses::Message, Error};
use serde_json::Value;
use std::sync::Arc;
#[derive(Clone)]
pub struct Ctx<T> {
pub request: Arc<RequestBuilder>,
body: T,
}
impl<T> Ctx<T> {
pub fn request(&self) -> &RequestBuilder {
&self.request
}
pub(crate) fn find_peer_id(&self, object: &Value) -> crate::Result<i64> {
match object {
Value::Object(map) => {
if let Some(peer_id) = map.get("peer_id").and_then(|id| id.as_i64()) {
return Ok(peer_id);
}
for v in map.values() {
if let Ok(id) = self.find_peer_id(v) {
return Ok(id);
}
}
Err(Error::PeerIdNotFound)
}
Value::Array(vec) => {
for item in vec {
if let Ok(id) = self.find_peer_id(item) {
return Ok(id);
}
}
Err(Error::PeerIdNotFound)
}
_ => Err(Error::PeerIdNotFound),
}
}
pub fn new(request: Arc<RequestBuilder>, body: T) -> Ctx<T> {
Ctx { request, body }
}
}
impl<T> std::ops::Deref for Ctx<T> {
type Target = T;
fn deref(&self) -> &Self::Target {
&self.body
}
}
impl<S> FromUpdate<S> for Ctx<Message>
where
S: Send + Sync,
{
async fn from_update(
update: Update,
_state: &S,
request: Arc<RequestBuilder>,
) -> Result<Self, ()> {
let message: Message =
serde_json::from_value(update.object).expect("Unable to parse an update");
Ok(Ctx {
request,
body: message,
})
}
}
impl<S> FromUpdate<S> for Ctx<Update>
where
S: Send + Sync,
{
async fn from_update(
update: Update,
_state: &S,
request: Arc<RequestBuilder>,
) -> Result<Self, ()> {
Ok(Ctx {
request,
body: update,
})
}
}