rocket_http/uri/fmt/
encoding.rs1use std::marker::PhantomData;
2use std::borrow::Cow;
3
4use percent_encoding::AsciiSet;
5
6use crate::RawStr;
7use crate::uri::fmt::{Part, Path, Query};
8use crate::parse::uri::tables::PATH_CHARS;
9
10#[derive(Clone, Copy)]
11#[allow(non_camel_case_types)]
12pub struct UNSAFE_ENCODE_SET<P: Part>(PhantomData<P>);
13
14pub trait EncodeSet {
15 const SET: AsciiSet;
16}
17
18const fn set_from_table(table: &'static [u8; 256]) -> AsciiSet {
19 const ASCII_RANGE_LEN: u8 = 0x80;
20
21 let mut set = percent_encoding::CONTROLS.add(0);
22 let mut i: u8 = 0;
23 while i < ASCII_RANGE_LEN {
24 if table[i as usize] == 0 {
25 set = set.add(i);
26 }
27
28 i += 1;
29 }
30
31 set
32}
33
34const PATH_SET: AsciiSet = set_from_table(&PATH_CHARS);
35
36impl<P: Part> Default for UNSAFE_ENCODE_SET<P> {
37 #[inline(always)]
38 fn default() -> Self { UNSAFE_ENCODE_SET(PhantomData) }
39}
40
41impl EncodeSet for UNSAFE_ENCODE_SET<Path> {
42 const SET: AsciiSet = PATH_SET
43 .add(b'%');
44}
45
46impl EncodeSet for UNSAFE_ENCODE_SET<Query> {
47 const SET: AsciiSet = PATH_SET
48 .remove(b'?')
49 .add(b'%')
50 .add(b'+');
51}
52
53#[derive(Clone, Copy)]
54#[allow(non_camel_case_types)]
55pub struct ENCODE_SET<P: Part>(PhantomData<P>);
56
57impl EncodeSet for ENCODE_SET<Path> {
58 const SET: AsciiSet = <UNSAFE_ENCODE_SET<Path>>::SET
59 .add(b'/');
60}
61
62impl EncodeSet for ENCODE_SET<Query> {
63 const SET: AsciiSet = <UNSAFE_ENCODE_SET<Query>>::SET
64 .add(b'&')
65 .add(b'=');
66}
67
68#[derive(Default, Clone, Copy)]
69#[allow(non_camel_case_types)]
70pub struct DEFAULT_ENCODE_SET;
71
72impl EncodeSet for DEFAULT_ENCODE_SET {
73 const SET: AsciiSet = <ENCODE_SET<Path>>::SET
76 .add(b'%')
78 .add(b'+')
79 .add(b'&')
81 .add(b'=');
82}
83
84pub fn percent_encode<S: EncodeSet + Default>(string: &RawStr) -> Cow<'_, str> {
85 percent_encoding::utf8_percent_encode(string.as_str(), &S::SET).into()
86}
87
88pub fn percent_encode_bytes<S: EncodeSet + Default>(bytes: &[u8]) -> Cow<'_, str> {
89 percent_encoding::percent_encode(bytes, &S::SET).into()
90}