blob: f55e39849b2201f3bdfbd45a4f481b4568bf919c [file] [log] [blame]
Alex Crichtonccbb45d2017-05-23 10:58:24 -07001use std::fmt;
2use std::hash::{Hash, Hasher};
3
David Tolnay98942562017-12-26 21:24:35 -05004use proc_macro2::{self, Span, Literal, TokenNode, Term};
Alex Crichtonccbb45d2017-05-23 10:58:24 -07005
David Tolnay98942562017-12-26 21:24:35 -05006use TokenTree;
Alex Crichtonccbb45d2017-05-23 10:58:24 -07007
8#[derive(Clone)]
9pub struct Lit {
10 pub value: LitKind,
11 pub span: Span,
12}
13
14#[derive(Clone)]
15pub enum LitKind {
16 Bool(bool),
17 Other(Literal),
18}
19
20impl Lit {
21 pub fn into_token_tree(self) -> TokenTree {
22 let kind = match self.value {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -070023 LitKind::Bool(true) => TokenNode::Term(Term::intern("true")),
24 LitKind::Bool(false) => TokenNode::Term(Term::intern("false")),
25 LitKind::Other(l) => TokenNode::Literal(l),
Alex Crichtonccbb45d2017-05-23 10:58:24 -070026 };
27 TokenTree(proc_macro2::TokenTree {
David Tolnay98942562017-12-26 21:24:35 -050028 span: self.span,
Alex Crichtonccbb45d2017-05-23 10:58:24 -070029 kind: kind,
30 })
Alex Crichton62a0a592017-05-22 13:58:53 -070031 }
David Tolnayf4bbbd92016-09-23 14:41:55 -070032}
33
Alex Crichtonccbb45d2017-05-23 10:58:24 -070034impl fmt::Display for Lit {
35 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
36 fmt::Display::fmt(&self.value, f)
Alex Crichton62a0a592017-05-22 13:58:53 -070037 }
David Tolnayf4bbbd92016-09-23 14:41:55 -070038}
39
Alex Crichtonccbb45d2017-05-23 10:58:24 -070040impl fmt::Debug for Lit {
41 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
42 fmt::Display::fmt(&self.value, f)
Pascal Hertleif36342c52016-10-19 10:31:42 +020043 }
44}
45
Alex Crichtonccbb45d2017-05-23 10:58:24 -070046impl PartialEq for Lit {
47 fn eq(&self, other: &Lit) -> bool {
48 self.value == other.value
Pascal Hertleif36342c52016-10-19 10:31:42 +020049 }
50}
51
Alex Crichtonccbb45d2017-05-23 10:58:24 -070052impl Eq for Lit {}
53
54impl Hash for Lit {
55 fn hash<H: Hasher>(&self, hasher: &mut H) {
56 self.value.hash(hasher)
Pascal Hertleif36342c52016-10-19 10:31:42 +020057 }
58}
59
Alex Crichtonccbb45d2017-05-23 10:58:24 -070060impl fmt::Display for LitKind {
61 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
62 match *self {
63 LitKind::Bool(b) => b.fmt(f),
64 LitKind::Other(ref l) => l.fmt(f),
65 }
Pascal Hertleif36342c52016-10-19 10:31:42 +020066 }
67}
68
Alex Crichtonccbb45d2017-05-23 10:58:24 -070069impl fmt::Debug for LitKind {
70 fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
71 match *self {
72 LitKind::Bool(b) => b.fmt(f),
73 LitKind::Other(ref l) => fmt::Display::fmt(l, f),
74 }
Pascal Hertleif36342c52016-10-19 10:31:42 +020075 }
76}
77
Alex Crichtonccbb45d2017-05-23 10:58:24 -070078impl PartialEq for LitKind {
79 fn eq(&self, other: &LitKind) -> bool {
80 match (self, other) {
81 (&LitKind::Bool(b1), &LitKind::Bool(b2)) => b1 == b2,
82 (&LitKind::Other(ref l1), &LitKind::Other(ref l2)) => {
83 l1.to_string() == l2.to_string()
Pascal Hertleif36342c52016-10-19 10:31:42 +020084 }
Alex Crichtonccbb45d2017-05-23 10:58:24 -070085 _ => false,
86 }
Alex Crichton2e0229c2017-05-23 09:34:50 -070087 }
David Tolnay5fe14fc2017-01-27 16:22:08 -080088}
89
Alex Crichtonccbb45d2017-05-23 10:58:24 -070090impl Eq for LitKind {}
David Tolnay5fe14fc2017-01-27 16:22:08 -080091
Alex Crichtonccbb45d2017-05-23 10:58:24 -070092impl Hash for LitKind {
93 fn hash<H: Hasher>(&self, hasher: &mut H) {
94 match *self {
95 LitKind::Bool(b) => (0u8, b).hash(hasher),
96 LitKind::Other(ref l) => (1u8, l.to_string()).hash(hasher),
97 }
Alex Crichton2e0229c2017-05-23 09:34:50 -070098 }
David Tolnay5fe14fc2017-01-27 16:22:08 -080099}
100
101#[cfg(feature = "parsing")]
David Tolnayf4bbbd92016-09-23 14:41:55 -0700102pub mod parsing {
103 use super::*;
David Tolnayc5ab8c62017-12-26 16:43:39 -0500104 use synom::Synom;
105 use cursor::Cursor;
106 use {PResult, parse_error};
David Tolnayf4bbbd92016-09-23 14:41:55 -0700107
Alex Crichton954046c2017-05-30 21:49:42 -0700108 impl Synom for Lit {
Michael Layzell92639a52017-06-01 00:07:44 -0400109 fn parse(input: Cursor) -> PResult<Self> {
Michael Layzell589a8f42017-06-02 19:47:01 -0400110 match input.literal() {
111 Some((rest, span, lit)) => {
112 Ok((rest, Lit {
David Tolnay98942562017-12-26 21:24:35 -0500113 span: span,
Michael Layzell589a8f42017-06-02 19:47:01 -0400114 value: LitKind::Other(lit)
115 }))
116 }
117 _ => match input.word() {
118 Some((rest, span, sym)) => {
119 let kind = if sym.as_str() == "true" {
120 LitKind::Bool(true)
121 } else if sym.as_str() == "false" {
122 LitKind::Bool(false)
123 } else {
124 return parse_error();
125 };
126
127 Ok((rest, Lit {
David Tolnay98942562017-12-26 21:24:35 -0500128 span: span,
Michael Layzell589a8f42017-06-02 19:47:01 -0400129 value: kind
130 }))
131 }
132 _ => parse_error(),
133 }
134 }
David Tolnayfa0edf22016-09-23 22:58:24 -0700135 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700136 }
137}
138
139#[cfg(feature = "printing")]
140mod printing {
141 use super::*;
142 use quote::{Tokens, ToTokens};
Alex Crichtonccbb45d2017-05-23 10:58:24 -0700143
David Tolnayf4bbbd92016-09-23 14:41:55 -0700144 impl ToTokens for Lit {
145 fn to_tokens(&self, tokens: &mut Tokens) {
Alex Crichtonf9e8f1a2017-07-05 18:20:44 -0700146 self.clone().into_token_tree().to_tokens(tokens)
David Tolnayf17fd2f2016-10-07 23:38:08 -0700147 }
148 }
David Tolnayf4bbbd92016-09-23 14:41:55 -0700149}