Skip to main content

lychee_lib/types/
request.rs

1use std::{borrow::Cow, convert::TryFrom, fmt::Display};
2
3use crate::{BasicAuthCredentials, ErrorKind, Uri, types::uri::raw::RawUriSpan};
4
5use super::ResolvedInputSource;
6
7/// A checkable element extracted from a [`ResolvedInputSource`],
8/// containing a [`Uri`] and additional metadata associated with it.
9#[derive(Debug, PartialEq, Eq, Hash, Clone)]
10pub struct Request {
11    /// The extracted Uniform Resource Identifier
12    /// which can be checked with lychee
13    pub uri: Uri,
14
15    /// The resource which contains the given URI
16    pub source: ResolvedInputSource,
17
18    /// How the URI is rendered inside a document
19    /// (for example `img`, `a`, `pre`, or `code`).
20    /// In case of plaintext input the field is `None`.
21    pub element: Option<String>,
22
23    /// What attribute (e.g. `href`) the URI is contained in
24    pub attribute: Option<String>,
25
26    /// Where the URI is located
27    pub span: Option<RawUriSpan>,
28
29    /// Basic auth credentials
30    pub credentials: Option<BasicAuthCredentials>,
31}
32
33impl Request {
34    /// Instantiate a new `Request` object,
35    /// with optional fields set to `None`
36    #[inline]
37    #[must_use]
38    pub const fn new(uri: Uri, source: ResolvedInputSource) -> Self {
39        Request {
40            uri,
41            source,
42            element: None,
43            attribute: None,
44            span: None,
45            credentials: None,
46        }
47    }
48
49    /// Set [`Self::element`]
50    #[must_use]
51    pub fn with_element(mut self, element: String) -> Self {
52        self.element = Some(element);
53        self
54    }
55
56    /// Set [`Self::attribute`]
57    #[must_use]
58    pub fn with_attribute(mut self, attribute: String) -> Self {
59        self.attribute = Some(attribute);
60        self
61    }
62
63    /// Set [`Self::span`]
64    #[must_use]
65    pub const fn with_span(mut self, span: RawUriSpan) -> Self {
66        self.span = Some(span);
67        self
68    }
69
70    /// Set [`Self::credentials`]
71    #[must_use]
72    pub fn with_credentials(mut self, credentials: BasicAuthCredentials) -> Self {
73        self.credentials = Some(credentials);
74        self
75    }
76}
77
78impl Display for Request {
79    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
80        write!(f, "{} ({})", self.uri, self.source)
81    }
82}
83
84impl TryFrom<Uri> for Request {
85    type Error = ErrorKind;
86
87    fn try_from(uri: Uri) -> Result<Self, Self::Error> {
88        Ok(Request::new(
89            uri.clone(),
90            ResolvedInputSource::RemoteUrl(Box::new(uri.url)),
91        ))
92    }
93}
94
95impl TryFrom<String> for Request {
96    type Error = ErrorKind;
97
98    fn try_from(s: String) -> Result<Self, Self::Error> {
99        let uri = Uri::try_from(s.as_str())?;
100        Ok(Request::new(
101            uri,
102            ResolvedInputSource::String(Cow::Owned(s)),
103        ))
104    }
105}
106
107impl TryFrom<&str> for Request {
108    type Error = ErrorKind;
109
110    fn try_from(s: &str) -> Result<Self, Self::Error> {
111        let uri = Uri::try_from(s)?;
112        Ok(Request::new(
113            uri,
114            ResolvedInputSource::String(Cow::Owned(s.to_owned())),
115        ))
116    }
117}