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
use crate::Tags; type Result<T> = std::result::Result<T, ParseError>; /** Tries to decode one message, returning the amount of remaining data in the input # Example ## A single message ```rust # use twitchchat::*; let input = ":test!test@test JOIN #museun\r\n"; let (pos, message) = decode_one(&input).unwrap(); assert_eq!(pos, 0); // no more messages were found let expected = messages::Raw { raw: ":test!test@test JOIN #museun\r\n", tags: Tags::default(), prefix: Some(decode::Prefix::User { nick: "test" }), command: "JOIN", args: "#museun", data: None, }; assert_eq!(message, expected); ``` # Multiple messages ```rust # use twitchchat::*; let input = ":test!test@test JOIN #museun\r\n:test!test@test JOIN #shaken_bot\r\n"; let (pos, message) = decode_one(&input).unwrap(); assert_eq!(pos, 30); // another message probably starts at offset '30' let expected = messages::Raw { raw: ":test!test@test JOIN #museun\r\n", tags: Tags::default(), prefix: Some(decode::Prefix::User { nick: "test" }), command: "JOIN", args: "#museun", data: None, }; assert_eq!(message, expected); // continue from where it left off let (pos, message) = decode_one(&input[pos..]).unwrap(); assert_eq!(pos, 0); // no more messages were found let expected = messages::Raw { raw: ":test!test@test JOIN #shaken_bot\r\n", tags: Tags::default(), prefix: Some(decode::Prefix::User { nick: "test" }), command: "JOIN", args: "#shaken_bot", data: None, }; assert_eq!(message, expected); ``` */ pub fn decode_one(input: &str) -> Result<(usize, Message<&'_ str>)> { let pos = input .find("\r\n") .ok_or_else(|| ParseError::IncompleteMessage { pos: 0 })?; let next = if pos + 2 == input.len() { 0 } else { pos + 2 }; Message::parse(&input[..pos + 2]).map(|msg| (next, msg)) } /** Tries to decode potentially many messages from this input string # Example ```rust # use twitchchat::*; let input = ":test!test@test JOIN #museun\r\n:test!test@test JOIN #shaken_bot\r\n"; let expected = &[ messages::Raw { raw: ":test!test@test JOIN #museun\r\n", tags: Tags::default(), prefix: Some(decode::Prefix::User { nick: "test" }), command: "JOIN", args: "#museun", data: None, }, messages::Raw { raw: ":test!test@test JOIN #shaken_bot\r\n", tags: Tags::default(), prefix: Some(decode::Prefix::User { nick: "test" }), command: "JOIN", args: "#shaken_bot", data: None, }, ]; for (message, expected) in decode(&input).zip(expected.iter()) { let msg = message.expect("valid message"); assert_eq!(msg, *expected); } ``` */ pub fn decode(input: &str) -> impl Iterator<Item = Result<Message<&'_ str>>> + '_ { ParseIter::new(input) } mod parser; use parser::*; mod message; pub use message::*; mod prefix; pub use prefix::*; mod error; pub use error::*; #[cfg(test)] mod tests;