1
1
#[ macro_use] extern crate matches;
2
2
pub extern crate mime;
3
3
4
- pub enum DataUrlError {
5
- NotADataUrl ,
6
- NoComma ,
7
- }
8
-
9
4
pub struct DataUrl < ' a > {
10
5
mime_type : mime:: Mime ,
11
6
base64 : bool ,
12
7
encoded_body_plus_fragment : & ' a str ,
13
8
}
14
9
10
+ pub enum DataUrlError {
11
+ NotADataUrl ,
12
+ NoComma ,
13
+ }
14
+
15
15
pub enum DecodeError < E > {
16
16
InvalidBase64 ( InvalidBase64 ) ,
17
17
WriteError ( E ) ,
@@ -23,12 +23,6 @@ impl<E> From<InvalidBase64> for DecodeError<E> {
23
23
fn from ( e : InvalidBase64 ) -> Self { DecodeError :: InvalidBase64 ( e) }
24
24
}
25
25
26
- /// The URL’s fragment identifier (after `#`) encoded as in the original input.
27
- ///
28
- /// It needs to be either percent-encoded to obtain the same string as in a parsed URL,
29
- /// or percent-decoded to interpret it as text.
30
- pub struct UrlFragmentIdentifier < ' a > ( pub & ' a str ) ;
31
-
32
26
impl < ' a > DataUrl < ' a > {
33
27
/// <https://fetch.spec.whatwg.org/#data-url-processor>
34
28
/// but starting from a string rather than a Url, to avoid extra string copies.
@@ -52,7 +46,7 @@ impl<'a> DataUrl<'a> {
52
46
/// Streaming-decode the data URL’s body to `write_body_bytes`,
53
47
/// and return the URL’s fragment identifier is returned if it has one.
54
48
pub fn decode < F , E > ( & self , write_body_bytes : F )
55
- -> Result < Option < UrlFragmentIdentifier < ' a > > , DecodeError < E > >
49
+ -> Result < Option < FragmentIdentifier < ' a > > , DecodeError < E > >
56
50
where F : FnMut ( & [ u8 ] ) -> Result < ( ) , E >
57
51
{
58
52
if self . base64 {
@@ -65,7 +59,7 @@ impl<'a> DataUrl<'a> {
65
59
66
60
/// Return the decoded body and the URL’s fragment identifier
67
61
pub fn decode_to_vec ( & self )
68
- -> Result < ( Vec < u8 > , Option < UrlFragmentIdentifier < ' a > > ) , InvalidBase64 >
62
+ -> Result < ( Vec < u8 > , Option < FragmentIdentifier < ' a > > ) , InvalidBase64 >
69
63
{
70
64
enum Impossible { }
71
65
let mut body = Vec :: new ( ) ;
@@ -78,6 +72,29 @@ impl<'a> DataUrl<'a> {
78
72
}
79
73
}
80
74
75
+ /// The URL’s fragment identifier (after `#`)
76
+ pub struct FragmentIdentifier < ' a > ( & ' a str ) ;
77
+
78
+ impl < ' a > FragmentIdentifier < ' a > {
79
+ /// Like in a parsed URL
80
+ pub fn to_percent_encoded ( & self ) -> String {
81
+ let mut string = String :: new ( ) ;
82
+ for byte in self . 0 . bytes ( ) {
83
+ match byte {
84
+ // Ignore ASCII tabs or newlines like the URL parser would
85
+ b'\t' | b'\n' | b'\r' => continue ,
86
+ // Fragment encode set
87
+ b'\0' ...b' ' | b'"' | b'<' | b'>' | b'`' | b'\x7F' ...b'\xFF' => {
88
+ percent_encode ( byte, & mut string)
89
+ }
90
+ // Printable ASCII
91
+ _ => string. push ( byte as char )
92
+ }
93
+ }
94
+ string
95
+ }
96
+ }
97
+
81
98
macro_rules! require {
82
99
( $condition: expr) => {
83
100
if !$condition {
@@ -217,7 +234,7 @@ fn percent_encode(byte: u8, string: &mut String) {
217
234
/// would be percent-decoded here.
218
235
/// We skip that round-trip and pass it through unchanged.
219
236
fn decode_without_base64 < F , E > ( encoded_body_plus_fragment : & str , mut write_bytes : F )
220
- -> Result < Option < UrlFragmentIdentifier > , E >
237
+ -> Result < Option < FragmentIdentifier > , E >
221
238
where F : FnMut ( & [ u8 ] ) -> Result < ( ) , E >
222
239
{
223
240
let bytes = encoded_body_plus_fragment. as_bytes ( ) ;
@@ -251,7 +268,7 @@ fn decode_without_base64<F, E>(encoded_body_plus_fragment: &str, mut write_bytes
251
268
b'#' => {
252
269
let fragment_start = i + 1 ;
253
270
let fragment = & encoded_body_plus_fragment[ fragment_start..] ;
254
- return Ok ( Some ( UrlFragmentIdentifier ( fragment) ) )
271
+ return Ok ( Some ( FragmentIdentifier ( fragment) ) )
255
272
}
256
273
257
274
// Ignore over '\t' | '\n' | '\r'
@@ -267,7 +284,7 @@ fn decode_without_base64<F, E>(encoded_body_plus_fragment: &str, mut write_bytes
267
284
/// <https://infra.spec.whatwg.org/#isomorphic-decode> composed with
268
285
/// <https://infra.spec.whatwg.org/#forgiving-base64-decode>.
269
286
fn decode_with_base64 < F , E > ( encoded_body_plus_fragment : & str , mut write_bytes : F )
270
- -> Result < Option < UrlFragmentIdentifier > , DecodeError < E > >
287
+ -> Result < Option < FragmentIdentifier > , DecodeError < E > >
271
288
where F : FnMut ( & [ u8 ] ) -> Result < ( ) , E >
272
289
{
273
290
let mut bit_buffer: u32 = 0 ;
0 commit comments