sl_chat_log_parser/
avatar_messages.rs1use chumsky::IterParser as _;
4use chumsky::Parser;
5use chumsky::prelude::{any, choice, just};
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<'src>()
48-> impl Parser<'src, &'src str, AvatarMessage, chumsky::extra::Err<chumsky::error::Rich<'src, char>>>
49{
50 any()
51 .repeated()
52 .collect::<String>()
53 .try_map(|s, _span: chumsky::span::SimpleSpan| {
54 let (v, s) = sl_types::chat::ChatVolume::volume_and_message(s.to_string());
55 Ok(AvatarMessage::Chat {
56 volume: v,
57 message: s,
58 })
59 })
60}
61
62fn avatar_emote_message_parser<'src>()
68-> impl Parser<'src, &'src str, AvatarMessage, chumsky::extra::Err<chumsky::error::Rich<'src, char>>>
69{
70 just("/me ")
71 .ignore_then(any().repeated().collect::<String>())
72 .try_map(|s, _span: chumsky::span::SimpleSpan| {
73 let (v, s) = sl_types::chat::ChatVolume::volume_and_message(s);
74 Ok(AvatarMessage::Emote {
75 volume: v,
76 message: s,
77 })
78 })
79}
80
81#[must_use]
87pub fn avatar_came_online_message_parser<'src>()
88-> impl Parser<'src, &'src str, AvatarMessage, chumsky::extra::Err<chumsky::error::Rich<'src, char>>>
89{
90 just("is online.").map(|_| AvatarMessage::CameOnline)
91}
92
93#[must_use]
99pub fn avatar_went_offline_message_parser<'src>()
100-> impl Parser<'src, &'src str, AvatarMessage, chumsky::extra::Err<chumsky::error::Rich<'src, char>>>
101{
102 just("is offline.").map(|_| AvatarMessage::WentOffline)
103}
104
105#[must_use]
111pub fn avatar_entered_area_message_parser<'src>()
112-> impl Parser<'src, &'src str, AvatarMessage, chumsky::extra::Err<chumsky::error::Rich<'src, char>>>
113{
114 just("entered ")
115 .ignore_then(sl_types::radar::area_parser())
116 .then(
117 just(" (")
118 .ignore_then(sl_types::map::distance_parser())
119 .then_ignore(just(")"))
120 .or_not(),
121 )
122 .then_ignore(just("."))
123 .try_map(|(area, distance), _span: chumsky::span::SimpleSpan| {
124 Ok(AvatarMessage::EnteredArea { area, distance })
125 })
126}
127
128#[must_use]
134pub fn avatar_left_area_message_parser<'src>()
135-> impl Parser<'src, &'src str, AvatarMessage, chumsky::extra::Err<chumsky::error::Rich<'src, char>>>
136{
137 just("left ")
138 .ignore_then(sl_types::radar::area_parser())
139 .then_ignore(just("."))
140 .try_map(|area, _span: chumsky::span::SimpleSpan| Ok(AvatarMessage::LeftArea { area }))
141}
142
143#[must_use]
149pub fn avatar_message_parser<'src>()
150-> impl Parser<'src, &'src str, AvatarMessage, chumsky::extra::Err<chumsky::error::Rich<'src, char>>>
151{
152 choice([
153 avatar_came_online_message_parser().boxed(),
154 avatar_went_offline_message_parser().boxed(),
155 avatar_entered_area_message_parser().boxed(),
156 avatar_left_area_message_parser().boxed(),
157 avatar_emote_message_parser().boxed(),
158 avatar_chat_message_parser().boxed(),
159 ])
160}