alith_client/primitives/
text_list.rs1use super::PrimitiveTrait;
2use crate::components::grammar::{Grammar, text::text_list::TextListGrammar};
3use anyhow::Result;
4use std::slice::{Iter, IterMut};
5use std::vec::IntoIter;
6
7#[derive(Debug, Clone)]
8pub struct TextListPrimitive {
9 pub min_count: u8,
10 pub max_count: u8,
11 pub text_token_length: u32,
12 pub item_prefix: Option<String>,
13 pub disallowed_chars: Vec<char>,
14}
15
16impl Default for TextListPrimitive {
17 fn default() -> Self {
18 TextListPrimitive {
19 min_count: 1,
20 max_count: 5,
21 text_token_length: 50,
22 item_prefix: None,
23 disallowed_chars: vec![],
24 }
25 }
26}
27
28impl TextListPrimitive {
29 pub fn text_token_length(&mut self, text_token_length: u32) -> &mut Self {
30 self.text_token_length = text_token_length;
31 self
32 }
33
34 pub fn min_count(&mut self, min_count: u8) -> &mut Self {
36 if self.min_count != min_count {
37 self.min_count = min_count;
38 }
39 self
40 }
41
42 pub fn max_count(&mut self, max_count: u8) -> &mut Self {
44 if self.max_count != max_count {
45 self.max_count = max_count;
46 }
47 self
48 }
49
50 pub fn item_prefix<S: Into<String>>(&mut self, item_prefix: S) -> &mut Self {
51 self.item_prefix = Some(item_prefix.into());
52 self
53 }
54
55 pub fn disallowed_char(&mut self, disallowed_char: char) -> &mut Self {
56 self.disallowed_chars.push(disallowed_char);
57 self
58 }
59
60 pub fn disallowed_chars(&mut self, disallowed_chars: Vec<char>) -> &mut Self {
61 self.disallowed_chars.extend(disallowed_chars);
62 self
63 }
64
65 fn grammar_inner(&self) -> TextListGrammar {
66 Grammar::text_list()
67 .item_token_length(self.text_token_length)
68 .min_count(self.min_count)
69 .max_count(self.max_count)
70 .item_prefix_option(self.item_prefix.clone())
71 .disallowed_chars(self.disallowed_chars.clone())
72 }
73}
74
75pub struct TextListType(Vec<String>);
76
77impl std::fmt::Display for TextListType {
78 fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
79 write!(f, "{}", self.0.join(", "))
80 }
81}
82impl IntoIterator for TextListType {
83 type Item = String;
84 type IntoIter = IntoIter<String>;
85
86 fn into_iter(self) -> Self::IntoIter {
87 self.0.into_iter()
88 }
89}
90
91impl<'a> IntoIterator for &'a TextListType {
92 type Item = &'a String;
93 type IntoIter = Iter<'a, String>;
94
95 fn into_iter(self) -> Self::IntoIter {
96 self.0.iter()
97 }
98}
99
100impl<'a> IntoIterator for &'a mut TextListType {
101 type Item = &'a mut String;
102 type IntoIter = IterMut<'a, String>;
103
104 fn into_iter(self) -> Self::IntoIter {
105 self.0.iter_mut()
106 }
107}
108
109impl PrimitiveTrait for TextListPrimitive {
110 type PrimitiveResult = TextListType;
111
112 fn clear_primitive(&mut self) {}
113
114 fn type_description(&self, result_can_be_none: bool) -> &str {
115 if result_can_be_none {
116 "list items or 'None.'"
117 } else {
118 "list items"
119 }
120 }
121
122 fn solution_description(&self, result_can_be_none: bool) -> String {
123 if result_can_be_none {
124 format!(
125 "between {}-{} list items, or, possibly, 'None.'",
126 self.min_count, self.max_count
127 )
128 } else {
129 format!("between {}-{} list items", self.min_count, self.max_count)
130 }
131 }
132
133 fn stop_word_result_is_none(&self, result_can_be_none: bool) -> Option<String> {
134 if result_can_be_none {
135 Some("None.".to_string())
136 } else {
137 None
138 }
139 }
140
141 fn grammar(&self) -> Grammar {
142 self.grammar_inner().wrap()
143 }
144
145 fn parse_to_primitive(&self, content: &str) -> Result<Self::PrimitiveResult> {
146 let parsed: Self::PrimitiveResult =
147 TextListType(self.grammar_inner().grammar_parse(content)?);
148 Ok(parsed)
149 }
150}