valence_command/parsers/
entity_selector.rs
1use super::Parser;
2use crate::parsers::{CommandArg, CommandArgParseError, ParseInput};
3
4#[derive(Debug, Clone, PartialEq, Eq)]
5pub enum EntitySelector {
6 SimpleSelector(EntitySelectors),
7 ComplexSelector(EntitySelectors, String),
8}
9
10#[derive(Debug, Clone, PartialEq, Eq, Default)]
11pub enum EntitySelectors {
12 AllEntities,
13 SinglePlayer(String),
14 #[default]
15 AllPlayers,
16 SelfPlayer,
17 NearestPlayer,
18 RandomPlayer,
19}
20
21impl CommandArg for EntitySelector {
22 fn parse_arg(input: &mut ParseInput) -> Result<Self, CommandArgParseError> {
27 input.skip_whitespace();
28 let mut simple_selector = None;
29 while let Some(c) = input.peek() {
30 match c {
31 '@' => {
32 input.pop(); match input.pop() {
34 Some('e') => simple_selector = Some(EntitySelectors::AllEntities),
35 Some('a') => simple_selector = Some(EntitySelectors::AllPlayers),
36 Some('p') => simple_selector = Some(EntitySelectors::NearestPlayer),
37 Some('r') => simple_selector = Some(EntitySelectors::RandomPlayer),
38 Some('s') => simple_selector = Some(EntitySelectors::SelfPlayer),
39 _ => {
40 return Err(CommandArgParseError::InvalidArgument {
41 expected: "entity selector".to_owned(),
42 got: c.to_string(),
43 })
44 }
45 }
46 if input.peek() != Some('[') {
47 return Ok(EntitySelector::SimpleSelector(simple_selector.unwrap()));
49 }
50 }
51 '[' => {
52 input.pop();
53 if simple_selector.is_none() {
54 return Err(CommandArgParseError::InvalidArgument {
55 expected: "entity selector".to_owned(),
56 got: c.to_string(),
57 });
58 }
59 let mut s = String::new();
60 while let Some(c) = input.pop() {
61 if c == ']' {
62 return Ok(EntitySelector::ComplexSelector(
63 simple_selector.unwrap(),
64 s.trim().to_owned(),
65 ));
66 }
67
68 s.push(c);
69 }
70 }
71 _ => {
72 return Ok(EntitySelector::SimpleSelector(
73 EntitySelectors::SinglePlayer(String::parse_arg(input)?),
74 ))
75 }
76 }
77 }
78 Err(CommandArgParseError::InvalidArgLength)
79 }
80
81 fn display() -> Parser {
82 Parser::Entity {
83 only_players: false,
84 single: false,
85 }
86 }
87}
88
89#[cfg(test)]
90mod tests {
91 use super::*;
92
93 #[test]
94 fn test_entity_selector() {
95 let mut input = ParseInput::new("@e");
96 assert_eq!(
97 EntitySelector::parse_arg(&mut input).unwrap(),
98 EntitySelector::SimpleSelector(EntitySelectors::AllEntities)
99 );
100 assert!(input.is_done());
101
102 let mut input = ParseInput::new("@e[distance=..5]");
103 assert_eq!(
104 EntitySelector::parse_arg(&mut input).unwrap(),
105 EntitySelector::ComplexSelector(
106 EntitySelectors::AllEntities,
107 "distance=..5".to_owned()
108 )
109 );
110 assert!(input.is_done());
111
112 let mut input = ParseInput::new("@s[distance=..5");
113 assert!(EntitySelector::parse_arg(&mut input).is_err());
114 assert!(input.is_done());
115
116 let mut input = ParseInput::new("@r[distance=..5] hello");
117 assert_eq!(
118 EntitySelector::parse_arg(&mut input).unwrap(),
119 EntitySelector::ComplexSelector(
120 EntitySelectors::RandomPlayer,
121 "distance=..5".to_owned()
122 )
123 );
124 assert!(!input.is_done());
125
126 let mut input = ParseInput::new("@p[distance=..5]hello");
127 assert_eq!(
128 EntitySelector::parse_arg(&mut input).unwrap(),
129 EntitySelector::ComplexSelector(
130 EntitySelectors::NearestPlayer,
131 "distance=..5".to_owned()
132 )
133 );
134 assert!(!input.is_done());
135
136 let mut input = ParseInput::new("@e[distance=..5] hello world");
137 assert_eq!(
138 EntitySelector::parse_arg(&mut input).unwrap(),
139 EntitySelector::ComplexSelector(
140 EntitySelectors::AllEntities,
141 "distance=..5".to_owned()
142 )
143 );
144 assert!(!input.is_done());
145
146 let mut input = ParseInput::new("@e[distance=..5]hello world");
147 assert_eq!(
148 EntitySelector::parse_arg(&mut input).unwrap(),
149 EntitySelector::ComplexSelector(
150 EntitySelectors::AllEntities,
151 "distance=..5".to_owned()
152 )
153 );
154 assert!(!input.is_done());
155 }
156}