summaryrefslogtreecommitdiffstats
path: root/vendor/text-size
diff options
context:
space:
mode:
Diffstat (limited to 'vendor/text-size')
-rw-r--r--vendor/text-size/.cargo-checksum.json1
-rw-r--r--vendor/text-size/CHANGELOG.md26
-rw-r--r--vendor/text-size/Cargo.toml35
-rw-r--r--vendor/text-size/LICENSE-APACHE201
-rw-r--r--vendor/text-size/LICENSE-MIT23
-rw-r--r--vendor/text-size/README.md27
-rw-r--r--vendor/text-size/bors.toml6
-rw-r--r--vendor/text-size/src/lib.rs32
-rw-r--r--vendor/text-size/src/range.rs456
-rw-r--r--vendor/text-size/src/serde_impls.rs48
-rw-r--r--vendor/text-size/src/size.rs161
-rw-r--r--vendor/text-size/src/traits.rs36
-rw-r--r--vendor/text-size/tests/auto_traits.rs18
-rw-r--r--vendor/text-size/tests/constructors.rs24
-rw-r--r--vendor/text-size/tests/indexing.rs8
-rw-r--r--vendor/text-size/tests/main.rs76
-rw-r--r--vendor/text-size/tests/serde.rs79
17 files changed, 1257 insertions, 0 deletions
diff --git a/vendor/text-size/.cargo-checksum.json b/vendor/text-size/.cargo-checksum.json
new file mode 100644
index 000000000..95beeebec
--- /dev/null
+++ b/vendor/text-size/.cargo-checksum.json
@@ -0,0 +1 @@
+{"files":{"CHANGELOG.md":"69cd308ac4ab7db1bcf8204880d681d7a42a3794cab738c7ea6d90f353b62e8b","Cargo.toml":"f776bb7b198bcfa43b18693fec21b31ebdf5481cfb8ede8e8fc53b5f5caa929a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"23f18e03dc49df91622fe2a76176497404e46ced8a715d9d2b67a7446571cca3","README.md":"efa9d6f4283e8823b7dd255f1558075b9e217ec7438734841b95af1f6b6d7039","bors.toml":"797bade4897d4609281db308c8d4b0cf4a6055a43b577603697f145869bc5026","src/lib.rs":"1de9f1b88371c39dcce294a62b705760f3fff36360ca299bcba583545867c3cd","src/range.rs":"0b24c4c1407ddaaab2ad83f3479a175f63ec6ef5638487952b33fe9268b06c43","src/serde_impls.rs":"d3a001f9add137a1546c033ac58b54a0e407e4ec876aebfcff2cbf4513357bc2","src/size.rs":"4e85f7b6977063570f9252562a24c93c7ee68481dd5f0bcc0f1d5d7e4ebfc584","src/traits.rs":"e3478d13e084a3a47e940001714622ce8ffa350ff53e03245ad2380c07ab9544","tests/auto_traits.rs":"e2c566aa4054ff0c3e01de7a9897150a2cde6615daa867175505e205aec6f3e1","tests/constructors.rs":"18f3ab9055a0e877632110d25e6cd4d2fc804a684c10344214c2e18c3d0d90d2","tests/indexing.rs":"87c4458ab76ea113b5169d8448c2560eabf077b2a532269bf941fb1a48aefb88","tests/main.rs":"9aadd5578250d381d2d9e522381be77dcc38a3acf83f1e1af143f69a29df950f","tests/serde.rs":"fa8f0b997fedb892a17a4830126c76e4f1ee66370687373ffd28b4dbb460a9f6"},"package":"288cb548dbe72b652243ea797201f3d481a0609a967980fcc5b2315ea811560a"} \ No newline at end of file
diff --git a/vendor/text-size/CHANGELOG.md b/vendor/text-size/CHANGELOG.md
new file mode 100644
index 000000000..0167599e5
--- /dev/null
+++ b/vendor/text-size/CHANGELOG.md
@@ -0,0 +1,26 @@
+# Changelog
+
+## 1.1.0
+
+* add `TextRange::ordering` method
+
+## 1.0.0 :tada:
+
+* the carate is renamed to `text-size` from `text_unit`
+
+Transition table:
+- `TextUnit::of_char(c)` ⟹ `TextSize::of(c)`
+- `TextUnit::of_str(s)` ⟹ `TextSize::of(s)`
+- `TextUnit::from_usize(size)` ⟹ `TextSize::try_from(size).unwrap_or_else(|| panic!(_))`
+- `unit.to_usize()` ⟹ `usize::from(size)`
+- `TextRange::from_to(from, to)` ⟹ `TextRange::new(from, to)`
+- `TextRange::offset_len(offset, size)` ⟹ `TextRange::from_len(offset, size)`
+- `range.start()` ⟹ `range.start()`
+- `range.end()` ⟹ `range.end()`
+- `range.len()` ⟹ `range.len()`
+- `range.is_empty()` ⟹ `range.is_empty()`
+- `a.is_subrange(b)` ⟹ `b.contains_range(a)`
+- `a.intersection(b)` ⟹ `a.intersect(b)`
+- `a.extend_to(b)` ⟹ `a.cover(b)`
+- `range.contains(offset)` ⟹ `range.contains(point)`
+- `range.contains_inclusive(offset)` ⟹ `range.contains_inclusive(point)`
diff --git a/vendor/text-size/Cargo.toml b/vendor/text-size/Cargo.toml
new file mode 100644
index 000000000..e4732b4f7
--- /dev/null
+++ b/vendor/text-size/Cargo.toml
@@ -0,0 +1,35 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g., crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
+[package]
+edition = "2018"
+name = "text-size"
+version = "1.1.0"
+authors = ["Aleksey Kladov <aleksey.kladov@gmail.com>", "Christopher Durham (CAD97) <cad97@cad97.com>"]
+description = "Newtypes for text offsets"
+documentation = "https://docs.rs/text-size"
+license = "MIT OR Apache-2.0"
+repository = "https://github.com/rust-analyzer/text-size"
+
+[[test]]
+name = "serde"
+path = "tests/serde.rs"
+required-features = ["serde"]
+[dependencies.serde]
+version = "1.0"
+optional = true
+default_features = false
+[dev-dependencies.serde_test]
+version = "1.0"
+
+[dev-dependencies.static_assertions]
+version = "1.1"
diff --git a/vendor/text-size/LICENSE-APACHE b/vendor/text-size/LICENSE-APACHE
new file mode 100644
index 000000000..16fe87b06
--- /dev/null
+++ b/vendor/text-size/LICENSE-APACHE
@@ -0,0 +1,201 @@
+ Apache License
+ Version 2.0, January 2004
+ http://www.apache.org/licenses/
+
+TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
+
+1. Definitions.
+
+ "License" shall mean the terms and conditions for use, reproduction,
+ and distribution as defined by Sections 1 through 9 of this document.
+
+ "Licensor" shall mean the copyright owner or entity authorized by
+ the copyright owner that is granting the License.
+
+ "Legal Entity" shall mean the union of the acting entity and all
+ other entities that control, are controlled by, or are under common
+ control with that entity. For the purposes of this definition,
+ "control" means (i) the power, direct or indirect, to cause the
+ direction or management of such entity, whether by contract or
+ otherwise, or (ii) ownership of fifty percent (50%) or more of the
+ outstanding shares, or (iii) beneficial ownership of such entity.
+
+ "You" (or "Your") shall mean an individual or Legal Entity
+ exercising permissions granted by this License.
+
+ "Source" form shall mean the preferred form for making modifications,
+ including but not limited to software source code, documentation
+ source, and configuration files.
+
+ "Object" form shall mean any form resulting from mechanical
+ transformation or translation of a Source form, including but
+ not limited to compiled object code, generated documentation,
+ and conversions to other media types.
+
+ "Work" shall mean the work of authorship, whether in Source or
+ Object form, made available under the License, as indicated by a
+ copyright notice that is included in or attached to the work
+ (an example is provided in the Appendix below).
+
+ "Derivative Works" shall mean any work, whether in Source or Object
+ form, that is based on (or derived from) the Work and for which the
+ editorial revisions, annotations, elaborations, or other modifications
+ represent, as a whole, an original work of authorship. For the purposes
+ of this License, Derivative Works shall not include works that remain
+ separable from, or merely link (or bind by name) to the interfaces of,
+ the Work and Derivative Works thereof.
+
+ "Contribution" shall mean any work of authorship, including
+ the original version of the Work and any modifications or additions
+ to that Work or Derivative Works thereof, that is intentionally
+ submitted to Licensor for inclusion in the Work by the copyright owner
+ or by an individual or Legal Entity authorized to submit on behalf of
+ the copyright owner. For the purposes of this definition, "submitted"
+ means any form of electronic, verbal, or written communication sent
+ to the Licensor or its representatives, including but not limited to
+ communication on electronic mailing lists, source code control systems,
+ and issue tracking systems that are managed by, or on behalf of, the
+ Licensor for the purpose of discussing and improving the Work, but
+ excluding communication that is conspicuously marked or otherwise
+ designated in writing by the copyright owner as "Not a Contribution."
+
+ "Contributor" shall mean Licensor and any individual or Legal Entity
+ on behalf of whom a Contribution has been received by Licensor and
+ subsequently incorporated within the Work.
+
+2. Grant of Copyright License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ copyright license to reproduce, prepare Derivative Works of,
+ publicly display, publicly perform, sublicense, and distribute the
+ Work and such Derivative Works in Source or Object form.
+
+3. Grant of Patent License. Subject to the terms and conditions of
+ this License, each Contributor hereby grants to You a perpetual,
+ worldwide, non-exclusive, no-charge, royalty-free, irrevocable
+ (except as stated in this section) patent license to make, have made,
+ use, offer to sell, sell, import, and otherwise transfer the Work,
+ where such license applies only to those patent claims licensable
+ by such Contributor that are necessarily infringed by their
+ Contribution(s) alone or by combination of their Contribution(s)
+ with the Work to which such Contribution(s) was submitted. If You
+ institute patent litigation against any entity (including a
+ cross-claim or counterclaim in a lawsuit) alleging that the Work
+ or a Contribution incorporated within the Work constitutes direct
+ or contributory patent infringement, then any patent licenses
+ granted to You under this License for that Work shall terminate
+ as of the date such litigation is filed.
+
+4. Redistribution. You may reproduce and distribute copies of the
+ Work or Derivative Works thereof in any medium, with or without
+ modifications, and in Source or Object form, provided that You
+ meet the following conditions:
+
+ (a) You must give any other recipients of the Work or
+ Derivative Works a copy of this License; and
+
+ (b) You must cause any modified files to carry prominent notices
+ stating that You changed the files; and
+
+ (c) You must retain, in the Source form of any Derivative Works
+ that You distribute, all copyright, patent, trademark, and
+ attribution notices from the Source form of the Work,
+ excluding those notices that do not pertain to any part of
+ the Derivative Works; and
+
+ (d) If the Work includes a "NOTICE" text file as part of its
+ distribution, then any Derivative Works that You distribute must
+ include a readable copy of the attribution notices contained
+ within such NOTICE file, excluding those notices that do not
+ pertain to any part of the Derivative Works, in at least one
+ of the following places: within a NOTICE text file distributed
+ as part of the Derivative Works; within the Source form or
+ documentation, if provided along with the Derivative Works; or,
+ within a display generated by the Derivative Works, if and
+ wherever such third-party notices normally appear. The contents
+ of the NOTICE file are for informational purposes only and
+ do not modify the License. You may add Your own attribution
+ notices within Derivative Works that You distribute, alongside
+ or as an addendum to the NOTICE text from the Work, provided
+ that such additional attribution notices cannot be construed
+ as modifying the License.
+
+ You may add Your own copyright statement to Your modifications and
+ may provide additional or different license terms and conditions
+ for use, reproduction, or distribution of Your modifications, or
+ for any such Derivative Works as a whole, provided Your use,
+ reproduction, and distribution of the Work otherwise complies with
+ the conditions stated in this License.
+
+5. Submission of Contributions. Unless You explicitly state otherwise,
+ any Contribution intentionally submitted for inclusion in the Work
+ by You to the Licensor shall be under the terms and conditions of
+ this License, without any additional terms or conditions.
+ Notwithstanding the above, nothing herein shall supersede or modify
+ the terms of any separate license agreement you may have executed
+ with Licensor regarding such Contributions.
+
+6. Trademarks. This License does not grant permission to use the trade
+ names, trademarks, service marks, or product names of the Licensor,
+ except as required for reasonable and customary use in describing the
+ origin of the Work and reproducing the content of the NOTICE file.
+
+7. Disclaimer of Warranty. Unless required by applicable law or
+ agreed to in writing, Licensor provides the Work (and each
+ Contributor provides its Contributions) on an "AS IS" BASIS,
+ WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
+ implied, including, without limitation, any warranties or conditions
+ of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
+ PARTICULAR PURPOSE. You are solely responsible for determining the
+ appropriateness of using or redistributing the Work and assume any
+ risks associated with Your exercise of permissions under this License.
+
+8. Limitation of Liability. In no event and under no legal theory,
+ whether in tort (including negligence), contract, or otherwise,
+ unless required by applicable law (such as deliberate and grossly
+ negligent acts) or agreed to in writing, shall any Contributor be
+ liable to You for damages, including any direct, indirect, special,
+ incidental, or consequential damages of any character arising as a
+ result of this License or out of the use or inability to use the
+ Work (including but not limited to damages for loss of goodwill,
+ work stoppage, computer failure or malfunction, or any and all
+ other commercial damages or losses), even if such Contributor
+ has been advised of the possibility of such damages.
+
+9. Accepting Warranty or Additional Liability. While redistributing
+ the Work or Derivative Works thereof, You may choose to offer,
+ and charge a fee for, acceptance of support, warranty, indemnity,
+ or other liability obligations and/or rights consistent with this
+ License. However, in accepting such obligations, You may act only
+ on Your own behalf and on Your sole responsibility, not on behalf
+ of any other Contributor, and only if You agree to indemnify,
+ defend, and hold each Contributor harmless for any liability
+ incurred by, or claims asserted against, such Contributor by reason
+ of your accepting any such warranty or additional liability.
+
+END OF TERMS AND CONDITIONS
+
+APPENDIX: How to apply the Apache License to your work.
+
+ To apply the Apache License to your work, attach the following
+ boilerplate notice, with the fields enclosed by brackets "[]"
+ replaced with your own identifying information. (Don't include
+ the brackets!) The text should be enclosed in the appropriate
+ comment syntax for the file format. We also recommend that a
+ file or class name and description of purpose be included on the
+ same "printed page" as the copyright notice for easier
+ identification within third-party archives.
+
+Copyright [yyyy] [name of copyright owner]
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
diff --git a/vendor/text-size/LICENSE-MIT b/vendor/text-size/LICENSE-MIT
new file mode 100644
index 000000000..31aa79387
--- /dev/null
+++ b/vendor/text-size/LICENSE-MIT
@@ -0,0 +1,23 @@
+Permission is hereby granted, free of charge, to any
+person obtaining a copy of this software and associated
+documentation files (the "Software"), to deal in the
+Software without restriction, including without
+limitation the rights to use, copy, modify, merge,
+publish, distribute, sublicense, and/or sell copies of
+the Software, and to permit persons to whom the Software
+is furnished to do so, subject to the following
+conditions:
+
+The above copyright notice and this permission notice
+shall be included in all copies or substantial portions
+of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
+ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
+TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
+PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
+SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
+CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
+IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+DEALINGS IN THE SOFTWARE.
diff --git a/vendor/text-size/README.md b/vendor/text-size/README.md
new file mode 100644
index 000000000..365b6028a
--- /dev/null
+++ b/vendor/text-size/README.md
@@ -0,0 +1,27 @@
+# text-size
+
+[![Build Status](https://travis-ci.org/matklad/text-size.svg?branch=master)](https://travis-ci.org/matklad/text-size)
+[![Crates.io](https://img.shields.io/crates/v/text-size.svg)](https://crates.io/crates/text-size)
+[![API reference](https://docs.rs/text-size/badge.svg)](https://docs.rs/text-size/)
+
+
+A library that provides newtype wrappers for `u32` and `(u32, u32)` for use as text offsets.
+
+See the [docs](https://docs.rs/text-size/) for more.
+
+## License
+
+Licensed under either of
+
+ * Apache License, Version 2.0
+ ([LICENSE-APACHE](LICENSE-APACHE) or http://www.apache.org/licenses/LICENSE-2.0)
+ * MIT license
+ ([LICENSE-MIT](LICENSE-MIT) or http://opensource.org/licenses/MIT)
+
+at your option.
+
+## Contribution
+
+Unless you explicitly state otherwise, any contribution intentionally submitted
+for inclusion in the work by you, as defined in the Apache-2.0 license, shall be
+dual licensed as above, without any additional terms or conditions.
diff --git a/vendor/text-size/bors.toml b/vendor/text-size/bors.toml
new file mode 100644
index 000000000..932be8d09
--- /dev/null
+++ b/vendor/text-size/bors.toml
@@ -0,0 +1,6 @@
+status = [
+ "Rust (ubuntu-latest)",
+ "Rust (windows-latest)",
+ "Rust (macos-latest)",
+]
+delete_merged_branches = true
diff --git a/vendor/text-size/src/lib.rs b/vendor/text-size/src/lib.rs
new file mode 100644
index 000000000..92bd36b19
--- /dev/null
+++ b/vendor/text-size/src/lib.rs
@@ -0,0 +1,32 @@
+//! Newtypes for working with text sizes/ranges in a more type-safe manner.
+//!
+//! This library can help with two things:
+//! * Reducing storage requirements for offsets and ranges, under the
+//! assumption that 32 bits is enough.
+//! * Providing standard vocabulary types for applications where text ranges
+//! are pervasive.
+//!
+//! However, you should not use this library simply because you work with
+//! strings. In the overwhelming majority of cases, using `usize` and
+//! `std::ops::Range<usize>` is better. In particular, if you are publishing a
+//! library, using only std types in the interface would make it more
+//! interoperable. Similarly, if you are writing something like a lexer, which
+//! produces, but does not *store* text ranges, then sticking to `usize` would
+//! be better.
+//!
+//! Minimal Supported Rust Version: latest stable.
+
+#![forbid(unsafe_code)]
+#![warn(missing_debug_implementations, missing_docs)]
+
+mod range;
+mod size;
+mod traits;
+
+#[cfg(feature = "serde")]
+mod serde_impls;
+
+pub use crate::{range::TextRange, size::TextSize, traits::TextLen};
+
+#[cfg(target_pointer_width = "16")]
+compile_error!("text-size assumes usize >= u32 and does not work on 16-bit targets");
diff --git a/vendor/text-size/src/range.rs b/vendor/text-size/src/range.rs
new file mode 100644
index 000000000..4a98deec5
--- /dev/null
+++ b/vendor/text-size/src/range.rs
@@ -0,0 +1,456 @@
+use cmp::Ordering;
+
+use {
+ crate::TextSize,
+ std::{
+ cmp, fmt,
+ ops::{Add, AddAssign, Bound, Index, IndexMut, Range, RangeBounds, Sub, SubAssign},
+ },
+};
+
+/// A range in text, represented as a pair of [`TextSize`][struct@TextSize].
+///
+/// It is a logic error for `start` to be greater than `end`.
+#[derive(Default, Copy, Clone, Eq, PartialEq, Hash)]
+pub struct TextRange {
+ // Invariant: start <= end
+ start: TextSize,
+ end: TextSize,
+}
+
+impl fmt::Debug for TextRange {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}..{}", self.start().raw, self.end().raw)
+ }
+}
+
+impl TextRange {
+ /// Creates a new `TextRange` with the given `start` and `end` (`start..end`).
+ ///
+ /// # Panics
+ ///
+ /// Panics if `end < start`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let start = TextSize::from(5);
+ /// let end = TextSize::from(10);
+ /// let range = TextRange::new(start, end);
+ ///
+ /// assert_eq!(range.start(), start);
+ /// assert_eq!(range.end(), end);
+ /// assert_eq!(range.len(), end - start);
+ /// ```
+ #[inline]
+ pub fn new(start: TextSize, end: TextSize) -> TextRange {
+ assert!(start <= end);
+ TextRange { start, end }
+ }
+
+ /// Create a new `TextRange` with the given `offset` and `len` (`offset..offset + len`).
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let text = "0123456789";
+ ///
+ /// let offset = TextSize::from(2);
+ /// let length = TextSize::from(5);
+ /// let range = TextRange::at(offset, length);
+ ///
+ /// assert_eq!(range, TextRange::new(offset, offset + length));
+ /// assert_eq!(&text[range], "23456")
+ /// ```
+ #[inline]
+ pub fn at(offset: TextSize, len: TextSize) -> TextRange {
+ TextRange::new(offset, offset + len)
+ }
+
+ /// Create a zero-length range at the specified offset (`offset..offset`).
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let point: TextSize;
+ /// # point = TextSize::from(3);
+ /// let range = TextRange::empty(point);
+ /// assert!(range.is_empty());
+ /// assert_eq!(range, TextRange::new(point, point));
+ /// ```
+ #[inline]
+ pub fn empty(offset: TextSize) -> TextRange {
+ TextRange {
+ start: offset,
+ end: offset,
+ }
+ }
+
+ /// Create a range up to the given end (`..end`).
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let point: TextSize;
+ /// # point = TextSize::from(12);
+ /// let range = TextRange::up_to(point);
+ ///
+ /// assert_eq!(range.len(), point);
+ /// assert_eq!(range, TextRange::new(0.into(), point));
+ /// assert_eq!(range, TextRange::at(0.into(), point));
+ /// ```
+ #[inline]
+ pub fn up_to(end: TextSize) -> TextRange {
+ TextRange {
+ start: 0.into(),
+ end,
+ }
+ }
+}
+
+/// Identity methods.
+impl TextRange {
+ /// The start point of this range.
+ #[inline]
+ pub const fn start(self) -> TextSize {
+ self.start
+ }
+
+ /// The end point of this range.
+ #[inline]
+ pub const fn end(self) -> TextSize {
+ self.end
+ }
+
+ /// The size of this range.
+ #[inline]
+ pub const fn len(self) -> TextSize {
+ // HACK for const fn: math on primitives only
+ TextSize {
+ raw: self.end().raw - self.start().raw,
+ }
+ }
+
+ /// Check if this range is empty.
+ #[inline]
+ pub const fn is_empty(self) -> bool {
+ // HACK for const fn: math on primitives only
+ self.start().raw == self.end().raw
+ }
+}
+
+/// Manipulation methods.
+impl TextRange {
+ /// Check if this range contains an offset.
+ ///
+ /// The end index is considered excluded.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let (start, end): (TextSize, TextSize);
+ /// # start = 10.into(); end = 20.into();
+ /// let range = TextRange::new(start, end);
+ /// assert!(range.contains(start));
+ /// assert!(!range.contains(end));
+ /// ```
+ #[inline]
+ pub fn contains(self, offset: TextSize) -> bool {
+ self.start() <= offset && offset < self.end()
+ }
+
+ /// Check if this range contains an offset.
+ ///
+ /// The end index is considered included.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let (start, end): (TextSize, TextSize);
+ /// # start = 10.into(); end = 20.into();
+ /// let range = TextRange::new(start, end);
+ /// assert!(range.contains_inclusive(start));
+ /// assert!(range.contains_inclusive(end));
+ /// ```
+ #[inline]
+ pub fn contains_inclusive(self, offset: TextSize) -> bool {
+ self.start() <= offset && offset <= self.end()
+ }
+
+ /// Check if this range completely contains another range.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let larger = TextRange::new(0.into(), 20.into());
+ /// let smaller = TextRange::new(5.into(), 15.into());
+ /// assert!(larger.contains_range(smaller));
+ /// assert!(!smaller.contains_range(larger));
+ ///
+ /// // a range always contains itself
+ /// assert!(larger.contains_range(larger));
+ /// assert!(smaller.contains_range(smaller));
+ /// ```
+ #[inline]
+ pub fn contains_range(self, other: TextRange) -> bool {
+ self.start() <= other.start() && other.end() <= self.end()
+ }
+
+ /// The range covered by both ranges, if it exists.
+ /// If the ranges touch but do not overlap, the output range is empty.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// assert_eq!(
+ /// TextRange::intersect(
+ /// TextRange::new(0.into(), 10.into()),
+ /// TextRange::new(5.into(), 15.into()),
+ /// ),
+ /// Some(TextRange::new(5.into(), 10.into())),
+ /// );
+ /// ```
+ #[inline]
+ pub fn intersect(self, other: TextRange) -> Option<TextRange> {
+ let start = cmp::max(self.start(), other.start());
+ let end = cmp::min(self.end(), other.end());
+ if end < start {
+ return None;
+ }
+ Some(TextRange::new(start, end))
+ }
+
+ /// Extends the range to cover `other` as well.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// assert_eq!(
+ /// TextRange::cover(
+ /// TextRange::new(0.into(), 5.into()),
+ /// TextRange::new(15.into(), 20.into()),
+ /// ),
+ /// TextRange::new(0.into(), 20.into()),
+ /// );
+ /// ```
+ #[inline]
+ pub fn cover(self, other: TextRange) -> TextRange {
+ let start = cmp::min(self.start(), other.start());
+ let end = cmp::max(self.end(), other.end());
+ TextRange::new(start, end)
+ }
+
+ /// Extends the range to cover `other` offsets as well.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// assert_eq!(
+ /// TextRange::empty(0.into()).cover_offset(20.into()),
+ /// TextRange::new(0.into(), 20.into()),
+ /// )
+ /// ```
+ #[inline]
+ pub fn cover_offset(self, offset: TextSize) -> TextRange {
+ self.cover(TextRange::empty(offset))
+ }
+
+ /// Add an offset to this range.
+ ///
+ /// Note that this is not appropriate for changing where a `TextRange` is
+ /// within some string; rather, it is for changing the reference anchor
+ /// that the `TextRange` is measured against.
+ ///
+ /// The unchecked version (`Add::add`) will _always_ panic on overflow,
+ /// in contrast to primitive integers, which check in debug mode only.
+ #[inline]
+ pub fn checked_add(self, offset: TextSize) -> Option<TextRange> {
+ Some(TextRange {
+ start: self.start.checked_add(offset)?,
+ end: self.end.checked_add(offset)?,
+ })
+ }
+
+ /// Subtract an offset from this range.
+ ///
+ /// Note that this is not appropriate for changing where a `TextRange` is
+ /// within some string; rather, it is for changing the reference anchor
+ /// that the `TextRange` is measured against.
+ ///
+ /// The unchecked version (`Sub::sub`) will _always_ panic on overflow,
+ /// in contrast to primitive integers, which check in debug mode only.
+ #[inline]
+ pub fn checked_sub(self, offset: TextSize) -> Option<TextRange> {
+ Some(TextRange {
+ start: self.start.checked_sub(offset)?,
+ end: self.end.checked_sub(offset)?,
+ })
+ }
+
+ /// Relative order of the two ranges (overlapping ranges are considered
+ /// equal).
+ ///
+ ///
+ /// This is useful when, for example, binary searching an array of disjoint
+ /// ranges.
+ ///
+ /// # Examples
+ ///
+ /// ```
+ /// # use text_size::*;
+ /// # use std::cmp::Ordering;
+ ///
+ /// let a = TextRange::new(0.into(), 3.into());
+ /// let b = TextRange::new(4.into(), 5.into());
+ /// assert_eq!(a.ordering(b), Ordering::Less);
+ ///
+ /// let a = TextRange::new(0.into(), 3.into());
+ /// let b = TextRange::new(3.into(), 5.into());
+ /// assert_eq!(a.ordering(b), Ordering::Less);
+ ///
+ /// let a = TextRange::new(0.into(), 3.into());
+ /// let b = TextRange::new(2.into(), 5.into());
+ /// assert_eq!(a.ordering(b), Ordering::Equal);
+ ///
+ /// let a = TextRange::new(0.into(), 3.into());
+ /// let b = TextRange::new(2.into(), 2.into());
+ /// assert_eq!(a.ordering(b), Ordering::Equal);
+ ///
+ /// let a = TextRange::new(2.into(), 3.into());
+ /// let b = TextRange::new(2.into(), 2.into());
+ /// assert_eq!(a.ordering(b), Ordering::Greater);
+ /// ```
+ #[inline]
+ pub fn ordering(self, other: TextRange) -> Ordering {
+ if self.end() <= other.start() {
+ Ordering::Less
+ } else if other.end() <= self.start() {
+ Ordering::Greater
+ } else {
+ Ordering::Equal
+ }
+ }
+}
+
+impl Index<TextRange> for str {
+ type Output = str;
+ #[inline]
+ fn index(&self, index: TextRange) -> &str {
+ &self[Range::<usize>::from(index)]
+ }
+}
+
+impl Index<TextRange> for String {
+ type Output = str;
+ #[inline]
+ fn index(&self, index: TextRange) -> &str {
+ &self[Range::<usize>::from(index)]
+ }
+}
+
+impl IndexMut<TextRange> for str {
+ #[inline]
+ fn index_mut(&mut self, index: TextRange) -> &mut str {
+ &mut self[Range::<usize>::from(index)]
+ }
+}
+
+impl IndexMut<TextRange> for String {
+ #[inline]
+ fn index_mut(&mut self, index: TextRange) -> &mut str {
+ &mut self[Range::<usize>::from(index)]
+ }
+}
+
+impl RangeBounds<TextSize> for TextRange {
+ fn start_bound(&self) -> Bound<&TextSize> {
+ Bound::Included(&self.start)
+ }
+
+ fn end_bound(&self) -> Bound<&TextSize> {
+ Bound::Excluded(&self.end)
+ }
+}
+
+impl<T> From<TextRange> for Range<T>
+where
+ T: From<TextSize>,
+{
+ #[inline]
+ fn from(r: TextRange) -> Self {
+ r.start().into()..r.end().into()
+ }
+}
+
+macro_rules! ops {
+ (impl $Op:ident for TextRange by fn $f:ident = $op:tt) => {
+ impl $Op<&TextSize> for TextRange {
+ type Output = TextRange;
+ #[inline]
+ fn $f(self, other: &TextSize) -> TextRange {
+ self $op *other
+ }
+ }
+ impl<T> $Op<T> for &TextRange
+ where
+ TextRange: $Op<T, Output=TextRange>,
+ {
+ type Output = TextRange;
+ #[inline]
+ fn $f(self, other: T) -> TextRange {
+ *self $op other
+ }
+ }
+ };
+}
+
+impl Add<TextSize> for TextRange {
+ type Output = TextRange;
+ #[inline]
+ fn add(self, offset: TextSize) -> TextRange {
+ self.checked_add(offset)
+ .expect("TextRange +offset overflowed")
+ }
+}
+
+impl Sub<TextSize> for TextRange {
+ type Output = TextRange;
+ #[inline]
+ fn sub(self, offset: TextSize) -> TextRange {
+ self.checked_sub(offset)
+ .expect("TextRange -offset overflowed")
+ }
+}
+
+ops!(impl Add for TextRange by fn add = +);
+ops!(impl Sub for TextRange by fn sub = -);
+
+impl<A> AddAssign<A> for TextRange
+where
+ TextRange: Add<A, Output = TextRange>,
+{
+ #[inline]
+ fn add_assign(&mut self, rhs: A) {
+ *self = *self + rhs
+ }
+}
+
+impl<S> SubAssign<S> for TextRange
+where
+ TextRange: Sub<S, Output = TextRange>,
+{
+ #[inline]
+ fn sub_assign(&mut self, rhs: S) {
+ *self = *self - rhs
+ }
+}
diff --git a/vendor/text-size/src/serde_impls.rs b/vendor/text-size/src/serde_impls.rs
new file mode 100644
index 000000000..a94bee956
--- /dev/null
+++ b/vendor/text-size/src/serde_impls.rs
@@ -0,0 +1,48 @@
+use {
+ crate::{TextRange, TextSize},
+ serde::{de, Deserialize, Deserializer, Serialize, Serializer},
+};
+
+impl Serialize for TextSize {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.raw.serialize(serializer)
+ }
+}
+
+impl<'de> Deserialize<'de> for TextSize {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ u32::deserialize(deserializer).map(TextSize::from)
+ }
+}
+
+impl Serialize for TextRange {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ (self.start(), self.end()).serialize(serializer)
+ }
+}
+
+impl<'de> Deserialize<'de> for TextRange {
+ #[allow(clippy::nonminimal_bool)]
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ let (start, end) = Deserialize::deserialize(deserializer)?;
+ if !(start <= end) {
+ return Err(de::Error::custom(format!(
+ "invalid range: {:?}..{:?}",
+ start, end
+ )));
+ }
+ Ok(TextRange::new(start, end))
+ }
+}
diff --git a/vendor/text-size/src/size.rs b/vendor/text-size/src/size.rs
new file mode 100644
index 000000000..ab2ec9a73
--- /dev/null
+++ b/vendor/text-size/src/size.rs
@@ -0,0 +1,161 @@
+use {
+ crate::TextLen,
+ std::{
+ convert::TryFrom,
+ fmt, iter,
+ num::TryFromIntError,
+ ops::{Add, AddAssign, Sub, SubAssign},
+ u32,
+ },
+};
+
+/// A measure of text length. Also, equivalently, an index into text.
+///
+/// This is a UTF-8 bytes offset stored as `u32`, but
+/// most clients should treat it as an opaque measure.
+///
+/// For cases that need to escape `TextSize` and return to working directly
+/// with primitive integers, `TextSize` can be converted losslessly to/from
+/// `u32` via [`From`] conversions as well as losslessly be converted [`Into`]
+/// `usize`. The `usize -> TextSize` direction can be done via [`TryFrom`].
+///
+/// These escape hatches are primarily required for unit testing and when
+/// converting from UTF-8 size to another coordinate space, such as UTF-16.
+#[derive(Clone, Copy, Default, PartialEq, Eq, PartialOrd, Ord, Hash)]
+pub struct TextSize {
+ pub(crate) raw: u32,
+}
+
+impl fmt::Debug for TextSize {
+ fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
+ write!(f, "{}", self.raw)
+ }
+}
+
+impl TextSize {
+ /// The text size of some primitive text-like object.
+ ///
+ /// Accepts `char`, `&str`, and `&String`.
+ ///
+ /// # Examples
+ ///
+ /// ```rust
+ /// # use text_size::*;
+ /// let char_size = TextSize::of('🦀');
+ /// assert_eq!(char_size, TextSize::from(4));
+ ///
+ /// let str_size = TextSize::of("rust-analyzer");
+ /// assert_eq!(str_size, TextSize::from(13));
+ /// ```
+ #[inline]
+ pub fn of<T: TextLen>(text: T) -> TextSize {
+ text.text_len()
+ }
+}
+
+/// Methods to act like a primitive integer type, where reasonably applicable.
+// Last updated for parity with Rust 1.42.0.
+impl TextSize {
+ /// Checked addition. Returns `None` if overflow occurred.
+ #[inline]
+ pub fn checked_add(self, rhs: TextSize) -> Option<TextSize> {
+ self.raw.checked_add(rhs.raw).map(|raw| TextSize { raw })
+ }
+
+ /// Checked subtraction. Returns `None` if overflow occurred.
+ #[inline]
+ pub fn checked_sub(self, rhs: TextSize) -> Option<TextSize> {
+ self.raw.checked_sub(rhs.raw).map(|raw| TextSize { raw })
+ }
+}
+
+impl From<u32> for TextSize {
+ #[inline]
+ fn from(raw: u32) -> Self {
+ TextSize { raw }
+ }
+}
+
+impl From<TextSize> for u32 {
+ #[inline]
+ fn from(value: TextSize) -> Self {
+ value.raw
+ }
+}
+
+impl TryFrom<usize> for TextSize {
+ type Error = TryFromIntError;
+ #[inline]
+ fn try_from(value: usize) -> Result<Self, TryFromIntError> {
+ Ok(u32::try_from(value)?.into())
+ }
+}
+
+impl From<TextSize> for usize {
+ #[inline]
+ fn from(value: TextSize) -> Self {
+ value.raw as usize
+ }
+}
+
+macro_rules! ops {
+ (impl $Op:ident for TextSize by fn $f:ident = $op:tt) => {
+ impl $Op<TextSize> for TextSize {
+ type Output = TextSize;
+ #[inline]
+ fn $f(self, other: TextSize) -> TextSize {
+ TextSize { raw: self.raw $op other.raw }
+ }
+ }
+ impl $Op<&TextSize> for TextSize {
+ type Output = TextSize;
+ #[inline]
+ fn $f(self, other: &TextSize) -> TextSize {
+ self $op *other
+ }
+ }
+ impl<T> $Op<T> for &TextSize
+ where
+ TextSize: $Op<T, Output=TextSize>,
+ {
+ type Output = TextSize;
+ #[inline]
+ fn $f(self, other: T) -> TextSize {
+ *self $op other
+ }
+ }
+ };
+}
+
+ops!(impl Add for TextSize by fn add = +);
+ops!(impl Sub for TextSize by fn sub = -);
+
+impl<A> AddAssign<A> for TextSize
+where
+ TextSize: Add<A, Output = TextSize>,
+{
+ #[inline]
+ fn add_assign(&mut self, rhs: A) {
+ *self = *self + rhs
+ }
+}
+
+impl<S> SubAssign<S> for TextSize
+where
+ TextSize: Sub<S, Output = TextSize>,
+{
+ #[inline]
+ fn sub_assign(&mut self, rhs: S) {
+ *self = *self - rhs
+ }
+}
+
+impl<A> iter::Sum<A> for TextSize
+where
+ TextSize: Add<A, Output = TextSize>,
+{
+ #[inline]
+ fn sum<I: Iterator<Item = A>>(iter: I) -> TextSize {
+ iter.fold(0.into(), Add::add)
+ }
+}
diff --git a/vendor/text-size/src/traits.rs b/vendor/text-size/src/traits.rs
new file mode 100644
index 000000000..d0bb6c1f6
--- /dev/null
+++ b/vendor/text-size/src/traits.rs
@@ -0,0 +1,36 @@
+use {crate::TextSize, std::convert::TryInto};
+
+use priv_in_pub::Sealed;
+mod priv_in_pub {
+ pub trait Sealed {}
+}
+
+/// Primitives with a textual length that can be passed to [`TextSize::of`].
+pub trait TextLen: Copy + Sealed {
+ /// The textual length of this primitive.
+ fn text_len(self) -> TextSize;
+}
+
+impl Sealed for &'_ str {}
+impl TextLen for &'_ str {
+ #[inline]
+ fn text_len(self) -> TextSize {
+ self.len().try_into().unwrap()
+ }
+}
+
+impl Sealed for &'_ String {}
+impl TextLen for &'_ String {
+ #[inline]
+ fn text_len(self) -> TextSize {
+ self.as_str().text_len()
+ }
+}
+
+impl Sealed for char {}
+impl TextLen for char {
+ #[inline]
+ fn text_len(self) -> TextSize {
+ (self.len_utf8() as u32).into()
+ }
+}
diff --git a/vendor/text-size/tests/auto_traits.rs b/vendor/text-size/tests/auto_traits.rs
new file mode 100644
index 000000000..6e6236953
--- /dev/null
+++ b/vendor/text-size/tests/auto_traits.rs
@@ -0,0 +1,18 @@
+use {
+ static_assertions::*,
+ std::{
+ fmt::Debug,
+ hash::Hash,
+ marker::{Send, Sync},
+ panic::{RefUnwindSafe, UnwindSafe},
+ },
+ text_size::*,
+};
+
+// auto traits
+assert_impl_all!(TextSize: Send, Sync, Unpin, UnwindSafe, RefUnwindSafe);
+assert_impl_all!(TextRange: Send, Sync, Unpin, UnwindSafe, RefUnwindSafe);
+
+// common traits
+assert_impl_all!(TextSize: Copy, Debug, Default, Hash, Ord);
+assert_impl_all!(TextRange: Copy, Debug, Default, Hash, Eq);
diff --git a/vendor/text-size/tests/constructors.rs b/vendor/text-size/tests/constructors.rs
new file mode 100644
index 000000000..9ff4e19c6
--- /dev/null
+++ b/vendor/text-size/tests/constructors.rs
@@ -0,0 +1,24 @@
+use text_size::TextSize;
+
+#[derive(Copy, Clone)]
+struct BadRope<'a>(&'a [&'a str]);
+
+impl BadRope<'_> {
+ fn text_len(self) -> TextSize {
+ self.0.iter().copied().map(TextSize::of).sum()
+ }
+}
+
+#[test]
+fn main() {
+ let x: char = 'c';
+ let _ = TextSize::of(x);
+
+ let x: &str = "hello";
+ let _ = TextSize::of(x);
+
+ let x: &String = &"hello".into();
+ let _ = TextSize::of(x);
+
+ let _ = BadRope(&[""]).text_len();
+}
diff --git a/vendor/text-size/tests/indexing.rs b/vendor/text-size/tests/indexing.rs
new file mode 100644
index 000000000..ebbed7700
--- /dev/null
+++ b/vendor/text-size/tests/indexing.rs
@@ -0,0 +1,8 @@
+use text_size::*;
+
+#[test]
+fn main() {
+ let range = TextRange::default();
+ &""[range];
+ &String::new()[range];
+}
diff --git a/vendor/text-size/tests/main.rs b/vendor/text-size/tests/main.rs
new file mode 100644
index 000000000..5e6b86d65
--- /dev/null
+++ b/vendor/text-size/tests/main.rs
@@ -0,0 +1,76 @@
+use {std::ops, text_size::*};
+
+fn size(x: u32) -> TextSize {
+ TextSize::from(x)
+}
+
+fn range(x: ops::Range<u32>) -> TextRange {
+ TextRange::new(x.start.into(), x.end.into())
+}
+
+#[test]
+fn sum() {
+ let xs: Vec<TextSize> = vec![size(0), size(1), size(2)];
+ assert_eq!(xs.iter().sum::<TextSize>(), size(3));
+ assert_eq!(xs.into_iter().sum::<TextSize>(), size(3));
+}
+
+#[test]
+fn math() {
+ assert_eq!(size(10) + size(5), size(15));
+ assert_eq!(size(10) - size(5), size(5));
+}
+
+#[test]
+fn checked_math() {
+ assert_eq!(size(1).checked_add(size(1)), Some(size(2)));
+ assert_eq!(size(1).checked_sub(size(1)), Some(size(0)));
+ assert_eq!(size(1).checked_sub(size(2)), None);
+ assert_eq!(size(!0).checked_add(size(1)), None);
+}
+
+#[test]
+#[rustfmt::skip]
+fn contains() {
+ assert!( range(2..4).contains_range(range(2..3)));
+ assert!( ! range(2..4).contains_range(range(1..3)));
+}
+
+#[test]
+fn intersect() {
+ assert_eq!(range(1..2).intersect(range(2..3)), Some(range(2..2)));
+ assert_eq!(range(1..5).intersect(range(2..3)), Some(range(2..3)));
+ assert_eq!(range(1..2).intersect(range(3..4)), None);
+}
+
+#[test]
+fn cover() {
+ assert_eq!(range(1..2).cover(range(2..3)), range(1..3));
+ assert_eq!(range(1..5).cover(range(2..3)), range(1..5));
+ assert_eq!(range(1..2).cover(range(4..5)), range(1..5));
+}
+
+#[test]
+fn cover_offset() {
+ assert_eq!(range(1..3).cover_offset(size(0)), range(0..3));
+ assert_eq!(range(1..3).cover_offset(size(1)), range(1..3));
+ assert_eq!(range(1..3).cover_offset(size(2)), range(1..3));
+ assert_eq!(range(1..3).cover_offset(size(3)), range(1..3));
+ assert_eq!(range(1..3).cover_offset(size(4)), range(1..4));
+}
+
+#[test]
+#[rustfmt::skip]
+fn contains_point() {
+ assert!( ! range(1..3).contains(size(0)));
+ assert!( range(1..3).contains(size(1)));
+ assert!( range(1..3).contains(size(2)));
+ assert!( ! range(1..3).contains(size(3)));
+ assert!( ! range(1..3).contains(size(4)));
+
+ assert!( ! range(1..3).contains_inclusive(size(0)));
+ assert!( range(1..3).contains_inclusive(size(1)));
+ assert!( range(1..3).contains_inclusive(size(2)));
+ assert!( range(1..3).contains_inclusive(size(3)));
+ assert!( ! range(1..3).contains_inclusive(size(4)));
+}
diff --git a/vendor/text-size/tests/serde.rs b/vendor/text-size/tests/serde.rs
new file mode 100644
index 000000000..874258a35
--- /dev/null
+++ b/vendor/text-size/tests/serde.rs
@@ -0,0 +1,79 @@
+use {serde_test::*, std::ops, text_size::*};
+
+fn size(x: u32) -> TextSize {
+ TextSize::from(x)
+}
+
+fn range(x: ops::Range<u32>) -> TextRange {
+ TextRange::new(x.start.into(), x.end.into())
+}
+
+#[test]
+fn size_serialization() {
+ assert_tokens(&size(00), &[Token::U32(00)]);
+ assert_tokens(&size(10), &[Token::U32(10)]);
+ assert_tokens(&size(20), &[Token::U32(20)]);
+ assert_tokens(&size(30), &[Token::U32(30)]);
+}
+
+#[test]
+fn range_serialization() {
+ assert_tokens(
+ &range(00..10),
+ &[
+ Token::Tuple { len: 2 },
+ Token::U32(00),
+ Token::U32(10),
+ Token::TupleEnd,
+ ],
+ );
+ assert_tokens(
+ &range(10..20),
+ &[
+ Token::Tuple { len: 2 },
+ Token::U32(10),
+ Token::U32(20),
+ Token::TupleEnd,
+ ],
+ );
+ assert_tokens(
+ &range(20..30),
+ &[
+ Token::Tuple { len: 2 },
+ Token::U32(20),
+ Token::U32(30),
+ Token::TupleEnd,
+ ],
+ );
+ assert_tokens(
+ &range(30..40),
+ &[
+ Token::Tuple { len: 2 },
+ Token::U32(30),
+ Token::U32(40),
+ Token::TupleEnd,
+ ],
+ );
+}
+
+#[test]
+fn invalid_range_deserialization() {
+ assert_tokens::<TextRange>(
+ &range(62..92),
+ &[
+ Token::Tuple { len: 2 },
+ Token::U32(62),
+ Token::U32(92),
+ Token::TupleEnd,
+ ],
+ );
+ assert_de_tokens_error::<TextRange>(
+ &[
+ Token::Tuple { len: 2 },
+ Token::U32(92),
+ Token::U32(62),
+ Token::TupleEnd,
+ ],
+ "invalid range: 92..62",
+ );
+}