asonix
0e1552eeaa
This gives us more control over things, like automatic 'linkifying', and the ability to add custom user tagging logic
69 lines
1.4 KiB
Rust
69 lines
1.4 KiB
Rust
use combine::{many1, parser::char::alpha_num, Parser, Stream};
|
|
|
|
#[derive(Clone, Debug, Eq, PartialEq)]
|
|
pub struct Handle {
|
|
pub handle: String,
|
|
pub domain: String,
|
|
}
|
|
|
|
fn at<Input>() -> impl Parser<Input, Output = char>
|
|
where
|
|
Input: Stream<Token = char>,
|
|
{
|
|
combine::parser::char::char('@')
|
|
}
|
|
|
|
fn handle_part<Input>() -> impl Parser<Input, Output = String>
|
|
where
|
|
Input: Stream<Token = char>,
|
|
{
|
|
many1(alpha_num())
|
|
}
|
|
|
|
fn domain_part<Input>() -> impl Parser<Input, Output = String>
|
|
where
|
|
Input: Stream<Token = char>,
|
|
{
|
|
crate::url::domain().map(|d| d.0)
|
|
}
|
|
|
|
pub(crate) fn handle<Input>() -> impl Parser<Input, Output = Handle>
|
|
where
|
|
Input: Stream<Token = char>,
|
|
{
|
|
at().with(handle_part())
|
|
.skip(at())
|
|
.and(domain_part())
|
|
.map(|(handle, domain)| Handle { handle, domain })
|
|
}
|
|
|
|
#[cfg(test)]
|
|
mod tests {
|
|
use super::*;
|
|
|
|
#[test]
|
|
fn parse_handle_part() {
|
|
let (_, rest) = handle_part().parse("as123").unwrap();
|
|
assert_eq!(rest, "");
|
|
}
|
|
|
|
#[test]
|
|
fn parse_simple_handle() {
|
|
let (_, rest) = handle().parse("@asdf@asdf").unwrap();
|
|
assert_eq!(rest, "");
|
|
}
|
|
|
|
#[test]
|
|
fn parse_complex_handle() {
|
|
let (_, rest) = handle()
|
|
.parse("@r2d2@telnet.towel.blinkenlights.nl")
|
|
.unwrap();
|
|
assert_eq!(rest, "");
|
|
}
|
|
|
|
#[test]
|
|
fn dont_parse_invalid_handle() {
|
|
assert!(handle().parse("asdf@asdf").is_err())
|
|
}
|
|
}
|