sark_core/request/frame/
raw.rs1use std::{mem, ops};
4
5use o3::{buffer, buffer::resident, mem::rc};
6use request::{Projection, field, frame::proof, path};
7use sark_http::request::{Bytes, span};
8
9use crate::{request, route};
10
11pub struct Path<'a, R> {
12 req: &'a R,
13 cap: route::raw::PathCapture,
14}
15
16impl<'a, R> Path<'a, R> {
17 pub const unsafe fn new(req: &'a R, cap: route::raw::PathCapture) -> Self {
22 Self { req, cap }
23 }
24}
25
26impl<'req, R: route::Schema>
27 Path<'_, request::raw::Parsed<request::Head<&'req [u8], R::Frame>, R>>
28{
29 pub fn get(self) -> &'req [u8] {
30 let path = self.req.owner().path();
31 let range = self.cap.start()..self.cap.end();
32 unsafe { path.get_unchecked(range) }
33 }
34
35 pub fn try_parse<T: field::Path>(self) -> Result<T, field::Error> {
36 let start = self.cap.start();
37 T::parse(path::Capture::new(self.get(), start))
38 }
39}
40
41impl<'d, R: route::Schema> Path<'_, request::raw::Parsed<request::Parts<'d, R::Frame>, R>> {
42 pub fn try_get(self) -> Result<Bytes<'d>, rc::Error> {
44 let range = self.cap.start()..self.cap.end();
45 Ok(match self.req.owner().head.route() {
46 Projection::Frame(path) => {
47 let start = path.start + range.start;
48 let end = path.start + range.end;
49 let owner = self.req.owner().head.owner();
50 let frame = unsafe { buffer::raw::Segment::try_project(owner, start..end) }?;
51 Bytes::from_shared(self.req.owner().id, frame)
52 }
53 Projection::Root => self.static_path(b"/", range),
54 Projection::Star => self.static_path(b"*", range),
55 })
56 }
57
58 pub fn try_parse<T: field::Path>(self) -> Result<T, field::Error> {
59 let path = self.req.owner().head.borrow().path();
60 let range = self.cap.start()..self.cap.end();
61 let value = unsafe { path.get_unchecked(range) };
63 T::parse(path::Capture::new(value, self.cap.start()))
64 }
65
66 fn static_path(self, path: &'d [u8], range: ops::Range<usize>) -> Bytes<'d> {
67 let frame = unsafe { path.get_unchecked(range) };
68 Bytes::new(self.req.owner().id, resident::Shared::from(frame))
69 }
70}
71
72pub struct Bound<'a, R> {
73 req: &'a R,
74 span: span::Span,
75}
76
77impl<'a, R> Bound<'a, R> {
78 pub const unsafe fn new(req: &'a R, span: span::Span) -> Self {
83 Self { req, span }
84 }
85}
86
87impl<'req, R: route::Schema>
88 Bound<'_, request::raw::Parsed<request::Head<&'req [u8], R::Frame>, R>>
89{
90 pub fn get(self) -> &'req [u8] {
91 let range = self.span.start()..self.span.end();
92 let owner = *self.req.owner().owner();
93 unsafe { owner.get_unchecked(range) }
94 }
95}
96
97impl<'a, 'req, R: route::Schema<Frame = proof::Peer>>
98 Bound<'a, request::raw::Parsed<request::Head<&'req [u8], proof::Peer>, R>>
99{
100 pub fn required(
101 req: &'a request::raw::Parsed<request::Head<&'req [u8], proof::Peer>, R>,
102 ) -> Self {
103 Self {
104 req,
105 span: req.owner().peer(),
106 }
107 }
108}
109
110impl<'d, R: route::Schema> Bound<'_, request::raw::Parsed<request::Parts<'d, R::Frame>, R>> {
111 pub fn try_get(self) -> Result<Bytes<'d>, rc::Error> {
112 let range = self.span.start()..self.span.end();
113 let owner = self.req.owner().head.owner();
114 let frame = unsafe { buffer::raw::Segment::try_project(owner, range) }?;
115 Ok(Bytes::from_shared(self.req.owner().id, frame))
116 }
117}
118
119impl<'a, 'd, R: route::Schema<Frame = proof::Peer>>
120 Bound<'a, request::raw::Parsed<request::Parts<'d, proof::Peer>, R>>
121{
122 pub fn required(req: &'a request::raw::Parsed<request::Parts<'d, proof::Peer>, R>) -> Self {
123 Self {
124 req,
125 span: req.owner().head.peer(),
126 }
127 }
128}
129
130const _: () = {
131 assert!(mem::size_of::<Path<'_, ()>>() == 3 * mem::size_of::<usize>());
132 assert!(mem::size_of::<Bound<'_, ()>>() == 2 * mem::size_of::<usize>());
133};