Skip to main content

spire_core/frontier/queue/
link.rs

1use http::Uri;
2
3use crate::frontier::seed::Seed;
4use crate::request::Tag;
5
6/// A link to follow with [`Queue::follow`](crate::frontier::queue::Queue::follow).
7///
8/// A link is either an `href`, absolute or relative to the page it was found
9/// on, or a complete [`Seed`]. Strings, URIs and seeds convert into links.
10///
11/// ```
12/// use spire_core::frontier::queue::Link;
13///
14/// let next = Link::from("/page/2");
15/// let detail = Link::from("../items/42").with_tag("item");
16/// ```
17#[derive(Debug, Clone)]
18pub struct Link {
19    pub(crate) target: Target,
20    pub(crate) tag: Option<Tag>,
21}
22
23#[derive(Debug, Clone)]
24pub(crate) enum Target {
25    Href(String),
26    Seed(Box<Seed>),
27}
28
29impl Link {
30    /// Creates a link from an `href`, absolute or relative.
31    #[must_use]
32    pub fn new(href: impl Into<String>) -> Self {
33        Self {
34            target: Target::Href(href.into()),
35            tag: None,
36        }
37    }
38
39    /// Routes the followed request to the handler for `tag`.
40    #[must_use]
41    pub fn with_tag(mut self, tag: impl Into<Tag>) -> Self {
42        self.tag = Some(tag.into());
43        self
44    }
45}
46
47impl From<&str> for Link {
48    fn from(href: &str) -> Self {
49        Self::new(href)
50    }
51}
52
53impl From<String> for Link {
54    fn from(href: String) -> Self {
55        Self::new(href)
56    }
57}
58
59impl From<&String> for Link {
60    fn from(href: &String) -> Self {
61        Self::new(href.as_str())
62    }
63}
64
65impl From<Uri> for Link {
66    fn from(uri: Uri) -> Self {
67        Self::new(uri.to_string())
68    }
69}
70
71impl From<Seed> for Link {
72    fn from(seed: Seed) -> Self {
73        Self {
74            target: Target::Seed(Box::new(seed)),
75            tag: None,
76        }
77    }
78}