use super::common::{ImmutableString, Range, Ranged};
#[derive(Debug, PartialEq, Clone)]
pub enum Value {
StringLit(StringLit),
NumberLit(NumberLit),
BooleanLit(BooleanLit),
Object(Object),
Array(Array),
NullKeyword(NullKeyword),
}
#[derive(Debug, PartialEq, Clone)]
pub enum Node<'a> {
StringLit(&'a StringLit),
NumberLit(&'a NumberLit),
BooleanLit(&'a BooleanLit),
Object(&'a Object),
ObjectProp(&'a ObjectProp),
Array(&'a Array),
NullKeyword(&'a NullKeyword),
WordLit(&'a WordLit),
}
impl<'a> Node<'a> {
pub fn kind(&self) -> NodeKind {
match self {
Node::StringLit(_) => NodeKind::StringLit,
Node::NumberLit(_) => NodeKind::NumberLit,
Node::BooleanLit(_) => NodeKind::BooleanLit,
Node::Object(_) => NodeKind::Object,
Node::ObjectProp(_) => NodeKind::ObjectProp,
Node::Array(_) => NodeKind::Array,
Node::NullKeyword(_) => NodeKind::NullKeyword,
Node::WordLit(_) => NodeKind::WordLit,
}
}
}
#[derive(Debug, PartialEq, Clone, Copy)]
pub enum NodeKind {
StringLit,
NumberLit,
BooleanLit,
Object,
ObjectProp,
Array,
NullKeyword,
WordLit,
}
#[derive(Debug, PartialEq, Clone)]
pub struct StringLit {
pub range: Range,
pub value: ImmutableString,
}
#[derive(Debug, PartialEq, Clone)]
pub struct WordLit {
pub range: Range,
pub value: ImmutableString,
}
#[derive(Debug, PartialEq, Clone)]
pub struct NumberLit {
pub range: Range,
pub value: ImmutableString,
}
#[derive(Debug, PartialEq, Clone)]
pub struct BooleanLit {
pub range: Range,
pub value: bool,
}
#[derive(Debug, PartialEq, Clone)]
pub struct NullKeyword {
pub range: Range,
}
#[derive(Debug, PartialEq, Clone)]
pub struct Object {
pub range: Range,
pub properties: Vec<ObjectProp>,
}
#[derive(Debug, PartialEq, Clone)]
pub struct ObjectProp {
pub range: Range,
pub name: ObjectPropName,
pub value: Value,
}
#[derive(Debug, PartialEq, Clone)]
pub enum ObjectPropName {
String(StringLit),
Word(WordLit),
}
impl ObjectPropName {
pub fn to_string(self) -> String {
match self {
ObjectPropName::String(lit) => lit.value.to_string(),
ObjectPropName::Word(lit) => lit.value.to_string(),
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct Array {
pub range: Range,
pub elements: Vec<Value>,
}
#[derive(Debug, PartialEq, Clone)]
pub enum CommentKind {
Line,
Block,
}
#[derive(Debug, PartialEq, Clone)]
pub enum Comment {
Line(CommentLine),
Block(CommentBlock),
}
impl Comment {
pub fn text(&self) -> &str {
match self {
Comment::Line(line) => line.text.as_ref(),
Comment::Block(line) => line.text.as_ref(),
}
}
pub fn kind(&self) -> CommentKind {
match self {
Comment::Line(_) => CommentKind::Line,
Comment::Block(_) => CommentKind::Block,
}
}
}
impl Ranged for Comment {
fn range(&self) -> &Range {
match self {
Comment::Line(line) => line.range(),
Comment::Block(line) => line.range(),
}
}
}
#[derive(Debug, PartialEq, Clone)]
pub struct CommentLine {
pub range: Range,
pub text: ImmutableString,
}
#[derive(Debug, PartialEq, Clone)]
pub struct CommentBlock {
pub range: Range,
pub text: ImmutableString,
}
impl<'a> From<&'a ObjectPropName> for Node<'a> {
fn from(object_prop_name: &'a ObjectPropName) -> Node<'a> {
match object_prop_name {
ObjectPropName::String(lit) => lit.into(),
ObjectPropName::Word(lit) => lit.into(),
}
}
}
impl Ranged for ObjectPropName {
fn range(&self) -> &Range {
match self {
ObjectPropName::String(lit) => lit.range(),
ObjectPropName::Word(lit) => lit.range(),
}
}
}
macro_rules! impl_ranged {
($($node_name:ident),*) => {
$(
impl Ranged for $node_name {
fn range(&self) -> &Range {
&self.range
}
}
)*
};
}
impl_ranged![
StringLit,
WordLit,
NumberLit,
BooleanLit,
NullKeyword,
Object,
ObjectProp,
Array,
CommentLine,
CommentBlock
];
impl Ranged for Value {
fn range(&self) -> &Range {
match self {
Value::Array(node) => node.range(),
Value::BooleanLit(node) => node.range(),
Value::NullKeyword(node) => node.range(),
Value::NumberLit(node) => node.range(),
Value::Object(node) => node.range(),
Value::StringLit(node) => node.range(),
}
}
}
macro_rules! generate_node {
($($node_name:ident),*) => {
impl<'a> Ranged for Node<'a> {
fn range(&self) -> &Range {
match self {
$(Node::$node_name(node) => node.range()),*
}
}
}
$(
impl<'a> From<&'a $node_name> for Node<'a> {
fn from(node: &'a $node_name) -> Node<'a> {
Node::$node_name(node)
}
}
)*
};
}
generate_node![
StringLit,
WordLit,
NumberLit,
BooleanLit,
NullKeyword,
Object,
ObjectProp,
Array
];
impl<'a> From<&'a Value> for Node<'a> {
fn from(value: &'a Value) -> Node<'a> {
match value {
Value::Array(node) => Node::Array(node),
Value::BooleanLit(node) => Node::BooleanLit(node),
Value::NullKeyword(node) => Node::NullKeyword(node),
Value::NumberLit(node) => Node::NumberLit(node),
Value::Object(node) => Node::Object(node),
Value::StringLit(node) => Node::StringLit(node),
}
}
}