summaryrefslogtreecommitdiff
path: root/vndbapi-msg/src/msg.rs
diff options
context:
space:
mode:
Diffstat (limited to 'vndbapi-msg/src/msg.rs')
-rw-r--r--vndbapi-msg/src/msg.rs130
1 files changed, 130 insertions, 0 deletions
diff --git a/vndbapi-msg/src/msg.rs b/vndbapi-msg/src/msg.rs
new file mode 100644
index 0000000..ead8ac0
--- /dev/null
+++ b/vndbapi-msg/src/msg.rs
@@ -0,0 +1,130 @@
+use std::fmt;
+use serde_json::Value;
+
+use parser::{parse_filter,parse_arg,parse_message};
+
+
+#[derive(Debug,Clone)]
+pub enum Arg {
+ BareString(String),
+ Json(Value),
+ Filter(Filter),
+}
+
+#[derive(Debug,Clone)]
+pub struct Message {
+ name: String,
+ args: Vec<Arg>,
+}
+
+
+#[derive(Debug,Clone)]
+pub enum Filter {
+ And(Box<Filter>, Box<Filter>),
+ Or(Box<Filter>, Box<Filter>),
+ Expr(String, Op, Value),
+}
+
+
+#[derive(Debug,Clone,Copy,PartialEq,Eq)]
+pub enum Op {
+ Eq,
+ NEq,
+ Le,
+ LEq,
+ Gt,
+ GEq,
+ Fuzzy,
+}
+
+
+impl Op {
+ pub fn as_str(self) -> &'static str {
+ match self {
+ Op::Eq => "=",
+ Op::NEq => "!=",
+ Op::Le => "<",
+ Op::LEq => "<=",
+ Op::Gt => ">",
+ Op::GEq => ">=",
+ Op::Fuzzy => "~",
+ }
+ }
+}
+
+
+impl fmt::Display for Op {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(self.as_str())
+ }
+}
+
+
+impl fmt::Display for Filter {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ &Filter::And(ref x, ref y) => write!(f, "({} and {})", x, y),
+ &Filter::Or(ref x, ref y) => write!(f, "({} or {})", x, y),
+ &Filter::Expr(ref n, o, ref v) => write!(f, "({} {} {})", n, o, v),
+ }
+ }
+}
+
+
+impl fmt::Display for Arg {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ match self {
+ &Arg::BareString(ref x) => f.write_str(&x),
+ &Arg::Json(ref x) => write!(f, "{}", x),
+ &Arg::Filter(ref x) => write!(f, "{}", x),
+ }
+ }
+}
+
+
+impl fmt::Display for Message {
+ fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
+ f.write_str(&self.name)?;
+ for a in self.args.iter() {
+ f.write_str(" ")?;
+ write!(f, "{}", a)?;
+ }
+ Ok(())
+ }
+}
+
+
+impl Filter {
+ pub fn parse(s: &str) -> Result<(Filter, &str), &'static str> {
+ parse_filter(s)
+ }
+}
+
+
+impl Arg {
+ pub fn parse(s: &str) -> Result<(Arg, &str), &'static str> {
+ parse_arg(s)
+ }
+}
+
+
+impl Message {
+ pub fn parse(s: &str) -> Result<Message, &'static str> {
+ parse_message(s)
+ }
+
+ pub fn new(name: &str) -> Result<Message, &'static str> {
+ if name.contains(|c| !(c >= 'a' && c <= 'z')) {
+ return Err("Invalid message name")
+ }
+ Ok(Message{name: name.to_string(), args: Vec::new()})
+ }
+
+ pub fn push_arg(mut self, arg: Arg) -> Message { self.args.push(arg); self }
+ pub fn push_bare (self, arg: &str ) -> Message { self.push_arg(Arg::BareString(arg.to_string())) }
+ pub fn push_json (self, arg: Value ) -> Message { self.push_arg(Arg::Json(arg)) }
+ pub fn push_filter(self, arg: Filter) -> Message { self.push_arg(Arg::Filter(arg)) }
+
+ pub fn name(&self) -> &str { &self.name }
+ pub fn args(&self) -> &[Arg] { &self.args }
+}