read_url/mock/mock_url.rs
1use super::super::{context::*, url::*, util::*};
2
3use {kutil::io::reader::*, std::fmt};
4
5//
6// MockUrl
7//
8
9/// A standalone URL implementation intended for testing purposes.
10///
11/// You can set a URL representation as you please, mocking any other scheme or not
12/// following the URL notation at all. Thus mock URLs must be explictly created via
13/// [UrlContext::mock_url] and cannot be returned by general [UrlContext] functions.
14///
15/// The [URL::base] and [URL::relative] functions are supported in two modes. When
16/// slashable is true, they will interpret the URL representation as a Unix-style filesystem
17/// path, whereby the path separator is "/", and "." and ".." are supported for path
18/// traversal. When slashable is false, [URL::relative] does simple string concatenation,
19/// and you must explicitly provide a base_url_representation if you want to support [URL::base].
20/// For both functions, the content and format are simply cloned.
21///
22/// [URL::conform] does nothing.
23///
24/// For custom URLs that are supported by general [UrlContext] functions, see
25/// [InternalUrl](super::super::internal::InternalUrl).
26#[derive(Clone, Debug)]
27pub struct MockUrl {
28 /// The URL representation.
29 pub url_representation: String,
30
31 /// Whether the URL representation is "slashable".
32 pub slashable: bool,
33
34 /// The optional base URL representation (used when slashable is false).
35 pub base_url_representation: Option<String>,
36
37 /// The optional query.
38 pub query: Option<UrlQuery>,
39
40 /// The optional fragment.
41 pub fragment: Option<String>,
42
43 /// The optional format.
44 pub format: Option<String>,
45
46 /// The optional content.
47 pub content: Option<ReadableBuffer>,
48
49 pub(crate) context: UrlContextRef,
50}
51
52impl MockUrl {
53 /// Constructor.
54 pub fn new(
55 context: &UrlContextRef,
56 url_representation: String,
57 slashable: bool,
58 base_url_representation: Option<String>,
59 query: Option<UrlQuery>,
60 fragment: Option<String>,
61 format: Option<String>,
62 content: Option<&[u8]>,
63 ) -> Self {
64 Self {
65 url_representation,
66 slashable,
67 base_url_representation,
68 query,
69 fragment,
70 format,
71 content: content.map(ReadableBuffer::new),
72 context: context.clone(),
73 }
74 }
75
76 /// Constructor.
77 pub fn new_with(&self, url_representation: String) -> MockUrl {
78 Self {
79 context: self.context.clone(),
80 url_representation,
81 slashable: self.slashable,
82 query: None,
83 fragment: None,
84 format: self.format.clone(),
85 content: self.content.clone(),
86 base_url_representation: None,
87 }
88 }
89}
90
91impl fmt::Display for MockUrl {
92 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
93 let query = url_query_string(&self.query);
94 let fragment = url_fragment_string(&self.fragment);
95 write!(formatter, "{}{}{}", self.url_representation, query, fragment)
96 }
97}
98
99// Conversions
100
101impl Into<UrlRef> for MockUrl {
102 fn into(self) -> UrlRef {
103 Box::new(self)
104 }
105}