1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
mod ctx;
mod state;

use crate::RequestBuilder;
use std::{future::Future, sync::Arc};

pub use self::{ctx::Ctx, state::State};

pub type Update<T = serde_json::Value> = crate::responses::LongPollResponse<T>;

impl<T> Update<T> {
    pub fn into_parts(self) -> Parts {
        Parts {
            vk: self.ts.unwrap(),
        }
    }
}

mod private {
    #[derive(Debug, Clone, Copy)]
    pub enum ViaParts {}
    #[derive(Debug, Clone, Copy)]
    pub enum ViaUpdate {}
}

pub trait FromUpdate<S, M = private::ViaUpdate>: Sized {
    fn from_update(
        update: Update,
        state: &S,
        request: Arc<RequestBuilder>,
    ) -> impl Future<Output = Result<Self, ()>> + Send;
}

#[derive(Clone)]
pub struct Parts {
    pub vk: String,
}

pub trait FromUpdateParts<S>: Sized {
    fn from_update_parts(
        parts: &mut Parts,
        state: &S,
        request: Arc<RequestBuilder>,
    ) -> impl Future<Output = Result<Self, ()>> + Send;
}

impl<S, T> FromUpdate<S, private::ViaParts> for T
where
    S: Send + Sync,
    T: FromUpdateParts<S>,
{
    async fn from_update(
        update: Update,
        state: &S,
        request: Arc<RequestBuilder>,
    ) -> Result<Self, ()> {
        let mut parts = update.into_parts();
        Self::from_update_parts(&mut parts, state, request).await
    }
}