teo_runtime/handler/group/
builder.rs

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
98
99
use std::collections::BTreeMap;
use std::sync::{Arc, Mutex};
use maplit::btreemap;
use teo_parser::ast::handler::HandlerInputFormat;
use teo_parser::r#type::Type;
use crate::app::data::AppData;
use crate::handler::ctx_argument::HandlerCtxArgument;
use crate::handler::{Group, Handler, handler};
use crate::handler::group::group;
use hyper::Method;
use crate::request::Request;
use crate::traits::named::Named;
use crate::utils::next_path;

#[derive(Debug, Clone)]
pub struct Builder {
    inner: Arc<Inner>
}

#[derive(Debug)]
struct Inner {
    pub path: Vec<String>,
    pub(crate) handlers: Arc<Mutex<BTreeMap<String, Handler>>>,
    pub app_data: AppData,

}

impl Builder {

    pub fn new(path: Vec<String>, app_data: AppData) -> Self {
        Self {
            inner: Arc::new(Inner {
                path,
                handlers: Arc::new(Mutex::new(btreemap! {})),
                app_data,
            })
        }
    }

    pub fn path(&self) -> &Vec<String> {
        &self.inner.path
    }

    pub fn handler(&self, name: &str) -> Option<Handler> {
        let handlers = self.inner.handlers.lock().unwrap();
        handlers.get(name).cloned()
    }

    pub fn insert_handler(&self, name: &str, handler: Handler) {
        let mut handlers = self.inner.handlers.lock().unwrap();
        handlers.insert(name.to_owned(), handler);
    }

    pub fn define_handler<T, F>(&self, name: &str, call: F) where T: 'static, for<'a> F: 'static + HandlerCtxArgument<'a, T> {
        let wrapped_call: &'static F = &*Box::leak(Box::new(call));
        let handler = Handler {
            inner: Arc::new(handler::Inner {
                namespace_path: {
                    let mut result = self.inner.path.clone();
                    result.pop();
                    result
                },
                input_type: Type::Undetermined,
                output_type: Type::Undetermined,
                nonapi: false,
                format: HandlerInputFormat::Json,
                path: next_path(self.path(), name),
                ignore_prefix: false,
                method: Method::POST,
                interface: None,
                url: None,
                call: Box::leak(Box::new(move |request: Request| async move {
                    wrapped_call.call(&request).await
                })),
            })
        };
        let mut handlers = self.inner.handlers.lock().unwrap();
        handlers.insert(name.to_owned(), handler);
    }

    pub fn app_data(&self) -> &AppData {
        &self.inner.app_data
    }

    pub fn build(self) -> Group {
        Group {
            inner: Arc::new(group::Inner {
                path: self.path().clone(),
                handlers: self.inner.handlers.lock().unwrap().clone(),
            })
        }
    }
}

impl Named for Builder {
    fn name(&self) -> &str {
        self.inner.path.last().unwrap().as_str()
    }
}