1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
//! Linkify finds links such as URLs and email addresses in plain text.
//! It's smart about where a link ends, such as with trailing punctuation.
//!
//! Your reaction might be: "Do I need a library for this? Why not a regex?".
//! Let's look at a few cases:
//!
//! * In `http://example.com/.` the link should not include the trailing dot
//! * `http://example.com/,` should not include the trailing comma
//! * `(http://example.com/)` should not include the parens
//!
//! Seems simple enough. But then we also have these cases:
//!
//! * `https://en.wikipedia.org/wiki/Link_(The_Legend_of_Zelda)` should include the trailing paren
//! * `http://üñîçøðé.com/ä` should also work for Unicode (including Emoji and Punycode)
//! * `<http://example.com/>` should not include angle brackets
//!
//! This library behaves as you'd expect in the above cases and many more.
//! It uses a simple scan with linear runtime.
//!
//! In addition to URLs, it can also find emails.
//!
//! ### Usage
//!
//! Basic usage:
//!
//! ```
//! use linkify::{LinkFinder, LinkKind};
//!
//! let input = "Have you seen http://example.com?";
//! let finder = LinkFinder::new();
//! let links: Vec<_> = finder.links(input).collect();
//!
//! assert_eq!(1, links.len());
//! let link = &links[0];
//!
//! assert_eq!("http://example.com", link.as_str());
//! assert_eq!(14, link.start());
//! assert_eq!(32, link.end());
//! assert_eq!(&LinkKind::Url, link.kind());
//! ```
//!
//! Restrict the kinds of links:
//!
//! ```
//! use linkify::{LinkFinder, LinkKind};
//!
//! let input = "http://example.com and foo@example.com";
//! let mut finder = LinkFinder::new();
//! finder.kinds(&[LinkKind::Email]);
//! let links: Vec<_> = finder.links(input).collect();
//!
//! assert_eq!(1, links.len());
//! let link = &links[0];
//! assert_eq!("foo@example.com", link.as_str());
//! assert_eq!(&LinkKind::Email, link.kind());
//! ```
//!
//! Split the text into consecutive spans (mixed links and plain text).
//!
//! ```
//! use linkify::{LinkFinder, LinkKind};
//!
//! let input = "Have you seen http://example.com?";
//! let finder = LinkFinder::new();
//! let spans: Vec<_> = finder.spans(input).collect();
//!
//! assert_eq!(3, spans.len());
//!
//! assert_eq!("Have you seen ", spans[0].as_str());
//! assert_eq!(0, spans[0].start());
//! assert_eq!(14, spans[0].end());
//! assert_eq!(None, spans[0].kind());
//!
//! assert_eq!("http://example.com", spans[1].as_str());
//! assert_eq!(14, spans[1].start());
//! assert_eq!(32, spans[1].end());
//! assert_eq!(Some(&LinkKind::Url), spans[1].kind());
//!
//! assert_eq!("?", spans[2].as_str());
//! assert_eq!(32, spans[2].start());
//! assert_eq!(33, spans[2].end());
//! assert_eq!(None, spans[2].kind());
//! ```
//!
//! ### Conformance
//!
//! This crates makes an effort to respect the various standards, namely:
//!
//! * [RFC 3986] and [RFC 3987] for URLs
//! * [RFC 5321] and [RFC 6531] for emails (except IP addresses and quoting)
//!
//! At the same time, it does not guarantee that the returned links are valid.
//! If in doubt, it rather returns a link than skipping it.
//!
//! If you need to validate URLs, e.g. for checking TLDs, use another library on
//! the returned links.
//!
//! [RFC 3986]: https://tools.ietf.org/search/rfc3986
//! [RFC 3987]: https://tools.ietf.org/search/rfc3987
//! [RFC 5321]: https://tools.ietf.org/search/rfc5321
//! [RFC 6531]: https://tools.ietf.org/search/rfc6531

#![doc(html_root_url = "https://docs.rs/linkify/0.4.0")]
#![deny(warnings)]
#![deny(missing_docs)]
#![deny(missing_debug_implementations)]

mod email;
mod finder;
mod scanner;
mod url;

pub use crate::finder::Link;
pub use crate::finder::LinkFinder;
pub use crate::finder::LinkKind;
pub use crate::finder::Links;
pub use crate::finder::{Span, Spans};