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
use tc_error::*;
use tcgeneric::{path_label, Instance, NativeClass, PathLabel, PathSegment};

use crate::scalar::Link;
use crate::state::State;

use super::*;

const CLASS: PathLabel = path_label(&["class"]);

struct SelfHandler<'a> {
    subject: &'a State,
}

impl<'a> Handler<'a> for SelfHandler<'a> {
    fn get(self: Box<Self>) -> Option<GetHandler<'a>> {
        Some(Box::new(|_txn, key| {
            Box::pin(async move {
                if key.is_none() {
                    Ok(self.subject.clone())
                } else {
                    Err(TCError::not_found(key))
                }
            })
        }))
    }
}

struct ClassHandler<'a> {
    subject: &'a State,
}

impl<'a> Handler<'a> for ClassHandler<'a> {
    fn get(self: Box<Self>) -> Option<GetHandler<'a>> {
        Some(Box::new(|_txn, _key| {
            Box::pin(async move { Ok(Link::from(self.subject.class().path()).into()) })
        }))
    }
}

impl Route for State {
    fn route<'a>(&'a self, path: &'a [PathSegment]) -> Option<Box<dyn Handler<'a> + 'a>> {
        let child_handler = match self {
            Self::Collection(collection) => collection.route(path),
            Self::Chain(chain) => chain.route(path),
            Self::Map(map) => map.route(path),
            Self::Object(object) => object.route(path),
            Self::Scalar(scalar) => scalar.route(path),
            Self::Tuple(tuple) => tuple.route(path),
        };

        if let Some(handler) = child_handler {
            return Some(handler);
        }

        if path.is_empty() {
            Some(Box::new(SelfHandler { subject: self }))
        } else if path == &CLASS[..] {
            Some(Box::new(ClassHandler { subject: self }))
        } else {
            None
        }
    }
}