rusteerio 0.0.0-stage → 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (206) hide show
  1. package/CONTRIBUTING.md +73 -0
  2. package/Cargo.lock +1051 -0
  3. package/Cargo.toml +36 -0
  4. package/LICENSE +21 -0
  5. package/README.md +252 -2
  6. package/RELEASING.md +138 -0
  7. package/THIRD_PARTY_NOTICES.md +7443 -0
  8. package/build.rs +3 -0
  9. package/dist/chunk-DKULX6VO.mjs +3185 -0
  10. package/dist/chunk-DKULX6VO.mjs.map +1 -0
  11. package/dist/chunk-OHPGEY3E.mjs +32 -0
  12. package/dist/chunk-OHPGEY3E.mjs.map +1 -0
  13. package/dist/index.cjs +3230 -0
  14. package/dist/index.cjs.map +1 -0
  15. package/dist/index.d.mts +113 -0
  16. package/dist/index.d.ts +113 -0
  17. package/dist/index.mjs +38 -0
  18. package/dist/index.mjs.map +1 -0
  19. package/dist/slim.cjs +2441 -0
  20. package/dist/slim.cjs.map +1 -0
  21. package/dist/slim.d.mts +11 -0
  22. package/dist/slim.d.ts +11 -0
  23. package/dist/slim.mjs +19 -0
  24. package/dist/slim.mjs.map +1 -0
  25. package/dist/types-BP6TpxE5.d.mts +532 -0
  26. package/dist/types-BP6TpxE5.d.ts +532 -0
  27. package/dist/utils.cjs +61 -0
  28. package/dist/utils.cjs.map +1 -0
  29. package/dist/utils.d.mts +13 -0
  30. package/dist/utils.d.ts +13 -0
  31. package/dist/utils.mjs +17 -0
  32. package/dist/utils.mjs.map +1 -0
  33. package/native/src/arena.rs +1781 -0
  34. package/native/src/attributes.rs +923 -0
  35. package/native/src/codec.rs +172 -0
  36. package/native/src/diagnostics.rs +1249 -0
  37. package/native/src/extraction.rs +226 -0
  38. package/native/src/gc.rs +166 -0
  39. package/native/src/hook_sink.rs +727 -0
  40. package/native/src/hook_stream.rs +513 -0
  41. package/native/src/lib.rs +2095 -0
  42. package/native/src/location.rs +392 -0
  43. package/native/src/runtime.rs +189 -0
  44. package/native/src/selector.rs +1287 -0
  45. package/native/src/sink.rs +261 -0
  46. package/native/src/stream.rs +334 -0
  47. package/native/src/tokenizer.rs +355 -0
  48. package/native/src/tracker.rs +232 -0
  49. package/native/vendor/README.md +25 -0
  50. package/native/vendor/html5ever-0.35.0/.cargo_vcs_info.json +6 -0
  51. package/native/vendor/html5ever-0.35.0/Cargo.lock +828 -0
  52. package/native/vendor/html5ever-0.35.0/Cargo.toml +85 -0
  53. package/native/vendor/html5ever-0.35.0/LICENSE-APACHE +201 -0
  54. package/native/vendor/html5ever-0.35.0/LICENSE-MIT +25 -0
  55. package/native/vendor/html5ever-0.35.0/README.md +60 -0
  56. package/native/vendor/html5ever-0.35.0/benches/html5ever.rs +86 -0
  57. package/native/vendor/html5ever-0.35.0/data/bench/lipsum-zh.html +19 -0
  58. package/native/vendor/html5ever-0.35.0/data/bench/lipsum.html +40 -0
  59. package/native/vendor/html5ever-0.35.0/data/bench/medium-fragment.html +24 -0
  60. package/native/vendor/html5ever-0.35.0/data/bench/small-fragment.html +7 -0
  61. package/native/vendor/html5ever-0.35.0/data/bench/strong.html +1 -0
  62. package/native/vendor/html5ever-0.35.0/data/bench/tiny-fragment.html +1 -0
  63. package/native/vendor/html5ever-0.35.0/examples/arena.rs +356 -0
  64. package/native/vendor/html5ever-0.35.0/examples/capi/tokenize.c +74 -0
  65. package/native/vendor/html5ever-0.35.0/examples/noop-tokenize.rs +47 -0
  66. package/native/vendor/html5ever-0.35.0/examples/noop-tree-builder.rs +132 -0
  67. package/native/vendor/html5ever-0.35.0/examples/print-tree-actions.rs +185 -0
  68. package/native/vendor/html5ever-0.35.0/examples/tokenize.rs +111 -0
  69. package/native/vendor/html5ever-0.35.0/src/driver.rs +148 -0
  70. package/native/vendor/html5ever-0.35.0/src/lib.rs +30 -0
  71. package/native/vendor/html5ever-0.35.0/src/macros.rs +34 -0
  72. package/native/vendor/html5ever-0.35.0/src/serialize/mod.rs +255 -0
  73. package/native/vendor/html5ever-0.35.0/src/tokenizer/char_ref/mod.rs +451 -0
  74. package/native/vendor/html5ever-0.35.0/src/tokenizer/interface.rs +99 -0
  75. package/native/vendor/html5ever-0.35.0/src/tokenizer/mod.rs +2305 -0
  76. package/native/vendor/html5ever-0.35.0/src/tokenizer/states.rs +97 -0
  77. package/native/vendor/html5ever-0.35.0/src/tree_builder/data.rs +170 -0
  78. package/native/vendor/html5ever-0.35.0/src/tree_builder/mod.rs +1848 -0
  79. package/native/vendor/html5ever-0.35.0/src/tree_builder/rules.rs +1494 -0
  80. package/native/vendor/html5ever-0.35.0/src/tree_builder/tag_sets.rs +114 -0
  81. package/native/vendor/html5ever-0.35.0/src/tree_builder/types.rs +91 -0
  82. package/native/vendor/html5ever-0.35.0/src/util/str.rs +52 -0
  83. package/native/vendor/html5gum-0.8.4/Cargo.lock +1006 -0
  84. package/native/vendor/html5gum-0.8.4/Cargo.toml +109 -0
  85. package/native/vendor/html5gum-0.8.4/LICENSE +19 -0
  86. package/native/vendor/html5gum-0.8.4/README.md +110 -0
  87. package/native/vendor/html5gum-0.8.4/benches/files/0050.html +2131 -0
  88. package/native/vendor/html5gum-0.8.4/benches/files/6D30.html +1004 -0
  89. package/native/vendor/html5gum-0.8.4/benches/files.rs +32 -0
  90. package/native/vendor/html5gum-0.8.4/benches/patterns.rs +31 -0
  91. package/native/vendor/html5gum-0.8.4/src/arrayvec.rs +29 -0
  92. package/native/vendor/html5gum-0.8.4/src/char_validator.rs +134 -0
  93. package/native/vendor/html5gum-0.8.4/src/emitters/callback.rs +676 -0
  94. package/native/vendor/html5gum-0.8.4/src/emitters/default.rs +207 -0
  95. package/native/vendor/html5gum-0.8.4/src/emitters/emitter.rs +344 -0
  96. package/native/vendor/html5gum-0.8.4/src/emitters/html5ever.rs +306 -0
  97. package/native/vendor/html5gum-0.8.4/src/emitters/mod.rs +25 -0
  98. package/native/vendor/html5gum-0.8.4/src/entities.rs +3342 -0
  99. package/native/vendor/html5gum-0.8.4/src/error.rs +96 -0
  100. package/native/vendor/html5gum-0.8.4/src/htmlstring.rs +130 -0
  101. package/native/vendor/html5gum-0.8.4/src/lib.rs +66 -0
  102. package/native/vendor/html5gum-0.8.4/src/machine.rs +2136 -0
  103. package/native/vendor/html5gum-0.8.4/src/machine_helper.rs +277 -0
  104. package/native/vendor/html5gum-0.8.4/src/read_helper.rs +244 -0
  105. package/native/vendor/html5gum-0.8.4/src/reader.rs +440 -0
  106. package/native/vendor/html5gum-0.8.4/src/span.rs +98 -0
  107. package/native/vendor/html5gum-0.8.4/src/state.rs +16 -0
  108. package/native/vendor/html5gum-0.8.4/src/testutils.rs +71 -0
  109. package/native/vendor/html5gum-0.8.4/src/tokenizer.rs +189 -0
  110. package/native/vendor/html5gum-0.8.4/src/utils.rs +88 -0
  111. package/native/vendor/markup5ever-0.35.0/.cargo_vcs_info.json +6 -0
  112. package/native/vendor/markup5ever-0.35.0/Cargo.toml +45 -0
  113. package/native/vendor/markup5ever-0.35.0/LICENSE-APACHE +201 -0
  114. package/native/vendor/markup5ever-0.35.0/LICENSE-MIT +25 -0
  115. package/native/vendor/markup5ever-0.35.0/interface/mod.rs +422 -0
  116. package/native/vendor/markup5ever-0.35.0/interface/tree_builder.rs +280 -0
  117. package/native/vendor/markup5ever-0.35.0/lib.rs +59 -0
  118. package/native/vendor/markup5ever-0.35.0/serialize.rs +77 -0
  119. package/native/vendor/markup5ever-0.35.0/util/buffer_queue.rs +333 -0
  120. package/native/vendor/markup5ever-0.35.0/util/smallcharset.rs +88 -0
  121. package/package.json +137 -4
  122. package/rusteerio.darwin-arm64.node +0 -0
  123. package/rusteerio.darwin-x64.node +0 -0
  124. package/rusteerio.linux-arm64-gnu.node +0 -0
  125. package/rusteerio.linux-arm64-musl.node +0 -0
  126. package/rusteerio.linux-x64-gnu.node +0 -0
  127. package/rusteerio.linux-x64-musl.node +0 -0
  128. package/rusteerio.win32-arm64-msvc.node +0 -0
  129. package/rusteerio.win32-x64-msvc.node +0 -0
  130. package/scripts/check-native.mjs +15 -0
  131. package/scripts/check-release.mjs +235 -0
  132. package/scripts/fix-declarations.mjs +27 -0
  133. package/scripts/generate-notices.mjs +176 -0
  134. package/scripts/notices/README.md +13 -0
  135. package/scripts/notices/cheerio-MIT.txt +21 -0
  136. package/scripts/notices/html5ever-AUTHORS.txt +20 -0
  137. package/scripts/notices/html5ever-COPYRIGHT.txt +8 -0
  138. package/scripts/notices/html5ever-LICENSE-APACHE.txt +201 -0
  139. package/scripts/notices/html5ever-LICENSE-MIT.txt +25 -0
  140. package/scripts/notices/napi-rs-MIT.txt +43 -0
  141. package/scripts/notices/neon-MIT.txt +19 -0
  142. package/scripts/notices/runtime-01c266bced4a434da005.txt +3 -0
  143. package/scripts/notices/runtime-0a54e647fe54104658b5.txt +14 -0
  144. package/scripts/notices/runtime-0b74dfa0bcee5c420c6b.txt +25 -0
  145. package/scripts/notices/runtime-0d542e0c8804e39aa7f3.txt +177 -0
  146. package/scripts/notices/runtime-0f96a83840e146e43c0e.txt +21 -0
  147. package/scripts/notices/runtime-123a331b5dbf04c30097.txt +25 -0
  148. package/scripts/notices/runtime-172020dbfd5b53a226df.txt +34 -0
  149. package/scripts/notices/runtime-209fbbe0ad52d9235e37.txt +26 -0
  150. package/scripts/notices/runtime-23f18e03dc49df91622f.txt +23 -0
  151. package/scripts/notices/runtime-268872b9816f90fd8e85.txt +220 -0
  152. package/scripts/notices/runtime-35242e7a83f69875e6ed.txt +176 -0
  153. package/scripts/notices/runtime-378f5840b258e2779c39.txt +25 -0
  154. package/scripts/notices/runtime-4108245a1f2df9d4e94d.txt +25 -0
  155. package/scripts/notices/runtime-4455bf75a91154108304.txt +21 -0
  156. package/scripts/notices/runtime-553fffcd9b1cb158bc3e.txt +13 -0
  157. package/scripts/notices/runtime-62c7a1e35f56406896d7.txt +176 -0
  158. package/scripts/notices/runtime-6485b8ed310d3f0340bf.txt +25 -0
  159. package/scripts/notices/runtime-69fef7b0f322a6555415.txt +201 -0
  160. package/scripts/notices/runtime-6df43f6f4b5d4587f3d8.txt +187 -0
  161. package/scripts/notices/runtime-799e9ca9d179295ef372.txt +24 -0
  162. package/scripts/notices/runtime-7b63ecd5f1902af1b637.txt +25 -0
  163. package/scripts/notices/runtime-7bc7d5de2a0b793d4e1a.txt +21 -0
  164. package/scripts/notices/runtime-7e12e5df4bae12cb2158.txt +24 -0
  165. package/scripts/notices/runtime-861399f8c21c042b1105.txt +12 -0
  166. package/scripts/notices/runtime-8ada45cd9f843acf64e4.txt +201 -0
  167. package/scripts/notices/runtime-90eb64f0279b0d9432ac.txt +12 -0
  168. package/scripts/notices/runtime-a60eea817514531668d7.txt +201 -0
  169. package/scripts/notices/runtime-a7c936ff1ed8fa340172.txt +25 -0
  170. package/scripts/notices/runtime-ab6eec6caf0fa5775e41.txt +275 -0
  171. package/scripts/notices/runtime-b1181a40b2a7b25cf66f.txt +19 -0
  172. package/scripts/notices/runtime-b71bd43a069ca0641a9e.txt +25 -0
  173. package/scripts/notices/runtime-c16f8dcf1a368b83be78.txt +201 -0
  174. package/scripts/notices/runtime-c2cfccb812fe482101a8.txt +21 -0
  175. package/scripts/notices/runtime-e99d88d232bf57d70f0f.txt +25 -0
  176. package/scripts/notices/runtime-f32fb3b417a194167cfa.txt +9 -0
  177. package/scripts/notices/runtime-f5062c9a188d81dfe66b.txt +39 -0
  178. package/scripts/notices/runtime-f9070a832833fa7488fd.txt +4 -0
  179. package/scripts/notices/runtime-fab3dd6bdab226f1c086.txt +373 -0
  180. package/scripts/notices/runtime-fba3318d0c600380177e.txt +62 -0
  181. package/scripts/notices/runtime-ff8f68cb076caf8cefe7.txt +25 -0
  182. package/scripts/notices/runtime-ff92bed461f50338dd70.txt +74 -0
  183. package/scripts/notices/runtime.json +1632 -0
  184. package/scripts/notices/sources.json +555 -0
  185. package/scripts/notices/xray-MIT.txt +21 -0
  186. package/src/attributes.ts +271 -0
  187. package/src/codec.ts +74 -0
  188. package/src/dom.ts +87 -0
  189. package/src/extract-plan.ts +97 -0
  190. package/src/extract.ts +130 -0
  191. package/src/hooks.ts +220 -0
  192. package/src/index.ts +223 -0
  193. package/src/io.ts +491 -0
  194. package/src/native.ts +135 -0
  195. package/src/nodes.ts +290 -0
  196. package/src/parse.ts +53 -0
  197. package/src/parser-types.ts +157 -0
  198. package/src/router.ts +327 -0
  199. package/src/selection.ts +566 -0
  200. package/src/slim.ts +12 -0
  201. package/src/transport.ts +104 -0
  202. package/src/types.ts +186 -0
  203. package/src/utils.ts +29 -0
  204. package/src/workers.ts +21 -0
  205. package/tsconfig.json +15 -0
  206. package/tsup.config.ts +16 -0
@@ -0,0 +1,333 @@
1
+ // Copyright 2014-2017 The html5ever Project Developers. See the
2
+ // COPYRIGHT file at the top-level directory of this distribution.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5
+ // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6
+ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7
+ // option. This file may not be copied, modified, or distributed
8
+ // except according to those terms.
9
+
10
+ //! The `BufferQueue` struct and helper types.
11
+ //!
12
+ //! This type is designed for the efficient parsing of string data, especially where many
13
+ //! significant characters are from the ascii range 0-63. This includes, for example, important
14
+ //! characters in xml/html parsing.
15
+ //!
16
+ //! Good and predictable performance is achieved by avoiding allocation where possible (a.k.a. zero
17
+ //! copy).
18
+ //!
19
+ //! [`BufferQueue`]: struct.BufferQueue.html
20
+
21
+ use std::{
22
+ cell::{RefCell, RefMut},
23
+ collections::VecDeque,
24
+ mem,
25
+ };
26
+
27
+ use tendril::StrTendril;
28
+
29
+ pub use self::SetResult::{FromSet, NotFromSet};
30
+ use crate::util::smallcharset::SmallCharSet;
31
+
32
+ /// Result from [`pop_except_from`] containing either a character from a [`SmallCharSet`], or a
33
+ /// string buffer of characters not from the set.
34
+ ///
35
+ /// [`pop_except_from`]: struct.BufferQueue.html#method.pop_except_from
36
+ /// [`SmallCharSet`]: ../struct.SmallCharSet.html
37
+ #[derive(PartialEq, Eq, Debug)]
38
+ pub enum SetResult {
39
+ /// A character from the `SmallCharSet`.
40
+ FromSet(char),
41
+ /// A string buffer containing no characters from the `SmallCharSet`.
42
+ NotFromSet(StrTendril),
43
+ }
44
+
45
+ /// A queue of owned string buffers, which supports incrementally consuming characters.
46
+ ///
47
+ /// Internally it uses [`VecDeque`] and has the same complexity properties.
48
+ ///
49
+ /// [`VecDeque`]: https://doc.rust-lang.org/std/collections/struct.VecDeque.html
50
+ #[derive(Clone, Debug)]
51
+ pub struct BufferQueue {
52
+ /// Buffers to process.
53
+ buffers: RefCell<VecDeque<StrTendril>>,
54
+ }
55
+
56
+ impl Default for BufferQueue {
57
+ /// Create an empty BufferQueue.
58
+ #[inline]
59
+ fn default() -> Self {
60
+ Self {
61
+ buffers: RefCell::new(VecDeque::with_capacity(16)),
62
+ }
63
+ }
64
+ }
65
+
66
+ impl BufferQueue {
67
+ /// Returns whether the queue is empty.
68
+ #[inline]
69
+ pub fn is_empty(&self) -> bool {
70
+ self.buffers.borrow().is_empty()
71
+ }
72
+
73
+ /// Get the buffer at the beginning of the queue.
74
+ #[inline]
75
+ pub fn pop_front(&self) -> Option<StrTendril> {
76
+ self.buffers.borrow_mut().pop_front()
77
+ }
78
+
79
+ /// Add a buffer to the beginning of the queue.
80
+ ///
81
+ /// If the buffer is empty, it will be skipped.
82
+ pub fn push_front(&self, buf: StrTendril) {
83
+ if buf.len32() == 0 {
84
+ return;
85
+ }
86
+ self.buffers.borrow_mut().push_front(buf);
87
+ }
88
+
89
+ /// Add a buffer to the end of the queue.
90
+ ///
91
+ /// If the buffer is empty, it will be skipped.
92
+ pub fn push_back(&self, buf: StrTendril) {
93
+ if buf.len32() == 0 {
94
+ return;
95
+ }
96
+ self.buffers.borrow_mut().push_back(buf);
97
+ }
98
+
99
+ /// Look at the next available character without removing it, if the queue is not empty.
100
+ pub fn peek(&self) -> Option<char> {
101
+ debug_assert!(
102
+ !self.buffers.borrow().iter().any(|el| el.len32() == 0),
103
+ "invariant \"all buffers in the queue are non-empty\" failed"
104
+ );
105
+ self.buffers
106
+ .borrow()
107
+ .front()
108
+ .map(|b| b.chars().next().unwrap())
109
+ }
110
+
111
+ /// Pops and returns either a single character from the given set, or
112
+ /// a buffer of characters none of which are in the set.
113
+ ///
114
+ /// # Examples
115
+ ///
116
+ /// ```
117
+ /// # #[macro_use] extern crate markup5ever;
118
+ /// # #[macro_use] extern crate tendril;
119
+ /// # fn main() {
120
+ /// use markup5ever::buffer_queue::{BufferQueue, SetResult};
121
+ ///
122
+ /// let mut queue = BufferQueue::default();
123
+ /// queue.push_back(format_tendril!(r#"<some_tag attr="text">SomeText</some_tag>"#));
124
+ /// let set = small_char_set!(b'<' b'>' b' ' b'=' b'"' b'/');
125
+ /// let tag = format_tendril!("some_tag");
126
+ /// let attr = format_tendril!("attr");
127
+ /// let attr_val = format_tendril!("text");
128
+ /// assert_eq!(queue.pop_except_from(set), Some(SetResult::FromSet('<')));
129
+ /// assert_eq!(queue.pop_except_from(set), Some(SetResult::NotFromSet(tag)));
130
+ /// assert_eq!(queue.pop_except_from(set), Some(SetResult::FromSet(' ')));
131
+ /// assert_eq!(queue.pop_except_from(set), Some(SetResult::NotFromSet(attr)));
132
+ /// assert_eq!(queue.pop_except_from(set), Some(SetResult::FromSet('=')));
133
+ /// assert_eq!(queue.pop_except_from(set), Some(SetResult::FromSet('"')));
134
+ /// assert_eq!(queue.pop_except_from(set), Some(SetResult::NotFromSet(attr_val)));
135
+ /// // ...
136
+ /// # }
137
+ /// ```
138
+ pub fn pop_except_from(&self, set: SmallCharSet) -> Option<SetResult> {
139
+ let (result, now_empty) = match self.buffers.borrow_mut().front_mut() {
140
+ None => (None, false),
141
+ Some(buf) => {
142
+ let n = set.nonmember_prefix_len(buf);
143
+ if n > 0 {
144
+ let out;
145
+ unsafe {
146
+ out = buf.unsafe_subtendril(0, n);
147
+ buf.unsafe_pop_front(n);
148
+ }
149
+ (Some(NotFromSet(out)), buf.is_empty())
150
+ } else {
151
+ let c = buf.pop_front_char().expect("empty buffer in queue");
152
+ (Some(FromSet(c)), buf.is_empty())
153
+ }
154
+ },
155
+ };
156
+
157
+ // Unborrow self for this part.
158
+ if now_empty {
159
+ self.buffers.borrow_mut().pop_front();
160
+ }
161
+
162
+ result
163
+ }
164
+
165
+ /// Consume bytes matching the pattern, using a custom comparison function `eq`.
166
+ ///
167
+ /// Returns `Some(true)` if there is a match, `Some(false)` if there is no match, or `None` if
168
+ /// it wasn't possible to know (more data is needed).
169
+ ///
170
+ /// The custom comparison function is used elsewhere to compare ascii-case-insensitively.
171
+ ///
172
+ /// # Examples
173
+ ///
174
+ /// ```
175
+ /// # extern crate markup5ever;
176
+ /// # #[macro_use] extern crate tendril;
177
+ /// # fn main() {
178
+ /// use markup5ever::buffer_queue::BufferQueue;
179
+ ///
180
+ /// let mut queue = BufferQueue::default();
181
+ /// queue.push_back(format_tendril!("testtext"));
182
+ /// let test_str = "test";
183
+ /// assert_eq!(queue.eat("test", |&a, &b| a == b), Some(true));
184
+ /// assert_eq!(queue.eat("text", |&a, &b| a == b), Some(true));
185
+ /// assert!(queue.is_empty());
186
+ /// # }
187
+ /// ```
188
+ pub fn eat<F: Fn(&u8, &u8) -> bool>(&self, pat: &str, eq: F) -> Option<bool> {
189
+ let mut buffers_exhausted = 0;
190
+ let mut consumed_from_last = 0;
191
+
192
+ self.buffers.borrow().front()?;
193
+
194
+ for pattern_byte in pat.bytes() {
195
+ if buffers_exhausted >= self.buffers.borrow().len() {
196
+ return None;
197
+ }
198
+ let buf = &self.buffers.borrow()[buffers_exhausted];
199
+
200
+ if !eq(&buf.as_bytes()[consumed_from_last], &pattern_byte) {
201
+ return Some(false);
202
+ }
203
+
204
+ consumed_from_last += 1;
205
+ if consumed_from_last >= buf.len() {
206
+ buffers_exhausted += 1;
207
+ consumed_from_last = 0;
208
+ }
209
+ }
210
+
211
+ // We have a match. Commit changes to the BufferQueue.
212
+ for _ in 0..buffers_exhausted {
213
+ self.buffers.borrow_mut().pop_front();
214
+ }
215
+
216
+ match self.buffers.borrow_mut().front_mut() {
217
+ None => assert_eq!(consumed_from_last, 0),
218
+ Some(ref mut buf) => buf.pop_front(consumed_from_last as u32),
219
+ }
220
+
221
+ Some(true)
222
+ }
223
+
224
+ /// Get the next character if one is available, removing it from the queue.
225
+ ///
226
+ /// This function manages the buffers, removing them as they become empty.
227
+ pub fn next(&self) -> Option<char> {
228
+ let (result, now_empty) = match self.buffers.borrow_mut().front_mut() {
229
+ None => (None, false),
230
+ Some(buf) => {
231
+ let c = buf.pop_front_char().expect("empty buffer in queue");
232
+ (Some(c), buf.is_empty())
233
+ },
234
+ };
235
+
236
+ if now_empty {
237
+ self.buffers.borrow_mut().pop_front();
238
+ }
239
+
240
+ result
241
+ }
242
+
243
+ pub fn replace_with(&self, other: BufferQueue) {
244
+ let _ = mem::replace(&mut *self.buffers.borrow_mut(), other.buffers.take());
245
+ }
246
+
247
+ pub fn swap_with(&self, other: &BufferQueue) {
248
+ mem::swap(
249
+ &mut *self.buffers.borrow_mut(),
250
+ &mut *other.buffers.borrow_mut(),
251
+ );
252
+ }
253
+
254
+ /// Return a mutable reference to the first tendril in the queue.
255
+ pub fn peek_front_chunk_mut(&self) -> Option<RefMut<'_, StrTendril>> {
256
+ let buffers = self.buffers.borrow_mut();
257
+ if buffers.is_empty() {
258
+ return None;
259
+ }
260
+
261
+ let front_buffer = RefMut::map(buffers, |buffers| {
262
+ buffers.front_mut().expect("there is at least one buffer")
263
+ });
264
+ Some(front_buffer)
265
+ }
266
+ }
267
+
268
+ #[cfg(test)]
269
+ #[allow(non_snake_case)]
270
+ mod test {
271
+ use tendril::SliceExt;
272
+
273
+ use super::BufferQueue;
274
+ use super::SetResult::{FromSet, NotFromSet};
275
+
276
+ #[test]
277
+ fn smoke_test() {
278
+ let bq = BufferQueue::default();
279
+ assert_eq!(bq.peek(), None);
280
+ assert_eq!(bq.next(), None);
281
+
282
+ bq.push_back("abc".to_tendril());
283
+ assert_eq!(bq.peek(), Some('a'));
284
+ assert_eq!(bq.next(), Some('a'));
285
+ assert_eq!(bq.peek(), Some('b'));
286
+ assert_eq!(bq.peek(), Some('b'));
287
+ assert_eq!(bq.next(), Some('b'));
288
+ assert_eq!(bq.peek(), Some('c'));
289
+ assert_eq!(bq.next(), Some('c'));
290
+ assert_eq!(bq.peek(), None);
291
+ assert_eq!(bq.next(), None);
292
+ }
293
+
294
+ #[test]
295
+ fn can_unconsume() {
296
+ let bq = BufferQueue::default();
297
+ bq.push_back("abc".to_tendril());
298
+ assert_eq!(bq.next(), Some('a'));
299
+
300
+ bq.push_front("xy".to_tendril());
301
+ assert_eq!(bq.next(), Some('x'));
302
+ assert_eq!(bq.next(), Some('y'));
303
+ assert_eq!(bq.next(), Some('b'));
304
+ assert_eq!(bq.next(), Some('c'));
305
+ assert_eq!(bq.next(), None);
306
+ }
307
+
308
+ #[test]
309
+ fn can_pop_except_set() {
310
+ let bq = BufferQueue::default();
311
+ bq.push_back("abc&def".to_tendril());
312
+ let pop = || bq.pop_except_from(small_char_set!('&'));
313
+ assert_eq!(pop(), Some(NotFromSet("abc".to_tendril())));
314
+ assert_eq!(pop(), Some(FromSet('&')));
315
+ assert_eq!(pop(), Some(NotFromSet("def".to_tendril())));
316
+ assert_eq!(pop(), None);
317
+ }
318
+
319
+ #[test]
320
+ fn can_eat() {
321
+ // This is not very comprehensive. We rely on the tokenizer
322
+ // integration tests for more thorough testing with many
323
+ // different input buffer splits.
324
+ let bq = BufferQueue::default();
325
+ bq.push_back("a".to_tendril());
326
+ bq.push_back("bc".to_tendril());
327
+ assert_eq!(bq.eat("abcd", u8::eq_ignore_ascii_case), None);
328
+ assert_eq!(bq.eat("ax", u8::eq_ignore_ascii_case), Some(false));
329
+ assert_eq!(bq.eat("ab", u8::eq_ignore_ascii_case), Some(true));
330
+ assert_eq!(bq.next(), Some('c'));
331
+ assert_eq!(bq.next(), None);
332
+ }
333
+ }
@@ -0,0 +1,88 @@
1
+ // Copyright 2014-2017 The html5ever Project Developers. See the
2
+ // COPYRIGHT file at the top-level directory of this distribution.
3
+ //
4
+ // Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
5
+ // http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
6
+ // <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
7
+ // option. This file may not be copied, modified, or distributed
8
+ // except according to those terms.
9
+
10
+ //! This module contains a single struct [`SmallCharSet`]. See its documentation for details.
11
+ //!
12
+ //! [`SmallCharSet`]: struct.SmallCharSet.html
13
+
14
+ /// Represents a set of "small characters", those with Unicode scalar
15
+ /// values less than 64.
16
+ ///
17
+ /// This is stored as a bitmap, with 1 bit for each value.
18
+ #[derive(Debug, Eq, PartialEq, Clone, Copy, Hash)]
19
+ pub struct SmallCharSet {
20
+ pub bits: u64,
21
+ }
22
+
23
+ impl SmallCharSet {
24
+ /// Checks whether a character (u8 value below 64) is stored in the SmallCharSet.
25
+ ///
26
+ /// # Examples
27
+ ///
28
+ /// ```ignore
29
+ /// # use markup5ever::SmallCharSet;
30
+ /// let set = SmallCharSet {
31
+ /// bits: 0b00000000_01000000_00000100_00000000_00000000_00000000_00010000_00000000
32
+ /// };
33
+ /// assert!(set.contains(64));
34
+ /// assert!(set.contains(b'6')); // `b'6'` is the same as 64u8
35
+ /// ```
36
+ #[inline]
37
+ fn contains(&self, n: u8) -> bool {
38
+ 0 != (self.bits & (1 << (n as usize)))
39
+ }
40
+
41
+ /// Count the number of bytes of characters at the beginning of `buf` which are not in the set.
42
+ ///
43
+ /// This functionality is used in [`BufferQueue::pop_except_from`].
44
+ ///
45
+ /// # Examples
46
+ ///
47
+ /// ```
48
+ /// # #[macro_use] extern crate markup5ever;
49
+ /// # fn main() {
50
+ /// let set = small_char_set!(48 49 50); // '0' '1' '2'
51
+ /// // `test` is 4 chars, 😁 is 4 chars, then we meet a character in the set
52
+ /// let test_str = "test😁01232afd";
53
+ /// assert_eq!(set.nonmember_prefix_len(test_str), 8);
54
+ /// # }
55
+ /// ```
56
+ ///
57
+ /// [`BufferQueue::pop_except_from`]: buffer_queue/struct.BufferQueue.html#method.pop_except_from
58
+ pub fn nonmember_prefix_len(&self, buf: &str) -> u32 {
59
+ let mut n = 0;
60
+ for b in buf.bytes() {
61
+ if b >= 64 || !self.contains(b) {
62
+ n += 1;
63
+ } else {
64
+ break;
65
+ }
66
+ }
67
+ n
68
+ }
69
+ }
70
+
71
+ #[cfg(test)]
72
+ mod test {
73
+ #[test]
74
+ fn nonmember_prefix() {
75
+ for &c in ['&', '\0'].iter() {
76
+ for x in 0..48u32 {
77
+ for y in 0..48u32 {
78
+ let mut s = "x".repeat(x as usize);
79
+ s.push(c);
80
+ s.push_str(&"x".repeat(y as usize));
81
+ let set = small_char_set!('&' '\0');
82
+
83
+ assert_eq!(x, set.nonmember_prefix_len(&s));
84
+ }
85
+ }
86
+ }
87
+ }
88
+ }
package/package.json CHANGED
@@ -1,6 +1,139 @@
1
1
  {
2
2
  "name": "rusteerio",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
6
- }
3
+ "version": "0.1.0",
4
+ "description": "Cheerio-compatible HTML processing with a Rust engine and parallel, non-blocking extraction",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "git+https://github.com/context-dot-dev/rusteerio.git"
9
+ },
10
+ "homepage": "https://github.com/context-dot-dev/rusteerio#readme",
11
+ "bugs": {
12
+ "url": "https://github.com/context-dot-dev/rusteerio/issues"
13
+ },
14
+ "keywords": [
15
+ "cheerio",
16
+ "rust",
17
+ "html",
18
+ "scraping",
19
+ "napi",
20
+ "parallel"
21
+ ],
22
+ "main": "./dist/index.cjs",
23
+ "module": "./dist/index.mjs",
24
+ "types": "./dist/index.d.ts",
25
+ "exports": {
26
+ ".": {
27
+ "import": {
28
+ "types": "./dist/index.d.mts",
29
+ "default": "./dist/index.mjs"
30
+ },
31
+ "require": {
32
+ "types": "./dist/index.d.ts",
33
+ "default": "./dist/index.cjs"
34
+ }
35
+ },
36
+ "./package.json": "./package.json",
37
+ "./slim": {
38
+ "import": {
39
+ "types": "./dist/slim.d.mts",
40
+ "default": "./dist/slim.mjs"
41
+ },
42
+ "require": {
43
+ "types": "./dist/slim.d.ts",
44
+ "default": "./dist/slim.cjs"
45
+ }
46
+ },
47
+ "./utils": {
48
+ "import": {
49
+ "types": "./dist/utils.d.mts",
50
+ "default": "./dist/utils.mjs"
51
+ },
52
+ "require": {
53
+ "types": "./dist/utils.d.ts",
54
+ "default": "./dist/utils.cjs"
55
+ }
56
+ }
57
+ },
58
+ "files": [
59
+ "dist",
60
+ "*.node",
61
+ "src",
62
+ "native/src",
63
+ "Cargo.toml",
64
+ "Cargo.lock",
65
+ "build.rs",
66
+ "tsconfig.json",
67
+ "tsup.config.ts",
68
+ "scripts/check-native.mjs",
69
+ "scripts/check-release.mjs",
70
+ "scripts/fix-declarations.mjs",
71
+ "scripts/generate-notices.mjs",
72
+ "LICENSE",
73
+ "THIRD_PARTY_NOTICES.md",
74
+ "README.md",
75
+ "CONTRIBUTING.md",
76
+ "RELEASING.md",
77
+ "scripts/notices",
78
+ "native/vendor"
79
+ ],
80
+ "engines": {
81
+ "node": ">=20.19.0"
82
+ },
83
+ "overrides": {
84
+ "esbuild": "0.28.2"
85
+ },
86
+ "scripts": {
87
+ "build": "npm run build:native && npm run build:ts",
88
+ "build:native": "napi build --platform --release --js false --dts native-binding.d.ts",
89
+ "build:ts": "tsup && node scripts/fix-declarations.mjs",
90
+ "check": "tsc --noEmit",
91
+ "test": "node --test test/*.test.mjs bench/*.test.mjs bench/suite/*.test.mjs",
92
+ "test:types": "tsc -p test/tsconfig.json --noEmit",
93
+ "bench": "node bench/benchmark.mjs",
94
+ "prepack": "npm run build:ts && node scripts/check-native.mjs",
95
+ "prepublishOnly": "npm run release:check",
96
+ "test:upstream": "node scripts/check-upstream.mjs && vitest run --config vitest.config.mts",
97
+ "test:package": "node scripts/test-package.mjs",
98
+ "bench:engine": "node bench/engine.mjs",
99
+ "bench:fair": "node --expose-gc bench/fair.mjs",
100
+ "release:check": "node scripts/check-release.mjs",
101
+ "notices:generate": "node scripts/generate-notices.mjs",
102
+ "notices:check": "node scripts/generate-notices.mjs --check"
103
+ },
104
+ "devDependencies": {
105
+ "@napi-rs/cli": "^2.18.4",
106
+ "@types/node": "^22.19.0",
107
+ "tsup": "^8.5.1",
108
+ "typescript": "^5.9.3",
109
+ "vitest": "4.1.11",
110
+ "cheerio": "1.2.0",
111
+ "domhandler": "^5.0.3",
112
+ "domutils": "^3.2.2",
113
+ "encoding-sniffer": "^0.2.1"
114
+ },
115
+ "napi": {
116
+ "name": "rusteerio",
117
+ "triples": {
118
+ "defaults": false,
119
+ "additional": [
120
+ "x86_64-unknown-linux-gnu",
121
+ "aarch64-unknown-linux-gnu",
122
+ "x86_64-unknown-linux-musl",
123
+ "aarch64-unknown-linux-musl",
124
+ "x86_64-apple-darwin",
125
+ "aarch64-apple-darwin",
126
+ "x86_64-pc-windows-msvc",
127
+ "aarch64-pc-windows-msvc"
128
+ ]
129
+ }
130
+ },
131
+ "author": {
132
+ "name": "Context.dev team",
133
+ "url": "https://context.dev"
134
+ },
135
+ "publishConfig": {
136
+ "access": "public",
137
+ "registry": "https://registry.npmjs.org/"
138
+ }
139
+ }
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
Binary file
@@ -0,0 +1,15 @@
1
+ import assert from 'node:assert/strict';
2
+ import { readdirSync, readFileSync } from 'node:fs';
3
+ import { nativeTargets, validateNativeBinary } from './check-release.mjs';
4
+ import { nativeStatus } from '../dist/index.mjs';
5
+
6
+ const status = nativeStatus();
7
+ assert.ok(status.available, `Build the native addon before packaging: ${status.error}`);
8
+ if (process.argv.includes('--all')) {
9
+ const files = new Set(readdirSync(new URL('../', import.meta.url)));
10
+ for (const target of nativeTargets) {
11
+ assert.ok(files.has(`rusteerio.${target}.node`), `Release is missing the ${target} native binary`);
12
+ }
13
+ }
14
+
15
+ for (const name of readdirSync(new URL('../', import.meta.url)).filter(name => /^rusteerio\..+\.node$/.test(name))) validateNativeBinary(name, readFileSync(new URL(`../${name}`, import.meta.url)));