Skip to main content

yew_linkify/
lib.rs

1use linkify::{LinkFinder, LinkKind};
2use yew::prelude::*;
3
4#[derive(Properties, PartialEq)]
5pub struct Props {
6    pub text: String,
7}
8
9#[function_component]
10pub fn Linkify(props: &Props) -> Html {
11    let finder = LinkFinder::new();
12    let text = props.text.as_str();
13    let spans = finder.spans(text);
14
15    html! {
16        <p>
17        {
18            for spans.into_iter().map(move |current| {
19
20            match current.kind() {
21
22                Some(LinkKind::Email) => {
23                    let mut mail_to_link: String = "mailto:".to_owned();
24                    let current_string: &str = current.as_str();
25
26                    mail_to_link.push_str(current_string);
27                    return html!{<a href={mail_to_link}>{current.as_str()}</a>}
28                }
29
30                Some(LinkKind::Url) => {
31                    // TODO: I don't know why I have to do this, will learn more rust and improve it later
32                    let mut plain_link: String = "".to_owned();
33                    let current_string: &str = current.as_str();
34                    plain_link.push_str(current_string);
35
36                    return html!{<a href={plain_link}>{current.as_str()}</a>}
37                }
38                _ => {
39                return html!{
40                    <span>{current.as_str()}</span>
41                }
42            }
43            }
44
45            })
46        }
47        </p>
48    }
49}
50
51#[cfg(test)]
52mod tests {
53    use linkify::{LinkFinder, LinkKind};
54
55    #[test]
56    fn test_linkify_email() {
57        let finder = LinkFinder::new();
58        let text = "Contact: test@example.com";
59        let spans: Vec<_> = finder.spans(text).collect();
60        assert!(spans.iter().any(|s| s.kind() == Some(&LinkKind::Email)));
61    }
62
63    #[test]
64    fn test_linkify_url() {
65        let finder = LinkFinder::new();
66        let text = "Visit https://example.com!";
67        let spans: Vec<_> = finder.spans(text).collect();
68        assert!(spans.iter().any(|s| s.kind() == Some(&LinkKind::Url)));
69    }
70}