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() -> impl Parser where Input: Stream, { combine::parser::char::char('@') } fn handle_part() -> impl Parser where Input: Stream, { many1(alpha_num()) } fn domain_part() -> impl Parser where Input: Stream, { crate::url::domain().map(|d| d.0) } pub(crate) fn handle() -> impl Parser where Input: Stream, { 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()) } }