1extern crate nom_packrat_macros;
34#[doc(inline)]
35pub use nom_packrat_macros::packrat_parser;
36use std::collections::{HashMap, VecDeque};
37use std::hash::Hash;
38
39#[macro_export]
44macro_rules! init {
45 () => {
46 crate::PACKRAT_STORAGE.with(|storage| storage.borrow_mut().clear())
47 };
48}
49
50#[macro_export]
66macro_rules! storage {
67 ($t:ty) => {
68 thread_local!(
69 pub(crate) static PACKRAT_STORAGE: core::cell::RefCell<
70 nom_packrat::PackratStorage<$t, ()>
71 > = {
72 core::cell::RefCell::new(nom_packrat::PackratStorage::new(None))
73 }
74 );
75 };
76 ($t:ty, $u:ty) => {
77 thread_local!(
78 pub(crate) static PACKRAT_STORAGE: core::cell::RefCell<
79 nom_packrat::PackratStorage<$t, $u>
80 > = {
81 core::cell::RefCell::new(nom_packrat::PackratStorage::new(None))
82 }
83 );
84 };
85 ($t:ty, $n:expr) => {
86 thread_local!(
87 pub(crate) static PACKRAT_STORAGE: core::cell::RefCell<
88 nom_packrat::PackratStorage<$t, ()>
89 > = {
90 core::cell::RefCell::new(nom_packrat::PackratStorage::new(Some($n)))
91 }
92 );
93 };
94 ($t:ty, $u:ty, $n:expr) => {
95 thread_local!(
96 pub(crate) static PACKRAT_STORAGE: core::cell::RefCell<
97 nom_packrat::PackratStorage<$t, $u>
98 > = {
99 core::cell::RefCell::new(nom_packrat::PackratStorage::new(Some($n)))
100 }
101 );
102 };
103}
104
105pub struct PackratStorage<T, U> {
106 size: Option<usize>,
107 map: HashMap<(&'static str, *const u8, U), Option<(T, usize)>>,
108 keys: VecDeque<(&'static str, *const u8, U)>,
109}
110
111impl<T, U> PackratStorage<T, U>
112where
113 U: Eq + Hash + Clone,
114{
115 pub fn new(size: Option<usize>) -> Self {
116 let init_size = size.unwrap_or_else(|| 0);
117 PackratStorage {
118 size,
119 map: HashMap::with_capacity(init_size),
120 keys: VecDeque::with_capacity(init_size),
121 }
122 }
123
124 pub fn get(&self, key: &(&'static str, *const u8, U)) -> Option<&Option<(T, usize)>> {
125 self.map.get(key)
126 }
127
128 pub fn insert(&mut self, key: (&'static str, *const u8, U), value: Option<(T, usize)>) {
129 if let Some(size) = self.size {
130 if self.keys.len() > size - 1 {
131 let key = self.keys.pop_front().unwrap();
132 self.map.remove(&key);
133 }
134 }
135
136 self.keys.push_back(key.clone());
137 self.map.insert(key, value);
138 }
139
140 pub fn clear(&mut self) {
141 self.map.clear();
142 self.keys.clear();
143 }
144}
145
146pub trait HasExtraState<T> {
147 fn get_extra_state(&self) -> T;
148}
149
150impl HasExtraState<()> for &str {
151 fn get_extra_state(&self) -> () {
152 ()
153 }
154}
155
156impl HasExtraState<()> for &[u8] {
157 fn get_extra_state(&self) -> () {
158 ()
159 }
160}
161
162impl<T> HasExtraState<()> for nom_locate::LocatedSpan<T, ()> {
163 fn get_extra_state(&self) -> () {
164 ()
165 }
166}
167
168impl<T, U, V> HasExtraState<T> for nom_locate::LocatedSpan<U, V>
169where
170 V: HasExtraState<T>,
171{
172 fn get_extra_state(&self) -> T {
173 self.extra.get_extra_state()
174 }
175}