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
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
//! 元数据
use std::{
    any::type_name,
    fmt::{Debug, Display, Formatter},
    sync::Arc,
};

use serde::{Serialize, Serializer};
use utoipa::{
    openapi::{ObjectBuilder, RefOr, Schema, SchemaType},
    ToSchema,
};

use crate::tina::{
    data::AppResult,
    server::{
        application::{AppConfig, Application},
        http::request::{AnyType, RequestAttribute, RequestExt},
        session::Session,
    },
};

/// 请求元数据
pub struct HttpReqMetadata {
    application: Application,
    /// Session
    pub session: Session,
    pub(crate) request: Box<AnyType>,
}

impl RequestAttribute for HttpReqMetadata {
    fn application(&self) -> Application {
        self.application.to_owned()
    }
    fn session(&self) -> Session {
        self.session.to_owned()
    }
}

impl HttpReqMetadata {
    /// 构建
    pub fn new<Req: RequestExt + 'static>(req: Req, application: Application, session: Session) -> HttpReqMetadata {
        let request = Box::new(req);
        HttpReqMetadata {
            application,
            session,
            request,
        }
    }
    /// 获取扩展
    pub fn extension<T: Send + Sync + 'static>(&self) -> AppResult<Arc<T>> {
        self.application.extension()
    }
}

impl From<HttpReqMetadata> for (Session, Application) {
    fn from(value: HttpReqMetadata) -> Self {
        (value.session, value.application)
    }
}

impl<'a> ToSchema<'a> for HttpReqMetadata {
    fn schema() -> (&'a str, RefOr<Schema>) {
        (type_name::<HttpReqMetadata>(), RefOr::T(Schema::from(ObjectBuilder::new().schema_type(SchemaType::Object))))
    }
}

impl Default for HttpReqMetadata {
    fn default() -> Self {
        HttpReqMetadata {
            application: AppConfig::new().into(),
            session: Session::default(),
            request: Box::new(()),
        }
    }
}

impl Debug for HttpReqMetadata {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        f.write_str("[RequestMetadata]")
    }
}

impl Display for HttpReqMetadata {
    fn fmt(&self, f: &mut Formatter<'_>) -> std::fmt::Result {
        f.write_str("[RequestMetadata]")
    }
}

impl Serialize for HttpReqMetadata {
    fn serialize<S>(&self, serializer: S) -> Result<<S as Serializer>::Ok, <S as Serializer>::Error>
    where
        S: Serializer,
    {
        "[RequestMetadata]".serialize(serializer)
    }
}