sl_chat_log_parser/
avatar_messages.rs1use chumsky::error::Simple;
4use chumsky::prelude::{any, choice, just};
5use chumsky::Parser;
6
7#[derive(Debug, Clone, PartialEq)]
9pub enum AvatarMessage {
10 Chat {
12 volume: sl_types::chat::ChatVolume,
14 message: String,
16 },
17 Emote {
19 volume: sl_types::chat::ChatVolume,
21 message: String,
23 },
24 CameOnline,
26 WentOffline,
28 EnteredArea {
30 area: sl_types::radar::Area,
32 distance: Option<sl_types::map::Distance>,
34 },
35 LeftArea {
37 area: sl_types::radar::Area,
39 },
40}
41
42fn avatar_chat_message_parser() -> impl Parser<char, AvatarMessage, Error = Simple<char>> {
48 any()
49 .repeated()
50 .collect::<String>()
51 .try_map(|s, _span: std::ops::Range<usize>| {
52 let (v, s) = sl_types::chat::ChatVolume::volume_and_message(s.to_string());
53 Ok(AvatarMessage::Chat {
54 volume: v,
55 message: s,
56 })
57 })
58}
59
60fn avatar_emote_message_parser() -> impl Parser<char, AvatarMessage, Error = Simple<char>> {
66 just("/me ")
67 .ignore_then(any().repeated().collect::<String>())
68 .try_map(|s, _span: std::ops::Range<usize>| {
69 let (v, s) = sl_types::chat::ChatVolume::volume_and_message(s);
70 Ok(AvatarMessage::Emote {
71 volume: v,
72 message: s,
73 })
74 })
75}
76
77pub(crate) fn avatar_came_online_message_parser(
83) -> impl Parser<char, AvatarMessage, Error = Simple<char>> {
84 just("is online.").map(|_| AvatarMessage::CameOnline)
85}
86
87pub(crate) fn avatar_went_offline_message_parser(
93) -> impl Parser<char, AvatarMessage, Error = Simple<char>> {
94 just("is offline.").map(|_| AvatarMessage::WentOffline)
95}
96
97pub(crate) fn avatar_entered_area_message_parser(
103) -> impl Parser<char, AvatarMessage, Error = Simple<char>> {
104 just("entered ")
105 .ignore_then(sl_types::radar::area_parser())
106 .then(
107 just(" (")
108 .ignore_then(sl_types::map::distance_parser())
109 .then_ignore(just(")"))
110 .or_not(),
111 )
112 .then_ignore(just("."))
113 .try_map(|(area, distance), _span: std::ops::Range<usize>| {
114 Ok(AvatarMessage::EnteredArea { area, distance })
115 })
116}
117
118pub(crate) fn avatar_left_area_message_parser(
124) -> impl Parser<char, AvatarMessage, Error = Simple<char>> {
125 just("left ")
126 .ignore_then(sl_types::radar::area_parser())
127 .then_ignore(just("."))
128 .try_map(|area, _span: std::ops::Range<usize>| Ok(AvatarMessage::LeftArea { area }))
129}
130
131#[must_use]
137pub fn avatar_message_parser() -> impl Parser<char, AvatarMessage, Error = Simple<char>> {
138 choice([
139 avatar_came_online_message_parser().boxed(),
140 avatar_went_offline_message_parser().boxed(),
141 avatar_entered_area_message_parser().boxed(),
142 avatar_left_area_message_parser().boxed(),
143 avatar_emote_message_parser().boxed(),
144 avatar_chat_message_parser().boxed(),
145 ])
146}