2020-05-16 16:56:17 -04:00
|
|
|
use std::fmt::{self, Display, Write};
|
2020-01-04 22:55:04 -05:00
|
|
|
|
2020-01-06 00:25:40 -05:00
|
|
|
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
|
|
|
pub enum Op {
|
|
|
|
Equal,
|
|
|
|
NotEqual,
|
2020-01-12 12:18:44 -05:00
|
|
|
GreaterThan,
|
2020-01-06 00:25:40 -05:00
|
|
|
GreaterThanEqual,
|
2020-01-12 12:18:44 -05:00
|
|
|
LessThan,
|
2020-01-06 00:25:40 -05:00
|
|
|
LessThanEqual,
|
2020-01-25 09:56:27 -05:00
|
|
|
Plus,
|
|
|
|
Minus,
|
|
|
|
Mul,
|
|
|
|
Div,
|
|
|
|
Rem,
|
2020-04-01 17:37:07 -04:00
|
|
|
And,
|
|
|
|
Or,
|
|
|
|
Not,
|
2020-01-06 00:25:40 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for Op {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
match self {
|
2020-01-18 19:11:19 -05:00
|
|
|
Self::Equal => write!(f, "=="),
|
|
|
|
Self::NotEqual => write!(f, "!="),
|
|
|
|
Self::GreaterThanEqual => write!(f, ">="),
|
|
|
|
Self::LessThanEqual => write!(f, "<="),
|
|
|
|
Self::GreaterThan => write!(f, ">"),
|
|
|
|
Self::LessThan => write!(f, "<"),
|
2020-01-25 09:56:27 -05:00
|
|
|
Self::Plus => write!(f, "+"),
|
|
|
|
Self::Minus => write!(f, "-"),
|
|
|
|
Self::Mul => write!(f, "*"),
|
|
|
|
Self::Div => write!(f, "/"),
|
|
|
|
Self::Rem => write!(f, "%"),
|
2020-04-01 17:37:07 -04:00
|
|
|
Self::And => write!(f, "and"),
|
|
|
|
Self::Or => write!(f, "or"),
|
|
|
|
Self::Not => write!(f, "not"),
|
2020-01-06 00:25:40 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-04-01 15:32:52 -04:00
|
|
|
impl Op {
|
|
|
|
/// Get order of precedence for an operator
|
|
|
|
///
|
|
|
|
/// Higher numbers are evaluated first.
|
|
|
|
/// Do not rely on the number itself, but rather the size relative to other numbers
|
|
|
|
///
|
|
|
|
/// If precedence is equal, the leftmost operation is evaluated first
|
2020-04-01 18:09:58 -04:00
|
|
|
pub fn precedence(self) -> usize {
|
2020-04-01 15:32:52 -04:00
|
|
|
match self {
|
2020-04-01 17:37:07 -04:00
|
|
|
Self::And | Self::Or | Self::Not => 0,
|
2020-04-01 15:32:52 -04:00
|
|
|
Self::Equal
|
|
|
|
| Self::NotEqual
|
|
|
|
| Self::GreaterThan
|
|
|
|
| Self::GreaterThanEqual
|
|
|
|
| Self::LessThan
|
2020-04-01 17:37:07 -04:00
|
|
|
| Self::LessThanEqual => 1,
|
|
|
|
Self::Plus | Self::Minus => 2,
|
|
|
|
Self::Mul | Self::Div | Self::Rem => 3,
|
2020-04-01 15:32:52 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-01-26 16:23:37 -05:00
|
|
|
#[derive(Debug, Copy, Clone, Eq, PartialEq)]
|
|
|
|
pub(crate) enum QuoteKind {
|
2020-04-18 13:19:30 -04:00
|
|
|
Quoted,
|
2020-01-26 16:23:37 -05:00
|
|
|
None,
|
|
|
|
}
|
|
|
|
|
2020-02-02 14:46:58 -05:00
|
|
|
impl Display for QuoteKind {
|
|
|
|
#[inline]
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
match self {
|
2020-05-06 12:07:27 -04:00
|
|
|
Self::Quoted => f.write_char('"'),
|
|
|
|
Self::None => Ok(()),
|
2020-02-02 14:46:58 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-03-23 19:56:24 -04:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
|
|
pub(crate) enum Brackets {
|
|
|
|
None,
|
|
|
|
Bracketed,
|
|
|
|
}
|
|
|
|
|
2020-02-08 16:07:37 -05:00
|
|
|
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
|
|
|
|
pub(crate) enum ListSeparator {
|
|
|
|
Space,
|
|
|
|
Comma,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl ListSeparator {
|
|
|
|
pub fn as_str(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Self::Space => " ",
|
|
|
|
Self::Comma => ", ",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
pub fn name(self) -> &'static str {
|
|
|
|
match self {
|
|
|
|
Self::Space => "space",
|
|
|
|
Self::Comma => "comma",
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-04-26 23:52:32 -04:00
|
|
|
|
2020-05-22 18:21:18 -04:00
|
|
|
#[derive(Debug, Clone, Eq, PartialEq, Hash)]
|
|
|
|
pub(crate) struct Identifier(String);
|
|
|
|
|
|
|
|
impl From<String> for Identifier {
|
|
|
|
fn from(s: String) -> Identifier {
|
|
|
|
Identifier(s.replace('_', "-"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&String> for Identifier {
|
|
|
|
fn from(s: &String) -> Identifier {
|
|
|
|
Identifier(s.replace('_', "-"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<&str> for Identifier {
|
|
|
|
fn from(s: &str) -> Identifier {
|
|
|
|
Identifier(s.replace('_', "-"))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
impl Display for Identifier {
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
|
|
|
write!(f, "{}", self.0)
|
|
|
|
}
|
|
|
|
}
|
2020-05-22 22:43:26 -04:00
|
|
|
|
|
|
|
impl Default for Identifier {
|
|
|
|
fn default() -> Self {
|
|
|
|
Self(String::new())
|
|
|
|
}
|
|
|
|
}
|
2020-05-23 13:53:24 -04:00
|
|
|
|
|
|
|
impl Identifier {
|
2020-05-31 05:32:19 -04:00
|
|
|
#[allow(clippy::missing_const_for_fn)]
|
2020-05-23 13:53:24 -04:00
|
|
|
pub fn into_inner(self) -> String {
|
|
|
|
self.0
|
|
|
|
}
|
2020-05-23 14:08:40 -04:00
|
|
|
}
|
2020-07-02 10:40:43 -04:00
|
|
|
|
|
|
|
/// Returns `name` without a vendor prefix.
|
|
|
|
///
|
|
|
|
/// If `name` has no vendor prefix, it's returned as-is.
|
|
|
|
pub(crate) fn unvendor(name: &str) -> &str {
|
|
|
|
let bytes = name.as_bytes();
|
|
|
|
|
|
|
|
if bytes.len() < 2 {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
if bytes.get(0_usize) != Some(&b'-') || bytes.get(1_usize) == Some(&b'-') {
|
|
|
|
return name;
|
|
|
|
}
|
|
|
|
|
|
|
|
for i in 2..bytes.len() {
|
|
|
|
if bytes.get(i) == Some(&b'-') {
|
|
|
|
return &name[i + 1..];
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
name
|
|
|
|
}
|