No bug - Revendor rust dependencies

--HG--
rename : third_party/rust/serde/src/bytes.rs => third_party/rust/serde-0.9.9/src/bytes.rs
rename : third_party/rust/serde/src/de/content.rs => third_party/rust/serde-0.9.9/src/de/content.rs
rename : third_party/rust/serde/src/de/private.rs => third_party/rust/serde-0.9.9/src/de/private.rs
rename : third_party/rust/serde/src/error.rs => third_party/rust/serde-0.9.9/src/error.rs
rename : third_party/rust/serde/src/iter.rs => third_party/rust/serde-0.9.9/src/iter.rs
rename : third_party/rust/serde/src/ser/content.rs => third_party/rust/serde-0.9.9/src/ser/content.rs
rename : third_party/rust/serde/src/ser/private.rs => third_party/rust/serde-0.9.9/src/ser/private.rs
rename : third_party/rust/serde/src/utils.rs => third_party/rust/serde-0.9.9/src/utils.rs
rename : third_party/rust/unicode-bidi/src/tables.rs => third_party/rust/unicode-bidi-0.2.5/src/tables.rs
This commit is contained in:
Servo VCS Sync 2017-05-23 05:17:49 +00:00
parent 4439d58753
commit 1f2bbf4599
89 changed files with 22099 additions and 4244 deletions

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"e2817af66db5f058a55b5f126ca9a663925bfeb36a592a4121e7e9a44d3a3453","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"ebe318a04cf4e547e0f3ab97f1345ecb553358ee13ea81f99e3323e37d70ccdf","src/bytes.rs":"2b6a9c2c3d6eabe8633adee6655a3b94f0d1e931e740e72699b6965bee21e226","src/de/content.rs":"469d3298d4109d514a8cd630273a288a361544979e2ab23aaa325b2201f9361f","src/de/from_primitive.rs":"b1bd165e343a4380965551709119ef9ed895e4b025045a810dabd671511ba3ab","src/de/impls.rs":"762c3f32627d12555ccd08fcdf3dfb621403c35cde8a5af7866e2ad74c95a4c8","src/de/mod.rs":"365ee7038c53e88cddd451afd11d459f65185fd04523bd000a6b424ac4f71db7","src/de/private.rs":"2578dbc89c2f2a852caed3fdc40f710d4828d085c4e954dd96789d678583424e","src/de/value.rs":"67a34c03fda6521c082548984b0116494e5fbff7e60e30e06f0dda62d9d3e083","src/error.rs":"3af5286c1daad9bfd504693f8a8587f7044c9b9520e23e072549c43a72e4821d","src/export.rs":"0b8e6b642010ad6a71f13f5facfd91e9da1d7c99d479dba020dec10e88fb6b0f","src/iter.rs":"af3c43712c240b3a06870e0b0b6e837b142d5a65c62742fa358fe36a9d9319a7","src/lib.rs":"75df159c150e62c99887c0a4f23ed1271c9eb910ebc79a2d4bd279b0e11ce7e3","src/macros.rs":"af1f75bb34460b814e44f7bc67bdd1dc1bba97f1f2a31744c22e1bfcdc29499a","src/ser/content.rs":"f1cd3724e5ddeacb75b3585b2fd2be7c42fc764444b1f764e31ed9fe49f62025","src/ser/impls.rs":"51d4036b8309381af8267375778bf80c3a9114577c03a04da9a679462077efac","src/ser/impossible.rs":"f1332a1250f9c1d85d679653ade502cf99bdff0344b9f864e6cf1a1789d7c597","src/ser/mod.rs":"d1d821488453651a986bb4e4608f72868c09a71a8dbf693584758b25603ae8bf","src/ser/private.rs":"3999dc19d61d43a64d5d1bdda61f80ea16405a926b074b5441b39d87318be73b","src/utils.rs":"ed271c0825c01d7b24968bf47ce9e2475ca219faf733eb33831d6e19bf07aaf1"},"package":"05a67b8a53f885f4b6e3ed183806035819f9862474e747fe4488a6d63bcbfcb7"}

View File

34
third_party/rust/serde-0.9.9/Cargo.toml vendored Normal file
View File

@ -0,0 +1,34 @@
[package]
name = "serde"
version = "0.9.9"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde/"
keywords = ["serde", "serialization", "no_std"]
categories = ["encoding"]
readme = "../README.md"
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[badges]
travis-ci = { repository = "serde-rs/serde" }
[features]
default = ["std"]
std = []
unstable = []
alloc = ["unstable"]
collections = ["alloc"]
unstable-testing = ["unstable", "std"]
# to get serde_derive picked up by play.integer32.com
playground = ["serde_derive"]
[dependencies]
serde_derive = { version = "0.9", optional = true }
[dev-dependencies]
serde_derive = "0.9"

View File

@ -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.

View File

@ -0,0 +1,25 @@
Copyright (c) 2014 The Rust Project Developers
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.

71
third_party/rust/serde-0.9.9/README.md vendored Normal file
View File

@ -0,0 +1,71 @@
# Serde &emsp; [![Build Status](https://api.travis-ci.org/serde-rs/serde.svg?branch=master)](https://travis-ci.org/serde-rs/serde) [![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde)
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
---
You may be looking for:
- [An overview of Serde](https://serde.rs/)
- [Data formats supported by Serde](https://serde.rs/#data-formats)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
- [Examples](https://serde.rs/examples.html)
- [API documentation](https://docs.serde.rs/serde/)
- [Release notes](https://github.com/serde-rs/serde/releases)
## Serde in action
```rust
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
// Convert the Point to a JSON string.
let serialized = serde_json::to_string(&point).unwrap();
// Prints serialized = {"x":1,"y":2}
println!("serialized = {}", serialized);
// Convert the JSON string back to a Point.
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
// Prints deserialized = Point { x: 1, y: 2 }
println!("deserialized = {:?}", deserialized);
}
```
## Getting help
Serde developers live in the #serde channel on
[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a
good resource with generally faster response time but less specific knowledge
about Serde. If IRC is not your thing or you don't get a good response, we are
happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new)
as well.
## License
Serde is 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 Serde by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

View File

@ -0,0 +1,409 @@
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Extracted from https://github.com/rust-num/num.
// Rust 1.5 is unhappy that this private module is undocumented.
#![allow(missing_docs)]
use core::{usize, u8, u16, u32, u64};
use core::{isize, i8, i16, i32, i64};
use core::{f32, f64};
use core::mem::size_of;
/// Numbers which have upper and lower bounds
pub trait Bounded {
// FIXME (#5527): These should be associated constants
/// returns the smallest finite number this type can represent
fn min_value() -> Self;
/// returns the largest finite number this type can represent
fn max_value() -> Self;
}
macro_rules! bounded_impl {
($t:ty, $min:expr, $max:expr) => {
impl Bounded for $t {
#[inline]
fn min_value() -> $t { $min }
#[inline]
fn max_value() -> $t { $max }
}
}
}
bounded_impl!(usize, usize::MIN, usize::MAX);
bounded_impl!(u8, u8::MIN, u8::MAX);
bounded_impl!(u16, u16::MIN, u16::MAX);
bounded_impl!(u32, u32::MIN, u32::MAX);
bounded_impl!(u64, u64::MIN, u64::MAX);
bounded_impl!(isize, isize::MIN, isize::MAX);
bounded_impl!(i8, i8::MIN, i8::MAX);
bounded_impl!(i16, i16::MIN, i16::MAX);
bounded_impl!(i32, i32::MIN, i32::MAX);
bounded_impl!(i64, i64::MIN, i64::MAX);
bounded_impl!(f32, f32::MIN, f32::MAX);
bounded_impl!(f64, f64::MIN, f64::MAX);
/// A generic trait for converting a value to a number.
pub trait ToPrimitive {
/// Converts the value of `self` to an `isize`.
#[inline]
fn to_isize(&self) -> Option<isize> {
self.to_i64().and_then(|x| x.to_isize())
}
/// Converts the value of `self` to an `i8`.
#[inline]
fn to_i8(&self) -> Option<i8> {
self.to_i64().and_then(|x| x.to_i8())
}
/// Converts the value of `self` to an `i16`.
#[inline]
fn to_i16(&self) -> Option<i16> {
self.to_i64().and_then(|x| x.to_i16())
}
/// Converts the value of `self` to an `i32`.
#[inline]
fn to_i32(&self) -> Option<i32> {
self.to_i64().and_then(|x| x.to_i32())
}
/// Converts the value of `self` to an `i64`.
fn to_i64(&self) -> Option<i64>;
/// Converts the value of `self` to a `usize`.
#[inline]
fn to_usize(&self) -> Option<usize> {
self.to_u64().and_then(|x| x.to_usize())
}
/// Converts the value of `self` to an `u8`.
#[inline]
fn to_u8(&self) -> Option<u8> {
self.to_u64().and_then(|x| x.to_u8())
}
/// Converts the value of `self` to an `u16`.
#[inline]
fn to_u16(&self) -> Option<u16> {
self.to_u64().and_then(|x| x.to_u16())
}
/// Converts the value of `self` to an `u32`.
#[inline]
fn to_u32(&self) -> Option<u32> {
self.to_u64().and_then(|x| x.to_u32())
}
/// Converts the value of `self` to an `u64`.
#[inline]
fn to_u64(&self) -> Option<u64>;
/// Converts the value of `self` to an `f32`.
#[inline]
fn to_f32(&self) -> Option<f32> {
self.to_f64().and_then(|x| x.to_f32())
}
/// Converts the value of `self` to an `f64`.
#[inline]
fn to_f64(&self) -> Option<f64> {
self.to_i64().and_then(|x| x.to_f64())
}
}
macro_rules! impl_to_primitive_int_to_int {
($SrcT:ty, $DstT:ty, $slf:expr) => (
{
if size_of::<$SrcT>() <= size_of::<$DstT>() {
Some($slf as $DstT)
} else {
let n = $slf as i64;
let min_value: $DstT = Bounded::min_value();
let max_value: $DstT = Bounded::max_value();
if min_value as i64 <= n && n <= max_value as i64 {
Some($slf as $DstT)
} else {
None
}
}
}
)
}
macro_rules! impl_to_primitive_int_to_uint {
($SrcT:ty, $DstT:ty, $slf:expr) => (
{
let zero: $SrcT = 0;
let max_value: $DstT = Bounded::max_value();
if zero <= $slf && $slf as u64 <= max_value as u64 {
Some($slf as $DstT)
} else {
None
}
}
)
}
macro_rules! impl_to_primitive_int {
($T:ty) => (
impl ToPrimitive for $T {
#[inline]
fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
#[inline]
fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
#[inline]
fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
#[inline]
fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32, *self) }
#[inline]
fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
#[inline]
fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
#[inline]
fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
#[inline]
fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
#[inline]
fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32, *self) }
#[inline]
fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64, *self) }
#[inline]
fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
#[inline]
fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
}
)
}
impl_to_primitive_int! { isize }
impl_to_primitive_int! { i8 }
impl_to_primitive_int! { i16 }
impl_to_primitive_int! { i32 }
impl_to_primitive_int! { i64 }
macro_rules! impl_to_primitive_uint_to_int {
($DstT:ty, $slf:expr) => (
{
let max_value: $DstT = Bounded::max_value();
if $slf as u64 <= max_value as u64 {
Some($slf as $DstT)
} else {
None
}
}
)
}
macro_rules! impl_to_primitive_uint_to_uint {
($SrcT:ty, $DstT:ty, $slf:expr) => (
{
if size_of::<$SrcT>() <= size_of::<$DstT>() {
Some($slf as $DstT)
} else {
let zero: $SrcT = 0;
let max_value: $DstT = Bounded::max_value();
if zero <= $slf && $slf as u64 <= max_value as u64 {
Some($slf as $DstT)
} else {
None
}
}
}
)
}
macro_rules! impl_to_primitive_uint {
($T:ty) => (
impl ToPrimitive for $T {
#[inline]
fn to_isize(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
#[inline]
fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
#[inline]
fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
#[inline]
fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32, *self) }
#[inline]
fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
#[inline]
fn to_usize(&self) -> Option<usize> {
impl_to_primitive_uint_to_uint!($T, usize, *self)
}
#[inline]
fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
#[inline]
fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
#[inline]
fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32, *self) }
#[inline]
fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64, *self) }
#[inline]
fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
#[inline]
fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
}
)
}
impl_to_primitive_uint! { usize }
impl_to_primitive_uint! { u8 }
impl_to_primitive_uint! { u16 }
impl_to_primitive_uint! { u32 }
impl_to_primitive_uint! { u64 }
macro_rules! impl_to_primitive_float_to_float {
($SrcT:ident, $DstT:ident, $slf:expr) => (
if size_of::<$SrcT>() <= size_of::<$DstT>() {
Some($slf as $DstT)
} else {
let n = $slf as f64;
let max_value: $SrcT = ::core::$SrcT::MAX;
if -max_value as f64 <= n && n <= max_value as f64 {
Some($slf as $DstT)
} else {
None
}
}
)
}
macro_rules! impl_to_primitive_float {
($T:ident) => (
impl ToPrimitive for $T {
#[inline]
fn to_isize(&self) -> Option<isize> { Some(*self as isize) }
#[inline]
fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
#[inline]
fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
#[inline]
fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
#[inline]
fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
#[inline]
fn to_usize(&self) -> Option<usize> { Some(*self as usize) }
#[inline]
fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
#[inline]
fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
#[inline]
fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
#[inline]
fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
#[inline]
fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32, *self) }
#[inline]
fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64, *self) }
}
)
}
impl_to_primitive_float! { f32 }
impl_to_primitive_float! { f64 }
pub trait FromPrimitive: Sized {
#[inline]
fn from_isize(n: isize) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
#[inline]
fn from_i8(n: i8) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
fn from_i64(n: i64) -> Option<Self>;
#[inline]
fn from_usize(n: usize) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
#[inline]
fn from_u8(n: u8) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
#[inline]
fn from_u32(n: u32) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
fn from_u64(n: u64) -> Option<Self>;
#[inline]
fn from_f32(n: f32) -> Option<Self> {
FromPrimitive::from_f64(n as f64)
}
#[inline]
fn from_f64(n: f64) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
}
macro_rules! impl_from_primitive {
($T:ty, $to_ty:ident) => (
impl FromPrimitive for $T {
#[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
#[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
#[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
#[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() }
#[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
#[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() }
}
)
}
impl_from_primitive! { isize, to_isize }
impl_from_primitive! { i8, to_i8 }
impl_from_primitive! { i16, to_i16 }
impl_from_primitive! { i32, to_i32 }
impl_from_primitive! { i64, to_i64 }
impl_from_primitive! { usize, to_usize }
impl_from_primitive! { u8, to_u8 }
impl_from_primitive! { u16, to_u16 }
impl_from_primitive! { u32, to_u32 }
impl_from_primitive! { u64, to_u64 }
impl_from_primitive! { f32, to_f32 }
impl_from_primitive! { f64, to_f64 }

File diff suppressed because it is too large Load Diff

1611
third_party/rust/serde-0.9.9/src/de/mod.rs vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,34 @@
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::String;
#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::borrow::Cow;
pub use core::default::Default;
pub use core::fmt;
pub use core::marker::PhantomData;
pub use core::option::Option::{self, None, Some};
pub use core::result::Result::{self, Ok, Err};
#[cfg(any(feature = "collections", feature = "std"))]
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
String::from_utf8_lossy(bytes)
}
// The generated code calls this like:
//
// let value = &_serde::export::from_utf8_lossy(bytes);
// Err(_serde::de::Error::unknown_variant(value, VARIANTS))
//
// so it is okay for the return type to be different from the std case as long
// as the above works.
#[cfg(not(any(feature = "collections", feature = "std")))]
pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
use core::str;
// Three unicode replacement characters if it fails. They look like a
// white-on-black question mark. The user will recognize it as invalid
// UTF-8.
str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}")
}

107
third_party/rust/serde-0.9.9/src/lib.rs vendored Normal file
View File

@ -0,0 +1,107 @@
//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
//! structures efficiently and generically.
//!
//! The Serde ecosystem consists of data structures that know how to serialize
//! and deserialize themselves along with data formats that know how to
//! serialize and deserialize other things. Serde provides the layer by which
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website https://serde.rs/ for additional documentation and
//! usage examples.
//!
//! ### Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's code
//! generation to automatically derive implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform roughly the same speed as a handwritten serializer
//! for the specific selection of data structure and data format.
//!
//! ### Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON](https://github.com/serde-rs/json), the ubiquitous JavaScript Object
//! Notation used by many HTTP APIs.
//! - [Bincode](https://github.com/TyOverby/bincode), a compact binary format
//! used for IPC within the Servo rendering engine.
//! - [CBOR](https://github.com/pyfisch/cbor), a Concise Binary Object
//! Representation designed for small message size without the need for
//! version negotiation.
//! - [YAML](https://github.com/dtolnay/serde-yaml), a popular human-friendly
//! configuration language that ain't markup language.
//! - [MessagePack](https://github.com/3Hren/msgpack-rust), an efficient binary
//! format that resembles a compact JSON.
//! - [TOML](https://github.com/alexcrichton/toml-rs), a minimal configuration
//! format used by [Cargo](http://doc.crates.io/manifest.html).
//! - [Pickle](https://github.com/birkenfeld/serde-pickle), a format common in
//! the Python world.
//! - [Hjson](https://github.com/laktak/hjson-rust), a variant of JSON designed
//! to be readable and writable by humans.
//! - [BSON](https://github.com/zonyitoo/bson-rs), the data storage and network
//! transfer format used by MongoDB.
//! - [URL](https://github.com/nox/serde_urlencoded), the x-www-form-urlencoded
//! format.
//! - [XML](https://github.com/serde-rs/xml), the flexible machine-friendly W3C
//! standard. *(deserialization only)*
//! - [Envy](https://github.com/softprops/envy), a way to deserialize
//! environment variables into Rust structs. *(deserialization only)*
//! - [Redis](https://github.com/OneSignal/serde-redis), deserialize values from
//! Redis when using [redis-rs](https://crates.io/crates/redis).
//! *(deserialization only)*
#![doc(html_root_url="https://docs.serde.rs")]
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "unstable", feature(inclusive_range, nonzero, specialization, zero_one))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "collections", feature(collections))]
#![cfg_attr(feature = "cargo-clippy", allow(linkedlist, type_complexity, doc_markdown))]
#![deny(missing_docs)]
#[cfg(feature = "collections")]
extern crate collections;
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "unstable")]
extern crate core as actual_core;
#[cfg(feature = "std")]
mod core {
pub use std::{ops, hash, fmt, cmp, marker, mem, i8, i16, i32, i64, u8, u16, u32, u64, isize,
usize, f32, f64, char, str, num, slice, iter, cell, default, result, option};
#[cfg(feature = "unstable")]
pub use actual_core::nonzero;
}
#[doc(inline)]
pub use ser::{Serialize, Serializer};
#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[macro_use]
mod macros;
pub mod bytes;
pub mod de;
#[cfg(feature = "std")]
#[doc(hidden)]
pub mod iter;
pub mod ser;
#[cfg_attr(feature = "std", doc(hidden))]
pub mod error;
mod utils;
// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;

View File

@ -0,0 +1,222 @@
#[cfg(feature = "std")]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_method {
($func:ident($($arg:ty),*)) => {
#[inline]
fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> ::std::result::Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor
{
self.deserialize(visitor)
}
};
}
#[cfg(not(feature = "std"))]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_method {
($func:ident($($arg:ty),*)) => {
#[inline]
fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> ::core::result::Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor
{
self.deserialize(visitor)
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_helper {
(bool) => {
forward_to_deserialize_method!{deserialize_bool()}
};
(u8) => {
forward_to_deserialize_method!{deserialize_u8()}
};
(u16) => {
forward_to_deserialize_method!{deserialize_u16()}
};
(u32) => {
forward_to_deserialize_method!{deserialize_u32()}
};
(u64) => {
forward_to_deserialize_method!{deserialize_u64()}
};
(i8) => {
forward_to_deserialize_method!{deserialize_i8()}
};
(i16) => {
forward_to_deserialize_method!{deserialize_i16()}
};
(i32) => {
forward_to_deserialize_method!{deserialize_i32()}
};
(i64) => {
forward_to_deserialize_method!{deserialize_i64()}
};
(f32) => {
forward_to_deserialize_method!{deserialize_f32()}
};
(f64) => {
forward_to_deserialize_method!{deserialize_f64()}
};
(char) => {
forward_to_deserialize_method!{deserialize_char()}
};
(str) => {
forward_to_deserialize_method!{deserialize_str()}
};
(string) => {
forward_to_deserialize_method!{deserialize_string()}
};
(unit) => {
forward_to_deserialize_method!{deserialize_unit()}
};
(option) => {
forward_to_deserialize_method!{deserialize_option()}
};
(seq) => {
forward_to_deserialize_method!{deserialize_seq()}
};
(seq_fixed_size) => {
forward_to_deserialize_method!{deserialize_seq_fixed_size(usize)}
};
(bytes) => {
forward_to_deserialize_method!{deserialize_bytes()}
};
(byte_buf) => {
forward_to_deserialize_method!{deserialize_byte_buf()}
};
(map) => {
forward_to_deserialize_method!{deserialize_map()}
};
(unit_struct) => {
forward_to_deserialize_method!{deserialize_unit_struct(&'static str)}
};
(newtype_struct) => {
forward_to_deserialize_method!{deserialize_newtype_struct(&'static str)}
};
(tuple_struct) => {
forward_to_deserialize_method!{deserialize_tuple_struct(&'static str, usize)}
};
(struct) => {
forward_to_deserialize_method!{deserialize_struct(&'static str, &'static [&'static str])}
};
(struct_field) => {
forward_to_deserialize_method!{deserialize_struct_field()}
};
(tuple) => {
forward_to_deserialize_method!{deserialize_tuple(usize)}
};
(enum) => {
forward_to_deserialize_method!{deserialize_enum(&'static str, &'static [&'static str])}
};
(ignored_any) => {
forward_to_deserialize_method!{deserialize_ignored_any()}
};
}
// Super explicit first paragraph because this shows up at the top level and
// trips up people who are just looking for basic Serialize / Deserialize
// documentation.
//
/// Helper macro when implementing the `Deserializer` part of a new data format
/// for Serde.
///
/// Some `Deserializer` implementations for self-describing formats do not care
/// what hint the `Visitor` gives them, they just want to blindly call the
/// `Visitor` method corresponding to the data they can tell is in the input.
/// This requires repetitive implementations of all the `Deserializer` trait
/// methods.
///
/// ```rust
/// # #[macro_use] extern crate serde;
/// # use serde::de::{value, Deserializer, Visitor};
/// # pub struct MyDeserializer;
/// # impl Deserializer for MyDeserializer {
/// # type Error = value::Error;
/// # fn deserialize<V>(self, _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor
/// # { unimplemented!() }
/// #
/// #[inline]
/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor
/// {
/// self.deserialize(visitor)
/// }
/// # forward_to_deserialize! {
/// # u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
/// # seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
/// # tuple_struct struct struct_field tuple enum ignored_any
/// # }
/// # }
/// # fn main() {}
/// ```
///
/// The `forward_to_deserialize!` macro implements these simple forwarding
/// methods so that they forward directly to `Deserializer::deserialize`. You
/// can choose which methods to forward.
///
/// ```rust
/// # #[macro_use] extern crate serde;
/// # use serde::de::{value, Deserializer, Visitor};
/// # pub struct MyDeserializer;
/// impl Deserializer for MyDeserializer {
/// # type Error = value::Error;
/// fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor
/// {
/// /* ... */
/// # let _ = visitor;
/// # unimplemented!()
/// }
///
/// forward_to_deserialize! {
/// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
/// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
/// tuple_struct struct struct_field tuple enum ignored_any
/// }
/// }
/// # fn main() {}
/// ```
#[macro_export]
macro_rules! forward_to_deserialize {
($($func:ident)*) => {
$(forward_to_deserialize_helper!{$func})*
};
}
/// Seralize the `$value` that implements Display as a string,
/// when that string is statically known to never have more than
/// a constant `$MAX_LEN` bytes.
///
/// Panics if the Display impl tries to write more than `$MAX_LEN` bytes.
#[cfg(feature = "std")]
// Not exported
macro_rules! serialize_display_bounded_length {
($value: expr, $MAX_LEN: expr, $serializer: expr) => {
{
use std::io::Write;
let mut buffer: [u8; $MAX_LEN] = unsafe { ::std::mem::uninitialized() };
let remaining_len;
{
let mut remaining = &mut buffer[..];
write!(remaining, "{}", $value).unwrap();
remaining_len = remaining.len()
}
let written_len = buffer.len() - remaining_len;
let written = &buffer[..written_len];
// write! only provides std::fmt::Formatter to Display implementations,
// which has methods write_str and write_char but no method to write arbitrary bytes.
// Therefore, `written` is well-formed in UTF-8.
let written_str = unsafe {
::std::str::from_utf8_unchecked(written)
};
$serializer.serialize_str(written_str)
}
}
}

View File

@ -0,0 +1,723 @@
#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::borrow::Cow;
#[cfg(feature = "std")]
use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, HashMap, HashSet, VecDeque};
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque, String, Vec};
#[cfg(feature = "collections")]
use collections::borrow::ToOwned;
#[cfg(feature = "std")]
use core::hash::{Hash, BuildHasher};
#[cfg(feature = "unstable")]
use core::iter;
#[cfg(feature = "std")]
use std::net;
#[cfg(feature = "unstable")]
use core::ops;
#[cfg(feature = "std")]
use std::path;
#[cfg(feature = "std")]
use std::rc::Rc;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::rc::Rc;
#[cfg(feature = "std")]
use std::time::Duration;
#[cfg(feature = "std")]
use std::sync::Arc;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::arc::Arc;
#[cfg(all(feature = "alloc", not(feature = "std")))]
use alloc::boxed::Box;
use core::marker::PhantomData;
#[cfg(feature = "unstable")]
use core::nonzero::{NonZero, Zeroable};
use super::{Serialize, SerializeSeq, SerializeTuple, Serializer};
#[cfg(feature = "std")]
use super::Error;
///////////////////////////////////////////////////////////////////////////////
macro_rules! impl_visit {
($ty:ty, $method:ident $($cast:tt)*) => {
impl Serialize for $ty {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
serializer.$method(*self $($cast)*)
}
}
}
}
impl_visit!(bool, serialize_bool);
impl_visit!(isize, serialize_i64 as i64);
impl_visit!(i8, serialize_i8);
impl_visit!(i16, serialize_i16);
impl_visit!(i32, serialize_i32);
impl_visit!(i64, serialize_i64);
impl_visit!(usize, serialize_u64 as u64);
impl_visit!(u8, serialize_u8);
impl_visit!(u16, serialize_u16);
impl_visit!(u32, serialize_u32);
impl_visit!(u64, serialize_u64);
impl_visit!(f32, serialize_f32);
impl_visit!(f64, serialize_f64);
impl_visit!(char, serialize_char);
///////////////////////////////////////////////////////////////////////////////
impl Serialize for str {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
serializer.serialize_str(self)
}
}
#[cfg(any(feature = "std", feature = "collections"))]
impl Serialize for String {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
(&self[..]).serialize(serializer)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for Option<T>
where T: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
match *self {
Some(ref value) => serializer.serialize_some(value),
None => serializer.serialize_none(),
}
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T> Serialize for PhantomData<T> {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
serializer.serialize_unit_struct("PhantomData")
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! array_impls {
($len:expr) => {
impl<T> Serialize for [T; $len] where T: Serialize {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
let mut seq = try!(serializer.serialize_seq_fixed_size($len));
for e in self {
try!(seq.serialize_element(e));
}
seq.end()
}
}
}
}
array_impls!(0);
array_impls!(1);
array_impls!(2);
array_impls!(3);
array_impls!(4);
array_impls!(5);
array_impls!(6);
array_impls!(7);
array_impls!(8);
array_impls!(9);
array_impls!(10);
array_impls!(11);
array_impls!(12);
array_impls!(13);
array_impls!(14);
array_impls!(15);
array_impls!(16);
array_impls!(17);
array_impls!(18);
array_impls!(19);
array_impls!(20);
array_impls!(21);
array_impls!(22);
array_impls!(23);
array_impls!(24);
array_impls!(25);
array_impls!(26);
array_impls!(27);
array_impls!(28);
array_impls!(29);
array_impls!(30);
array_impls!(31);
array_impls!(32);
///////////////////////////////////////////////////////////////////////////////
macro_rules! serialize_seq {
() => {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
serializer.collect_seq(self)
}
}
}
impl<T> Serialize for [T]
where T: Serialize
{
serialize_seq!();
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for BinaryHeap<T>
where T: Serialize + Ord
{
serialize_seq!();
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for BTreeSet<T>
where T: Serialize + Ord
{
serialize_seq!();
}
#[cfg(feature = "std")]
impl<T, H> Serialize for HashSet<T, H>
where T: Serialize + Eq + Hash,
H: BuildHasher
{
serialize_seq!();
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for LinkedList<T>
where T: Serialize
{
serialize_seq!();
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for Vec<T>
where T: Serialize
{
serialize_seq!();
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<T> Serialize for VecDeque<T>
where T: Serialize
{
serialize_seq!();
}
#[cfg(feature = "unstable")]
impl<A> Serialize for ops::Range<A>
where ops::Range<A>: ExactSizeIterator + iter::Iterator<Item = A> + Clone,
A: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
let mut seq = try!(serializer.serialize_seq(Some(self.len())));
for e in self.clone() {
try!(seq.serialize_element(&e));
}
seq.end()
}
}
#[cfg(feature = "unstable")]
impl<A> Serialize for ops::RangeInclusive<A>
where ops::RangeInclusive<A>: ExactSizeIterator + iter::Iterator<Item = A> + Clone,
A: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
let mut seq = try!(serializer.serialize_seq(Some(self.len())));
for e in self.clone() {
try!(seq.serialize_element(&e));
}
seq.end()
}
}
///////////////////////////////////////////////////////////////////////////////
impl Serialize for () {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
serializer.serialize_unit()
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! tuple_impls {
($(
$TupleVisitor:ident ($len:expr, $($T:ident),+) {
$($state:pat => $idx:tt,)+
}
)+) => {
$(
impl<$($T),+> Serialize for ($($T,)+)
where $($T: Serialize),+
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
let mut tuple = try!(serializer.serialize_tuple($len));
$(
try!(tuple.serialize_element(&self.$idx));
)+
tuple.end()
}
}
)+
}
}
tuple_impls! {
TupleVisitor1 (1, T0) {
0 => 0,
}
TupleVisitor2 (2, T0, T1) {
0 => 0,
1 => 1,
}
TupleVisitor3 (3, T0, T1, T2) {
0 => 0,
1 => 1,
2 => 2,
}
TupleVisitor4 (4, T0, T1, T2, T3) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
}
TupleVisitor5 (5, T0, T1, T2, T3, T4) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
}
TupleVisitor6 (6, T0, T1, T2, T3, T4, T5) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
}
TupleVisitor7 (7, T0, T1, T2, T3, T4, T5, T6) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
}
TupleVisitor8 (8, T0, T1, T2, T3, T4, T5, T6, T7) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
}
TupleVisitor9 (9, T0, T1, T2, T3, T4, T5, T6, T7, T8) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
}
TupleVisitor10 (10, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
}
TupleVisitor11 (11, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
}
TupleVisitor12 (12, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
}
TupleVisitor13 (13, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
12 => 12,
}
TupleVisitor14 (14, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
12 => 12,
13 => 13,
}
TupleVisitor15 (15, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
12 => 12,
13 => 13,
14 => 14,
}
TupleVisitor16 (16, T0, T1, T2, T3, T4, T5, T6, T7, T8, T9, T10, T11, T12, T13, T14, T15) {
0 => 0,
1 => 1,
2 => 2,
3 => 3,
4 => 4,
5 => 5,
6 => 6,
7 => 7,
8 => 8,
9 => 9,
10 => 10,
11 => 11,
12 => 12,
13 => 13,
14 => 14,
15 => 15,
}
}
///////////////////////////////////////////////////////////////////////////////
macro_rules! serialize_map {
() => {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer,
{
serializer.collect_map(self)
}
}
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<K, V> Serialize for BTreeMap<K, V>
where K: Serialize + Ord,
V: Serialize
{
serialize_map!();
}
#[cfg(feature = "std")]
impl<K, V, H> Serialize for HashMap<K, V, H>
where K: Serialize + Eq + Hash,
V: Serialize,
H: BuildHasher
{
serialize_map!();
}
///////////////////////////////////////////////////////////////////////////////
impl<'a, T: ?Sized> Serialize for &'a T
where T: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
(**self).serialize(serializer)
}
}
impl<'a, T: ?Sized> Serialize for &'a mut T
where T: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
(**self).serialize(serializer)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T: ?Sized> Serialize for Box<T>
where T: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
(**self).serialize(serializer)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T> Serialize for Rc<T>
where T: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
(**self).serialize(serializer)
}
}
#[cfg(any(feature = "std", feature = "alloc"))]
impl<T> Serialize for Arc<T>
where T: Serialize
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
(**self).serialize(serializer)
}
}
#[cfg(any(feature = "std", feature = "collections"))]
impl<'a, T: ?Sized> Serialize for Cow<'a, T>
where T: Serialize + ToOwned
{
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
(**self).serialize(serializer)
}
}
///////////////////////////////////////////////////////////////////////////////
impl<T, E> Serialize for Result<T, E>
where T: Serialize,
E: Serialize
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
match *self {
Result::Ok(ref value) => serializer.serialize_newtype_variant("Result", 0, "Ok", value),
Result::Err(ref value) => {
serializer.serialize_newtype_variant("Result", 1, "Err", value)
}
}
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl Serialize for Duration {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
use super::SerializeStruct;
let mut state = try!(serializer.serialize_struct("Duration", 2));
try!(state.serialize_field("secs", &self.as_secs()));
try!(state.serialize_field("nanos", &self.subsec_nanos()));
state.end()
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl Serialize for net::IpAddr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
match *self {
net::IpAddr::V4(ref a) => a.serialize(serializer),
net::IpAddr::V6(ref a) => a.serialize(serializer),
}
}
}
#[cfg(feature = "std")]
impl Serialize for net::Ipv4Addr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
/// "101.102.103.104".len()
const MAX_LEN: usize = 15;
serialize_display_bounded_length!(self, MAX_LEN, serializer)
}
}
#[cfg(feature = "std")]
impl Serialize for net::Ipv6Addr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
/// "1000:1002:1003:1004:1005:1006:1007:1008".len()
const MAX_LEN: usize = 39;
serialize_display_bounded_length!(self, MAX_LEN, serializer)
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl Serialize for net::SocketAddr {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
match *self {
net::SocketAddr::V4(ref addr) => addr.serialize(serializer),
net::SocketAddr::V6(ref addr) => addr.serialize(serializer),
}
}
}
#[cfg(feature = "std")]
impl Serialize for net::SocketAddrV4 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
/// "101.102.103.104:65000".len()
const MAX_LEN: usize = 21;
serialize_display_bounded_length!(self, MAX_LEN, serializer)
}
}
#[cfg(feature = "std")]
impl Serialize for net::SocketAddrV6 {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
/// "[1000:1002:1003:1004:1005:1006:1007:1008]:65000".len()
const MAX_LEN: usize = 47;
serialize_display_bounded_length!(self, MAX_LEN, serializer)
}
}
///////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl Serialize for path::Path {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
match self.to_str() {
Some(s) => s.serialize(serializer),
None => Err(Error::custom("path contains invalid UTF-8 characters")),
}
}
}
#[cfg(feature = "std")]
impl Serialize for path::PathBuf {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
self.as_path().serialize(serializer)
}
}
#[cfg(feature = "unstable")]
impl<T> Serialize for NonZero<T>
where T: Serialize + Zeroable
{
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where S: Serializer
{
(**self).serialize(serializer)
}
}

View File

@ -0,0 +1,156 @@
//! This module contains `Impossible` serializer and its implementations.
use core::marker::PhantomData;
use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct,
SerializeTupleVariant, SerializeMap, SerializeStruct, SerializeStructVariant};
/// Helper type for implementing a `Serializer` that does not support
/// serializing one of the compound types.
///
/// This type cannot be instantiated, but implements every one of the traits
/// corresponding to the `Serializer` compound types: `SerializeSeq`,
/// `SerializeTuple`, `SerializeTupleStruct`, `SerializeTupleVariant`,
/// `SerializeMap`, `SerializeStruct`, and `SerializeStructVariant`.
///
/// ```rust,ignore
/// impl Serializer for MySerializer {
/// type Ok = ();
/// type Error = Error;
///
/// type SerializeSeq = Impossible<(), Error>;
/// /* other associated types */
///
/// /// This data format does not support serializing sequences.
/// fn serialize_seq(self,
/// len: Option<usize>)
/// -> Result<Self::SerializeSeq, Error> {
/// // Given Impossible cannot be instantiated, the only
/// // thing we can do here is to return an error.
/// Err(...)
/// }
///
/// /* other Serializer methods */
/// }
/// ```
pub struct Impossible<Ok, E> {
void: Void,
_marker: PhantomData<(Ok, E)>,
}
enum Void {}
impl<Ok, E> SerializeSeq for Impossible<Ok, E>
where E: ser::Error
{
type Ok = Ok;
type Error = E;
fn serialize_element<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<(), E> {
match self.void {}
}
fn end(self) -> Result<Ok, E> {
match self.void {}
}
}
impl<Ok, E> SerializeTuple for Impossible<Ok, E>
where E: ser::Error
{
type Ok = Ok;
type Error = E;
fn serialize_element<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<(), E> {
match self.void {}
}
fn end(self) -> Result<Ok, E> {
match self.void {}
}
}
impl<Ok, E> SerializeTupleStruct for Impossible<Ok, E>
where E: ser::Error
{
type Ok = Ok;
type Error = E;
fn serialize_field<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<(), E> {
match self.void {}
}
fn end(self) -> Result<Ok, E> {
match self.void {}
}
}
impl<Ok, E> SerializeTupleVariant for Impossible<Ok, E>
where E: ser::Error
{
type Ok = Ok;
type Error = E;
fn serialize_field<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<(), E> {
match self.void {}
}
fn end(self) -> Result<Ok, E> {
match self.void {}
}
}
impl<Ok, E> SerializeMap for Impossible<Ok, E>
where E: ser::Error
{
type Ok = Ok;
type Error = E;
fn serialize_key<T: ?Sized + Serialize>(&mut self, _key: &T) -> Result<(), E> {
match self.void {}
}
fn serialize_value<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<(), E> {
match self.void {}
}
fn end(self) -> Result<Ok, E> {
match self.void {}
}
}
impl<Ok, E> SerializeStruct for Impossible<Ok, E>
where E: ser::Error
{
type Ok = Ok;
type Error = E;
fn serialize_field<T: ?Sized + Serialize>(&mut self,
_key: &'static str,
_value: &T)
-> Result<(), E> {
match self.void {}
}
fn end(self) -> Result<Ok, E> {
match self.void {}
}
}
impl<Ok, E> SerializeStructVariant for Impossible<Ok, E>
where E: ser::Error
{
type Ok = Ok;
type Error = E;
fn serialize_field<T: ?Sized + Serialize>(&mut self,
_key: &'static str,
_value: &T)
-> Result<(), E> {
match self.void {}
}
fn end(self) -> Result<Ok, E> {
match self.void {}
}
}

View File

@ -0,0 +1,848 @@
//! Generic data structure serialization framework.
//!
//! The two most important traits in this module are `Serialize` and
//! `Serializer`.
//!
//! - **A type that implements `Serialize` is a data structure** that can be
//! serialized to any data format supported by Serde, and conversely
//! - **A type that implements `Serializer` is a data format** that can
//! serialize any data structure supported by Serde.
//!
//! # The Serialize trait
//!
//! Serde provides `Serialize` implementations for many Rust primitive and
//! standard library types. The complete list is below. All of these can be
//! serialized using Serde out of the box.
//!
//! Additionally, Serde provides a procedural macro called `serde_derive` to
//! automatically generate `Serialize` implementations for structs and enums in
//! your program. See the [codegen section of the manual][codegen] for how to
//! use this.
//!
//! In rare cases it may be necessary to implement `Serialize` manually for some
//! type in your program. See the [Implementing `Serialize`][impl-serialize]
//! section of the manual for more about this.
//!
//! Third-party crates may provide `Serialize` implementations for types that
//! they expose. For example the `linked-hash-map` crate provides a
//! `LinkedHashMap<K, V>` type that is serializable by Serde because the crate
//! provides an implementation of `Serialize` for it.
//!
//! # The Serializer trait
//!
//! `Serializer` implementations are provided by third-party crates, for example
//! [`serde_json`][serde_json], [`serde_yaml`][serde_yaml] and
//! [`bincode`][bincode].
//!
//! A partial list of well-maintained formats is given on the [Serde
//! website][data-formats].
//!
//! # Implementations of Serialize provided by Serde
//!
//! - **Primitive types**:
//! - bool
//! - isize, i8, i16, i32, i64
//! - usize, u8, u16, u32, u64
//! - f32, f64
//! - char
//! - str
//! - &T and &mut T
//! - **Compound types**:
//! - [T]
//! - [T; 0] through [T; 32]
//! - tuples up to size 16
//! - **Common standard library types**:
//! - String
//! - Option\<T\>
//! - Result\<T, E\>
//! - PhantomData\<T\>
//! - **Wrapper types**:
//! - Box\<T\>
//! - Rc\<T\>
//! - Arc\<T\>
//! - Cow\<'a, T\>
//! - **Collection types**:
//! - BTreeMap\<K, V\>
//! - BTreeSet\<T\>
//! - BinaryHeap\<T\>
//! - HashMap\<K, V, H\>
//! - HashSet\<T, H\>
//! - LinkedList\<T\>
//! - VecDeque\<T\>
//! - Vec\<T\>
//! - EnumSet\<T\> (unstable)
//! - Range\<T\> (unstable)
//! - RangeInclusive\<T\> (unstable)
//! - **Miscellaneous standard library types**:
//! - Duration
//! - Path
//! - PathBuf
//! - NonZero\<T\> (unstable)
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
//! - Ipv6Addr
//! - SocketAddr
//! - SocketAddrV4
//! - SocketAddrV6
//!
//! [codegen]: https://serde.rs/codegen.html
//! [impl-serialize]: https://serde.rs/impl-serialize.html
//! [serde_json]: https://github.com/serde-rs/json
//! [serde_yaml]: https://github.com/dtolnay/serde-yaml
//! [bincode]: https://github.com/TyOverby/bincode
//! [data-formats]: https://serde.rs/#data-formats
#[cfg(feature = "std")]
use std::error;
#[cfg(not(feature = "std"))]
use error;
use core::fmt::Display;
use core::iter::IntoIterator;
mod impls;
mod impossible;
// Helpers used by generated code. Not public API.
#[doc(hidden)]
pub mod private;
#[cfg(any(feature = "std", feature = "collections"))]
mod content;
pub use self::impossible::Impossible;
///////////////////////////////////////////////////////////////////////////////
/// Trait used by `Serialize` implementations to generically construct errors
/// belonging to the `Serializer` against which they are currently running.
pub trait Error: Sized + error::Error {
/// Raised when a `Serialize` implementation encounters a general error
/// while serializing a type.
///
/// The message should not be capitalized and should not end with a period.
///
/// For example, a filesystem `Path` may refuse to serialize itself if it
/// contains invalid UTF-8 data.
///
/// ```rust
/// # use serde::ser::{Serialize, Serializer, Error};
/// # struct Path;
/// # impl Path { fn to_str(&self) -> Option<&str> { unimplemented!() } }
/// impl Serialize for Path {
/// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
/// where S: Serializer
/// {
/// match self.to_str() {
/// Some(s) => s.serialize(serializer),
/// None => Err(Error::custom("path contains invalid UTF-8 characters")),
/// }
/// }
/// }
/// ```
fn custom<T: Display>(msg: T) -> Self;
}
///////////////////////////////////////////////////////////////////////////////
/// A **data structure** that can be serialized into any data format supported
/// by Serde.
///
/// Serde provides `Serialize` implementations for many Rust primitive and
/// standard library types. The complete list is [here][ser]. All of these can
/// be serialized using Serde out of the box.
///
/// Additionally, Serde provides a procedural macro called `serde_derive` to
/// automatically generate `Serialize` implementations for structs and enums in
/// your program. See the [codegen section of the manual][codegen] for how to
/// use this.
///
/// In rare cases it may be necessary to implement `Serialize` manually for some
/// type in your program. See the [Implementing `Serialize`][impl-serialize]
/// section of the manual for more about this.
///
/// Third-party crates may provide `Serialize` implementations for types that
/// they expose. For example the `linked-hash-map` crate provides a
/// `LinkedHashMap<K, V>` type that is serializable by Serde because the crate
/// provides an implementation of `Serialize` for it.
///
/// [ser]: https://docs.serde.rs/serde/ser/index.html
/// [codegen]: https://serde.rs/codegen.html
/// [impl-serialize]: https://serde.rs/impl-serialize.html
pub trait Serialize {
/// Serialize this value into the given Serde serializer.
///
/// See the [Implementing `Serialize`][impl-serialize] section of the manual
/// for more information about how to implement this method.
///
/// [impl-serialize]: https://serde.rs/impl-serialize.html
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer;
}
///////////////////////////////////////////////////////////////////////////////
/// A **data format** that can serialize any data structure supported by Serde.
///
/// The role of this trait is to define the serialization half of the Serde data
/// model, which is a way to categorize every Rust data structure into one of 28
/// possible types. Each method of the `Serializer` trait corresponds to one of
/// the types of the data model.
///
/// Implementations of `Serialize` map themselves into this data model by
/// invoking exactly one of the `Serializer` methods.
///
/// The types that make up the Serde data model are:
///
/// - 12 primitive types:
/// - bool
/// - i8, i16, i32, i64
/// - u8, u16, u32, u64
/// - f32, f64
/// - char
/// - string
/// - byte array - [u8]
/// - option
/// - either none or some value
/// - unit
/// - unit is the type of () in Rust
/// - unit_struct
/// - for example `struct Unit` or `PhantomData<T>`
/// - unit_variant
/// - the `E::A` and `E::B` in `enum E { A, B }`
/// - newtype_struct
/// - for example `struct Millimeters(u8)`
/// - newtype_variant
/// - the `E::N` in `enum E { N(u8) }`
/// - seq
/// - a dynamically sized sequence of values, for example `Vec<T>` or
/// `HashSet<T>`
/// - seq_fixed_size
/// - a statically sized sequence of values for which the size will be known
/// at deserialization time without looking at the serialized data, for
/// example `[u64; 10]`
/// - tuple
/// - for example `(u8,)` or `(String, u64, Vec<T>)`
/// - tuple_struct
/// - for example `struct Rgb(u8, u8, u8)`
/// - tuple_variant
/// - the `E::T` in `enum E { T(u8, u8) }`
/// - map
/// - for example `BTreeMap<K, V>`
/// - struct
/// - a key-value pairing in which the keys will be known at deserialization
/// time without looking at the serialized data, for example `struct S { r:
/// u8, g: u8, b: u8 }`
/// - struct_variant
/// - the `E::S` in `enum E { S { r: u8, g: u8, b: u8 } }`
///
/// Many Serde serializers produce text or binary data as output, for example
/// JSON or Bincode. This is not a requirement of the `Serializer` trait, and
/// there are serializers that do not produce text or binary output. One example
/// is the `serde_json::value::Serializer` (distinct from the main `serde_json`
/// serializer) that produces a `serde_json::Value` data structure in memory as
/// output.
pub trait Serializer: Sized {
/// The output type produced by this `Serializer` during successful
/// serialization. Most serializers that produce text or binary output
/// should set `Ok = ()` and serialize into an `io::Write` or buffer
/// contained within the `Serializer` instance. Serializers that build
/// in-memory data structures may be simplified by using `Ok` to propagate
/// the data structure around.
type Ok;
/// The error type when some error occurs during serialization.
type Error: Error;
/// Type returned from `serialize_seq` and `serialize_seq_fixed_size` for
/// serializing the content of the sequence.
type SerializeSeq: SerializeSeq<Ok = Self::Ok, Error = Self::Error>;
/// Type returned from `serialize_tuple` for serializing the content of the
/// tuple.
type SerializeTuple: SerializeTuple<Ok = Self::Ok, Error = Self::Error>;
/// Type returned from `serialize_tuple_struct` for serializing the content
/// of the tuple struct.
type SerializeTupleStruct: SerializeTupleStruct<Ok = Self::Ok, Error = Self::Error>;
/// Type returned from `serialize_tuple_variant` for serializing the content
/// of the tuple variant.
type SerializeTupleVariant: SerializeTupleVariant<Ok = Self::Ok, Error = Self::Error>;
/// Type returned from `serialize_map` for serializing the content of the
/// map.
type SerializeMap: SerializeMap<Ok = Self::Ok, Error = Self::Error>;
/// Type returned from `serialize_struct` for serializing the content of the
/// struct.
type SerializeStruct: SerializeStruct<Ok = Self::Ok, Error = Self::Error>;
/// Type returned from `serialize_struct_variant` for serializing the
/// content of the struct variant.
type SerializeStructVariant: SerializeStructVariant<Ok = Self::Ok, Error = Self::Error>;
/// Serialize a `bool` value.
fn serialize_bool(self, v: bool) -> Result<Self::Ok, Self::Error>;
/// Serialize an `i8` value.
///
/// If the format does not differentiate between `i8` and `i64`, a
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
fn serialize_i8(self, v: i8) -> Result<Self::Ok, Self::Error>;
/// Serialize an `i16` value.
///
/// If the format does not differentiate between `i16` and `i64`, a
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
fn serialize_i16(self, v: i16) -> Result<Self::Ok, Self::Error>;
/// Serialize an `i32` value.
///
/// If the format does not differentiate between `i32` and `i64`, a
/// reasonable implementation would be to cast the value to `i64` and
/// forward to `serialize_i64`.
fn serialize_i32(self, v: i32) -> Result<Self::Ok, Self::Error>;
/// Serialize an `i64` value.
fn serialize_i64(self, v: i64) -> Result<Self::Ok, Self::Error>;
/// Serialize a `u8` value.
///
/// If the format does not differentiate between `u8` and `u64`, a
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
fn serialize_u8(self, v: u8) -> Result<Self::Ok, Self::Error>;
/// Serialize a `u16` value.
///
/// If the format does not differentiate between `u16` and `u64`, a
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
fn serialize_u16(self, v: u16) -> Result<Self::Ok, Self::Error>;
/// Serialize a `u32` value.
///
/// If the format does not differentiate between `u32` and `u64`, a
/// reasonable implementation would be to cast the value to `u64` and
/// forward to `serialize_u64`.
fn serialize_u32(self, v: u32) -> Result<Self::Ok, Self::Error>;
/// Serialize a `u64` value.
fn serialize_u64(self, v: u64) -> Result<Self::Ok, Self::Error>;
/// Serialize an `f32` value.
///
/// If the format does not differentiate between `f32` and `f64`, a
/// reasonable implementation would be to cast the value to `f64` and
/// forward to `serialize_f64`.
fn serialize_f32(self, v: f32) -> Result<Self::Ok, Self::Error>;
/// Serialize an `f64` value.
fn serialize_f64(self, v: f64) -> Result<Self::Ok, Self::Error>;
/// Serialize a character.
///
/// If the format does not support characters, it is reasonable to serialize
/// it as a single element `str` or a `u32`.
fn serialize_char(self, v: char) -> Result<Self::Ok, Self::Error>;
/// Serialize a `&str`.
fn serialize_str(self, value: &str) -> Result<Self::Ok, Self::Error>;
/// Serialize a chunk of raw byte data.
///
/// Enables serializers to serialize byte slices more compactly or more
/// efficiently than other types of slices. If no efficient implementation
/// is available, a reasonable implementation would be to forward to
/// `serialize_seq`. If forwarded, the implementation looks usually just
/// like this:
///
/// ```rust,ignore
/// let mut seq = self.serialize_seq(Some(value.len()))?;
/// for b in value {
/// seq.serialize_element(b)?;
/// }
/// seq.end()
/// ```
fn serialize_bytes(self, value: &[u8]) -> Result<Self::Ok, Self::Error>;
/// Serialize a `None` value.
fn serialize_none(self) -> Result<Self::Ok, Self::Error>;
/// Serialize a `Some(T)` value.
fn serialize_some<T: ?Sized + Serialize>(self, value: &T) -> Result<Self::Ok, Self::Error>;
/// Serialize a `()` value.
fn serialize_unit(self) -> Result<Self::Ok, Self::Error>;
/// Serialize a unit struct like `struct Unit` or `PhantomData<T>`.
///
/// A reasonable implementation would be to forward to `serialize_unit`.
fn serialize_unit_struct(self, name: &'static str) -> Result<Self::Ok, Self::Error>;
/// Serialize a unit variant like `E::A` in `enum E { A, B }`.
///
/// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, and the `variant` is the name of the
/// variant.
///
/// A reasonable implementation would be to forward to `serialize_unit`.
///
/// ```rust,ignore
/// match *self {
/// E::A => serializer.serialize_unit_variant("E", 0, "A"),
/// E::B => serializer.serialize_unit_variant("E", 1, "B"),
/// }
/// ```
fn serialize_unit_variant(self,
name: &'static str,
variant_index: usize,
variant: &'static str)
-> Result<Self::Ok, Self::Error>;
/// Serialize a newtype struct like `struct Millimeters(u8)`.
///
/// Serializers are encouraged to treat newtype structs as insignificant
/// wrappers around the data they contain. A reasonable implementation would
/// be to forward to `value.serialize(self)`.
///
/// ```rust,ignore
/// serializer.serialize_newtype_struct("Millimeters", &self.0)
/// ```
fn serialize_newtype_struct<T: ?Sized + Serialize>(self,
name: &'static str,
value: &T)
-> Result<Self::Ok, Self::Error>;
/// Serialize a newtype variant like `E::N` in `enum E { N(u8) }`.
///
/// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, and the `variant` is the name of the
/// variant. The `value` is the data contained within this newtype variant.
///
/// ```rust,ignore
/// match *self {
/// E::N(ref n) => serializer.serialize_newtype_variant("E", 0, "N", n),
/// }
/// ```
fn serialize_newtype_variant<T: ?Sized + Serialize>(self,
name: &'static str,
variant_index: usize,
variant: &'static str,
value: &T)
-> Result<Self::Ok, Self::Error>;
/// Begin to serialize a dynamically sized sequence. This call must be
/// followed by zero or more calls to `serialize_element`, then a call to
/// `end`.
///
/// The argument is the number of elements in the sequence, which may or may
/// not be computable before the sequence is iterated. Some serializers only
/// support sequences whose length is known up front.
///
/// ```rust,ignore
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// ```
fn serialize_seq(self, len: Option<usize>) -> Result<Self::SerializeSeq, Self::Error>;
/// Begin to serialize a statically sized sequence whose length will be
/// known at deserialization time without looking at the serialized data.
/// This call must be followed by zero or more calls to `serialize_element`,
/// then a call to `end`.
///
/// ```rust,ignore
/// let mut seq = serializer.serialize_seq_fixed_size(self.len())?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// ```
fn serialize_seq_fixed_size(self, size: usize) -> Result<Self::SerializeSeq, Self::Error>;
/// Begin to serialize a tuple. This call must be followed by zero or more
/// calls to `serialize_field`, then a call to `end`.
///
/// ```rust,ignore
/// let mut tup = serializer.serialize_tuple(3)?;
/// tup.serialize_field(&self.0)?;
/// tup.serialize_field(&self.1)?;
/// tup.serialize_field(&self.2)?;
/// tup.end()
/// ```
fn serialize_tuple(self, len: usize) -> Result<Self::SerializeTuple, Self::Error>;
/// Begin to serialize a tuple struct like `struct Rgb(u8, u8, u8)`. This
/// call must be followed by zero or more calls to `serialize_field`, then a
/// call to `end`.
///
/// The `name` is the name of the tuple struct and the `len` is the number
/// of data fields that will be serialized.
///
/// ```rust,ignore
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
/// ts.serialize_field(&self.0)?;
/// ts.serialize_field(&self.1)?;
/// ts.serialize_field(&self.2)?;
/// ts.end()
/// ```
fn serialize_tuple_struct(self,
name: &'static str,
len: usize)
-> Result<Self::SerializeTupleStruct, Self::Error>;
/// Begin to serialize a tuple variant like `E::T` in `enum E { T(u8, u8)
/// }`. This call must be followed by zero or more calls to
/// `serialize_field`, then a call to `end`.
///
/// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, the `variant` is the name of the variant,
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust,ignore
/// match *self {
/// E::T(ref a, ref b) => {
/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?;
/// tv.serialize_field(a)?;
/// tv.serialize_field(b)?;
/// tv.end()
/// }
/// }
/// ```
fn serialize_tuple_variant(self,
name: &'static str,
variant_index: usize,
variant: &'static str,
len: usize)
-> Result<Self::SerializeTupleVariant, Self::Error>;
/// Begin to serialize a map. This call must be followed by zero or more
/// calls to `serialize_key` and `serialize_value`, then a call to `end`.
///
/// The argument is the number of elements in the map, which may or may not
/// be computable before the map is iterated. Some serializers only support
/// maps whose length is known up front.
///
/// ```rust,ignore
/// let mut map = serializer.serialize_map(Some(self.len()))?;
/// for (k, v) in self {
/// map.serialize_entry(k, v)?;
/// }
/// map.end()
/// ```
fn serialize_map(self, len: Option<usize>) -> Result<Self::SerializeMap, Self::Error>;
/// Begin to serialize a struct like `struct Rgb { r: u8, g: u8, b: u8 }`.
/// This call must be followed by zero or more calls to `serialize_field`,
/// then a call to `end`.
///
/// The `name` is the name of the struct and the `len` is the number of
/// data fields that will be serialized.
///
/// ```rust,ignore
/// let mut struc = serializer.serialize_struct("Rgb", 3)?;
/// struc.serialize_field("r", &self.r)?;
/// struc.serialize_field("g", &self.g)?;
/// struc.serialize_field("b", &self.b)?;
/// struc.end()
/// ```
fn serialize_struct(self,
name: &'static str,
len: usize)
-> Result<Self::SerializeStruct, Self::Error>;
/// Begin to serialize a struct variant like `E::S` in `enum E { S { r: u8,
/// g: u8, b: u8 } }`. This call must be followed by zero or more calls to
/// `serialize_field`, then a call to `end`.
///
/// The `name` is the name of the enum, the `variant_index` is the index of
/// this variant within the enum, the `variant` is the name of the variant,
/// and the `len` is the number of data fields that will be serialized.
///
/// ```rust,ignore
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
/// sv.serialize_field("b", b)?;
/// sv.end()
/// }
/// }
/// ```
fn serialize_struct_variant(self,
name: &'static str,
variant_index: usize,
variant: &'static str,
len: usize)
-> Result<Self::SerializeStructVariant, Self::Error>;
/// Collect an iterator as a sequence.
///
/// The default implementation serializes each item yielded by the iterator
/// using `Self::SerializeSeq`. Implementors should not need to override
/// this method.
fn collect_seq<I>(self, iter: I) -> Result<Self::Ok, Self::Error>
where I: IntoIterator,
<I as IntoIterator>::Item: Serialize
{
let iter = iter.into_iter();
let mut serializer = try!(self.serialize_seq(iter.len_hint()));
for item in iter {
try!(serializer.serialize_element(&item));
}
serializer.end()
}
/// Collect an iterator as a map.
///
/// The default implementation serializes each pair yielded by the iterator
/// using `Self::SerializeMap`. Implementors should not need to override
/// this method.
fn collect_map<K, V, I>(self, iter: I) -> Result<Self::Ok, Self::Error>
where K: Serialize,
V: Serialize,
I: IntoIterator<Item = (K, V)>
{
let iter = iter.into_iter();
let mut serializer = try!(self.serialize_map(iter.len_hint()));
for (key, value) in iter {
try!(serializer.serialize_entry(&key, &value));
}
serializer.end()
}
}
/// Returned from `Serializer::serialize_seq` and
/// `Serializer::serialize_seq_fixed_size`.
///
/// ```rust,ignore
/// let mut seq = serializer.serialize_seq(Some(self.len()))?;
/// for element in self {
/// seq.serialize_element(element)?;
/// }
/// seq.end()
/// ```
pub trait SerializeSeq {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serialize a sequence element.
fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finish serializing a sequence.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_tuple`.
///
/// ```rust,ignore
/// let mut tup = serializer.serialize_tuple(3)?;
/// tup.serialize_field(&self.0)?;
/// tup.serialize_field(&self.1)?;
/// tup.serialize_field(&self.2)?;
/// tup.end()
/// ```
pub trait SerializeTuple {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serialize a tuple element.
fn serialize_element<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finish serializing a tuple.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_tuple_struct`.
///
/// ```rust,ignore
/// let mut ts = serializer.serialize_tuple_struct("Rgb", 3)?;
/// ts.serialize_field(&self.0)?;
/// ts.serialize_field(&self.1)?;
/// ts.serialize_field(&self.2)?;
/// ts.end()
/// ```
pub trait SerializeTupleStruct {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serialize a tuple struct field.
fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finish serializing a tuple struct.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_tuple_variant`.
///
/// ```rust,ignore
/// match *self {
/// E::T(ref a, ref b) => {
/// let mut tv = serializer.serialize_tuple_variant("E", 0, "T", 2)?;
/// tv.serialize_field(a)?;
/// tv.serialize_field(b)?;
/// tv.end()
/// }
/// }
/// ```
pub trait SerializeTupleVariant {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serialize a tuple variant field.
fn serialize_field<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Finish serializing a tuple variant.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_map`.
///
/// ```rust,ignore
/// let mut map = serializer.serialize_map(Some(self.len()))?;
/// for (k, v) in self {
/// map.serialize_entry(k, v)?;
/// }
/// map.end()
/// ```
pub trait SerializeMap {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serialize a map key.
fn serialize_key<T: ?Sized + Serialize>(&mut self, key: &T) -> Result<(), Self::Error>;
/// Serialize a map value.
fn serialize_value<T: ?Sized + Serialize>(&mut self, value: &T) -> Result<(), Self::Error>;
/// Serialize a map entry consisting of a key and a value.
///
/// Some `Serialize` types are not able to hold a key and value in memory at
/// the same time so `SerializeMap` implementations are required to support
/// `serialize_key` and `serialize_value` individually. The
/// `serialize_entry` method allows serializers to optimize for the case
/// where key and value are both available. `Serialize` implementations are
/// encouraged to use `serialize_entry` if possible.
///
/// The default implementation delegates to `serialize_key` and
/// `serialize_value`. This is appropriate for serializers that do not care
/// about performance or are not able to optimize `serialize_entry` any
/// better than this.
fn serialize_entry<K: ?Sized + Serialize, V: ?Sized + Serialize>(&mut self,
key: &K,
value: &V)
-> Result<(), Self::Error> {
try!(self.serialize_key(key));
self.serialize_value(value)
}
/// Finish serializing a map.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_struct`.
///
/// ```rust,ignore
/// let mut struc = serializer.serialize_struct("Rgb", 3)?;
/// struc.serialize_field("r", &self.r)?;
/// struc.serialize_field("g", &self.g)?;
/// struc.serialize_field("b", &self.b)?;
/// struc.end()
/// ```
pub trait SerializeStruct {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serialize a struct field.
fn serialize_field<T: ?Sized + Serialize>(&mut self,
key: &'static str,
value: &T)
-> Result<(), Self::Error>;
/// Finish serializing a struct.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_struct_variant`.
///
/// ```rust,ignore
/// match *self {
/// E::S { ref r, ref g, ref b } => {
/// let mut sv = serializer.serialize_struct_variant("E", 0, "S", 3)?;
/// sv.serialize_field("r", r)?;
/// sv.serialize_field("g", g)?;
/// sv.serialize_field("b", b)?;
/// sv.end()
/// }
/// }
/// ```
pub trait SerializeStructVariant {
/// Must match the `Ok` type of our `Serializer`.
type Ok;
/// Must match the `Error` type of our `Serializer`.
type Error: Error;
/// Serialize a struct variant field.
fn serialize_field<T: ?Sized + Serialize>(&mut self,
key: &'static str,
value: &T)
-> Result<(), Self::Error>;
/// Finish serializing a struct variant.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
trait LenHint: Iterator {
fn len_hint(&self) -> Option<usize>;
}
impl<I: Iterator> LenHint for I {
#[cfg(not(feature = "unstable"))]
fn len_hint(&self) -> Option<usize> {
iterator_len_hint(self)
}
#[cfg(feature = "unstable")]
default fn len_hint(&self) -> Option<usize> {
iterator_len_hint(self)
}
}
#[cfg(feature = "unstable")]
impl<I: ExactSizeIterator> LenHint for I {
fn len_hint(&self) -> Option<usize> {
Some(self.len())
}
}
fn iterator_len_hint<I: Iterator>(iter: &I) -> Option<usize> {
match iter.size_hint() {
(lo, Some(hi)) if lo == hi => Some(lo),
_ => None,
}
}

View File

@ -1 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"e2817af66db5f058a55b5f126ca9a663925bfeb36a592a4121e7e9a44d3a3453","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"ebe318a04cf4e547e0f3ab97f1345ecb553358ee13ea81f99e3323e37d70ccdf","src/bytes.rs":"2b6a9c2c3d6eabe8633adee6655a3b94f0d1e931e740e72699b6965bee21e226","src/de/content.rs":"469d3298d4109d514a8cd630273a288a361544979e2ab23aaa325b2201f9361f","src/de/from_primitive.rs":"b1bd165e343a4380965551709119ef9ed895e4b025045a810dabd671511ba3ab","src/de/impls.rs":"762c3f32627d12555ccd08fcdf3dfb621403c35cde8a5af7866e2ad74c95a4c8","src/de/mod.rs":"365ee7038c53e88cddd451afd11d459f65185fd04523bd000a6b424ac4f71db7","src/de/private.rs":"2578dbc89c2f2a852caed3fdc40f710d4828d085c4e954dd96789d678583424e","src/de/value.rs":"67a34c03fda6521c082548984b0116494e5fbff7e60e30e06f0dda62d9d3e083","src/error.rs":"3af5286c1daad9bfd504693f8a8587f7044c9b9520e23e072549c43a72e4821d","src/export.rs":"0b8e6b642010ad6a71f13f5facfd91e9da1d7c99d479dba020dec10e88fb6b0f","src/iter.rs":"af3c43712c240b3a06870e0b0b6e837b142d5a65c62742fa358fe36a9d9319a7","src/lib.rs":"75df159c150e62c99887c0a4f23ed1271c9eb910ebc79a2d4bd279b0e11ce7e3","src/macros.rs":"af1f75bb34460b814e44f7bc67bdd1dc1bba97f1f2a31744c22e1bfcdc29499a","src/ser/content.rs":"f1cd3724e5ddeacb75b3585b2fd2be7c42fc764444b1f764e31ed9fe49f62025","src/ser/impls.rs":"51d4036b8309381af8267375778bf80c3a9114577c03a04da9a679462077efac","src/ser/impossible.rs":"f1332a1250f9c1d85d679653ade502cf99bdff0344b9f864e6cf1a1789d7c597","src/ser/mod.rs":"d1d821488453651a986bb4e4608f72868c09a71a8dbf693584758b25603ae8bf","src/ser/private.rs":"3999dc19d61d43a64d5d1bdda61f80ea16405a926b074b5441b39d87318be73b","src/utils.rs":"ed271c0825c01d7b24968bf47ce9e2475ca219faf733eb33831d6e19bf07aaf1"},"package":"05a67b8a53f885f4b6e3ed183806035819f9862474e747fe4488a6d63bcbfcb7"}
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"a37a2a8ebf5a7732f77446e1f9fdc6441bf01cc39311c55fa716451fa32ba64d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"eedee04bddb61e99bc816656bb3b8ae2fa50ff00045ecdb5212682f3592d9ab2","src/de/from_primitive.rs":"28ec3ab1c430cf27d632b642ccfccb6d055eeb9fb576e7e446ba24c66f507fb4","src/de/ignored_any.rs":"1b5ee592f5ae58d69e321144d4397f149c047e327529d0b880e1a5285e781a35","src/de/impls.rs":"8088c7cb2427c9c32bb7104b6d473c9242e98b630b95949543b322348dba4969","src/de/mod.rs":"761d9bd018fe75b8dbd9ec78e2882e533e2488a7cb7980805c1939143eb7a5af","src/de/utf8.rs":"956b124b7ce98353cb781b56e43a6fed2e67f1389d35b7a468d5be75b1485853","src/de/value.rs":"26eec47336c3d31ecbc2b7c131d71954a68ae62b8f13574d85d118eb69177ed1","src/export.rs":"a3e62187f57748cc12109b109cc850343adfab83b74b6b60123fd531c68d5d8d","src/lib.rs":"e2ec21d527103edd1b54d8baa96a44f1c9f7716438214461cd87d606eda64fc0","src/macros.rs":"e1d542b1dac2c1d1f9d5ada7cc5b6639767fc67851421cc3adfb942a7cf750b6","src/private/de.rs":"598f6736d3c23b2e1481932df3636701f36cc5943428647742335081c5c7a650","src/private/macros.rs":"6861a4f332ea24d0ed5db1c28fe3105d2716523902f045c0bbbd439ebf9e44de","src/private/mod.rs":"bcd7c54838e139475c23a323678e20eccbe88c0be93f7977f7675cead4d3b6ed","src/private/ser.rs":"12e686fa3bf7f10ca21642c6308c6ef0b2158ee66ebda412b5d5c388019e7cd7","src/ser/impls.rs":"534f0f94757b0e87304bdbe6f2440b51cb4fc2933d23a62ac61b8c382d80b4c0","src/ser/impossible.rs":"35bd09bb517b28eda0048b0622eb5a0313d5aebf37c03b5a44dbca200d0a9ac8","src/ser/mod.rs":"fc6d1d8dc5e1e1459fda4349634a955c3e59a9bc6d98978be5f8a37bc9c1b02c"},"package":"c0c3d79316a6051231925504f6ef893d45088e8823c77a8331a3dcf427ee9087"}

View File

@ -1,7 +1,7 @@
[package]
name = "serde"
version = "0.9.9"
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>"]
version = "1.0.7" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "A generic serialization/deserialization framework"
homepage = "https://serde.rs"
@ -9,26 +9,67 @@ repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde/"
keywords = ["serde", "serialization", "no_std"]
categories = ["encoding"]
readme = "../README.md"
readme = "README.md"
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[badges]
travis-ci = { repository = "serde-rs/serde" }
appveyor = { repository = "serde-rs/serde" }
[dependencies]
serde_derive = { version = "1.0", optional = true, path = "../serde_derive" }
[dev-dependencies]
serde_derive = { version = "1.0", path = "../serde_derive" }
### FEATURES #################################################################
[features]
default = ["std"]
# Re-export the derive(Serialize, Deserialize) macros. This is specifically
# intended for library crates that provide optional Serde impls behind a Cargo
# cfg of their own. All other crates should depend on serde_derive directly.
#
# Please refer to the long comment above the line `pub use serde_derive::*` in
# src/lib.rs before enabling this feature. If you think you need this feature
# and your use case does not precisely match the one described in the comment,
# please open an issue to let us know about your use case.
derive = ["serde_derive"]
# Provide impls for common standard library types like Vec<T> and HashMap<K, V>.
# Requires a dependency on the Rust standard library.
std = []
# Provide impls for types that require unstable functionality. For tracking and
# discussion of unstable functionality please refer to this issue:
#
# https://github.com/serde-rs/serde/issues/812
unstable = []
# Provide impls for types that require memory allocation like Box<T> and Rc<T>.
# This is a subset of std but may be enabled without depending on all of std.
#
# Requires a dependency on the unstable core allocation library:
#
# https://doc.rust-lang.org/alloc/
alloc = ["unstable"]
# Provide impls for collection types like String and Cow<T>. This is a subset of
# std but may be enabled without depending on all of std.
#
# Requires a dependency on the unstable collections library:
#
# https://doc.rust-lang.org/collections/
collections = ["alloc"]
unstable-testing = ["unstable", "std"]
# to get serde_derive picked up by play.integer32.com
# Opt into impls for Rc<T> and Arc<T>. Serializing and deserializing these types
# does not preserve identity and may result in multiple copies of the same data.
# Be sure that this is what you want before enabling this feature.
rc = []
# Get serde_derive picked up by the Integer 32 playground. Not public API.
#
# http://play.integer32.com/
playground = ["serde_derive"]
[dependencies]
serde_derive = { version = "0.9", optional = true }
[dev-dependencies]
serde_derive = "0.9"

View File

@ -1,4 +1,9 @@
# Serde &emsp; [![Build Status](https://api.travis-ci.org/serde-rs/serde.svg?branch=master)](https://travis-ci.org/serde-rs/serde) [![Latest Version](https://img.shields.io/crates/v/serde.svg)](https://crates.io/crates/serde)
# Serde &emsp; [![Build Status]][travis] [![Latest Version]][crates.io]
[Build Status]: https://api.travis-ci.org/serde-rs/serde.svg?branch=master
[travis]: https://travis-ci.org/serde-rs/serde
[Latest Version]: https://img.shields.io/crates/v/serde.svg
[crates.io]: https://crates.io/crates/serde
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
@ -15,10 +20,15 @@ You may be looking for:
## Serde in action
<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">
<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png">
</a>
```rust
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]

View File

@ -1,6 +1,4 @@
// Copyright 2013-2014 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
@ -8,402 +6,111 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Extracted from https://github.com/rust-num/num.
use lib::*;
// Rust 1.5 is unhappy that this private module is undocumented.
#![allow(missing_docs)]
use core::{usize, u8, u16, u32, u64};
use core::{isize, i8, i16, i32, i64};
use core::{f32, f64};
use core::mem::size_of;
/// Numbers which have upper and lower bounds
pub trait Bounded {
// FIXME (#5527): These should be associated constants
/// returns the smallest finite number this type can represent
fn min_value() -> Self;
/// returns the largest finite number this type can represent
fn max_value() -> Self;
}
macro_rules! bounded_impl {
($t:ty, $min:expr, $max:expr) => {
impl Bounded for $t {
#[inline]
fn min_value() -> $t { $min }
#[inline]
fn max_value() -> $t { $max }
}
}
}
bounded_impl!(usize, usize::MIN, usize::MAX);
bounded_impl!(u8, u8::MIN, u8::MAX);
bounded_impl!(u16, u16::MIN, u16::MAX);
bounded_impl!(u32, u32::MIN, u32::MAX);
bounded_impl!(u64, u64::MIN, u64::MAX);
bounded_impl!(isize, isize::MIN, isize::MAX);
bounded_impl!(i8, i8::MIN, i8::MAX);
bounded_impl!(i16, i16::MIN, i16::MAX);
bounded_impl!(i32, i32::MIN, i32::MAX);
bounded_impl!(i64, i64::MIN, i64::MAX);
bounded_impl!(f32, f32::MIN, f32::MAX);
bounded_impl!(f64, f64::MIN, f64::MAX);
/// A generic trait for converting a value to a number.
pub trait ToPrimitive {
/// Converts the value of `self` to an `isize`.
#[inline]
fn to_isize(&self) -> Option<isize> {
self.to_i64().and_then(|x| x.to_isize())
}
/// Converts the value of `self` to an `i8`.
#[inline]
fn to_i8(&self) -> Option<i8> {
self.to_i64().and_then(|x| x.to_i8())
}
/// Converts the value of `self` to an `i16`.
#[inline]
fn to_i16(&self) -> Option<i16> {
self.to_i64().and_then(|x| x.to_i16())
}
/// Converts the value of `self` to an `i32`.
#[inline]
fn to_i32(&self) -> Option<i32> {
self.to_i64().and_then(|x| x.to_i32())
}
/// Converts the value of `self` to an `i64`.
fn to_i64(&self) -> Option<i64>;
/// Converts the value of `self` to a `usize`.
#[inline]
fn to_usize(&self) -> Option<usize> {
self.to_u64().and_then(|x| x.to_usize())
}
/// Converts the value of `self` to an `u8`.
#[inline]
fn to_u8(&self) -> Option<u8> {
self.to_u64().and_then(|x| x.to_u8())
}
/// Converts the value of `self` to an `u16`.
#[inline]
fn to_u16(&self) -> Option<u16> {
self.to_u64().and_then(|x| x.to_u16())
}
/// Converts the value of `self` to an `u32`.
#[inline]
fn to_u32(&self) -> Option<u32> {
self.to_u64().and_then(|x| x.to_u32())
}
/// Converts the value of `self` to an `u64`.
#[inline]
fn to_u64(&self) -> Option<u64>;
/// Converts the value of `self` to an `f32`.
#[inline]
fn to_f32(&self) -> Option<f32> {
self.to_f64().and_then(|x| x.to_f32())
}
/// Converts the value of `self` to an `f64`.
#[inline]
fn to_f64(&self) -> Option<f64> {
self.to_i64().and_then(|x| x.to_f64())
}
}
macro_rules! impl_to_primitive_int_to_int {
($SrcT:ty, $DstT:ty, $slf:expr) => (
{
if size_of::<$SrcT>() <= size_of::<$DstT>() {
Some($slf as $DstT)
} else {
let n = $slf as i64;
let min_value: $DstT = Bounded::min_value();
let max_value: $DstT = Bounded::max_value();
if min_value as i64 <= n && n <= max_value as i64 {
Some($slf as $DstT)
} else {
None
}
}
}
)
}
macro_rules! impl_to_primitive_int_to_uint {
($SrcT:ty, $DstT:ty, $slf:expr) => (
{
let zero: $SrcT = 0;
let max_value: $DstT = Bounded::max_value();
if zero <= $slf && $slf as u64 <= max_value as u64 {
Some($slf as $DstT)
} else {
None
}
}
)
}
macro_rules! impl_to_primitive_int {
($T:ty) => (
impl ToPrimitive for $T {
#[inline]
fn to_isize(&self) -> Option<isize> { impl_to_primitive_int_to_int!($T, isize, *self) }
#[inline]
fn to_i8(&self) -> Option<i8> { impl_to_primitive_int_to_int!($T, i8, *self) }
#[inline]
fn to_i16(&self) -> Option<i16> { impl_to_primitive_int_to_int!($T, i16, *self) }
#[inline]
fn to_i32(&self) -> Option<i32> { impl_to_primitive_int_to_int!($T, i32, *self) }
#[inline]
fn to_i64(&self) -> Option<i64> { impl_to_primitive_int_to_int!($T, i64, *self) }
#[inline]
fn to_usize(&self) -> Option<usize> { impl_to_primitive_int_to_uint!($T, usize, *self) }
#[inline]
fn to_u8(&self) -> Option<u8> { impl_to_primitive_int_to_uint!($T, u8, *self) }
#[inline]
fn to_u16(&self) -> Option<u16> { impl_to_primitive_int_to_uint!($T, u16, *self) }
#[inline]
fn to_u32(&self) -> Option<u32> { impl_to_primitive_int_to_uint!($T, u32, *self) }
#[inline]
fn to_u64(&self) -> Option<u64> { impl_to_primitive_int_to_uint!($T, u64, *self) }
#[inline]
fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
#[inline]
fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
}
)
}
impl_to_primitive_int! { isize }
impl_to_primitive_int! { i8 }
impl_to_primitive_int! { i16 }
impl_to_primitive_int! { i32 }
impl_to_primitive_int! { i64 }
macro_rules! impl_to_primitive_uint_to_int {
($DstT:ty, $slf:expr) => (
{
let max_value: $DstT = Bounded::max_value();
if $slf as u64 <= max_value as u64 {
Some($slf as $DstT)
} else {
None
}
}
)
}
macro_rules! impl_to_primitive_uint_to_uint {
($SrcT:ty, $DstT:ty, $slf:expr) => (
{
if size_of::<$SrcT>() <= size_of::<$DstT>() {
Some($slf as $DstT)
} else {
let zero: $SrcT = 0;
let max_value: $DstT = Bounded::max_value();
if zero <= $slf && $slf as u64 <= max_value as u64 {
Some($slf as $DstT)
} else {
None
}
}
}
)
}
macro_rules! impl_to_primitive_uint {
($T:ty) => (
impl ToPrimitive for $T {
#[inline]
fn to_isize(&self) -> Option<isize> { impl_to_primitive_uint_to_int!(isize, *self) }
#[inline]
fn to_i8(&self) -> Option<i8> { impl_to_primitive_uint_to_int!(i8, *self) }
#[inline]
fn to_i16(&self) -> Option<i16> { impl_to_primitive_uint_to_int!(i16, *self) }
#[inline]
fn to_i32(&self) -> Option<i32> { impl_to_primitive_uint_to_int!(i32, *self) }
#[inline]
fn to_i64(&self) -> Option<i64> { impl_to_primitive_uint_to_int!(i64, *self) }
#[inline]
fn to_usize(&self) -> Option<usize> {
impl_to_primitive_uint_to_uint!($T, usize, *self)
}
#[inline]
fn to_u8(&self) -> Option<u8> { impl_to_primitive_uint_to_uint!($T, u8, *self) }
#[inline]
fn to_u16(&self) -> Option<u16> { impl_to_primitive_uint_to_uint!($T, u16, *self) }
#[inline]
fn to_u32(&self) -> Option<u32> { impl_to_primitive_uint_to_uint!($T, u32, *self) }
#[inline]
fn to_u64(&self) -> Option<u64> { impl_to_primitive_uint_to_uint!($T, u64, *self) }
#[inline]
fn to_f32(&self) -> Option<f32> { Some(*self as f32) }
#[inline]
fn to_f64(&self) -> Option<f64> { Some(*self as f64) }
}
)
}
impl_to_primitive_uint! { usize }
impl_to_primitive_uint! { u8 }
impl_to_primitive_uint! { u16 }
impl_to_primitive_uint! { u32 }
impl_to_primitive_uint! { u64 }
macro_rules! impl_to_primitive_float_to_float {
($SrcT:ident, $DstT:ident, $slf:expr) => (
if size_of::<$SrcT>() <= size_of::<$DstT>() {
Some($slf as $DstT)
macro_rules! int_to_int {
($dst:ident, $n:ident) => (
if $dst::MIN as i64 <= $n as i64 && $n as i64 <= $dst::MAX as i64 {
Some($n as $dst)
} else {
let n = $slf as f64;
let max_value: $SrcT = ::core::$SrcT::MAX;
if -max_value as f64 <= n && n <= max_value as f64 {
Some($slf as $DstT)
} else {
None
}
None
}
)
}
macro_rules! impl_to_primitive_float {
($T:ident) => (
impl ToPrimitive for $T {
#[inline]
fn to_isize(&self) -> Option<isize> { Some(*self as isize) }
#[inline]
fn to_i8(&self) -> Option<i8> { Some(*self as i8) }
#[inline]
fn to_i16(&self) -> Option<i16> { Some(*self as i16) }
#[inline]
fn to_i32(&self) -> Option<i32> { Some(*self as i32) }
#[inline]
fn to_i64(&self) -> Option<i64> { Some(*self as i64) }
#[inline]
fn to_usize(&self) -> Option<usize> { Some(*self as usize) }
#[inline]
fn to_u8(&self) -> Option<u8> { Some(*self as u8) }
#[inline]
fn to_u16(&self) -> Option<u16> { Some(*self as u16) }
#[inline]
fn to_u32(&self) -> Option<u32> { Some(*self as u32) }
#[inline]
fn to_u64(&self) -> Option<u64> { Some(*self as u64) }
#[inline]
fn to_f32(&self) -> Option<f32> { impl_to_primitive_float_to_float!($T, f32, *self) }
#[inline]
fn to_f64(&self) -> Option<f64> { impl_to_primitive_float_to_float!($T, f64, *self) }
macro_rules! int_to_uint {
($dst:ident, $n:ident) => (
if 0 <= $n && $n as u64 <= $dst::MAX as u64 {
Some($n as $dst)
} else {
None
}
)
}
impl_to_primitive_float! { f32 }
impl_to_primitive_float! { f64 }
macro_rules! uint_to {
($dst:ident, $n:ident) => (
if $n as u64 <= $dst::MAX as u64 {
Some($n as $dst)
} else {
None
}
)
}
pub trait FromPrimitive: Sized {
#[inline]
fn from_isize(n: isize) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
#[inline]
fn from_i8(n: i8) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
#[inline]
fn from_i16(n: i16) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
#[inline]
fn from_i32(n: i32) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
fn from_isize(n: isize) -> Option<Self>;
fn from_i8(n: i8) -> Option<Self>;
fn from_i16(n: i16) -> Option<Self>;
fn from_i32(n: i32) -> Option<Self>;
fn from_i64(n: i64) -> Option<Self>;
#[inline]
fn from_usize(n: usize) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
#[inline]
fn from_u8(n: u8) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
#[inline]
fn from_u16(n: u16) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
#[inline]
fn from_u32(n: u32) -> Option<Self> {
FromPrimitive::from_u64(n as u64)
}
fn from_usize(n: usize) -> Option<Self>;
fn from_u8(n: u8) -> Option<Self>;
fn from_u16(n: u16) -> Option<Self>;
fn from_u32(n: u32) -> Option<Self>;
fn from_u64(n: u64) -> Option<Self>;
#[inline]
fn from_f32(n: f32) -> Option<Self> {
FromPrimitive::from_f64(n as f64)
}
#[inline]
fn from_f64(n: f64) -> Option<Self> {
FromPrimitive::from_i64(n as i64)
}
}
macro_rules! impl_from_primitive {
($T:ty, $to_ty:ident) => (
impl FromPrimitive for $T {
#[inline] fn from_i8(n: i8) -> Option<$T> { n.$to_ty() }
#[inline] fn from_i16(n: i16) -> Option<$T> { n.$to_ty() }
#[inline] fn from_i32(n: i32) -> Option<$T> { n.$to_ty() }
#[inline] fn from_i64(n: i64) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u8(n: u8) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u16(n: u16) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u32(n: u32) -> Option<$T> { n.$to_ty() }
#[inline] fn from_u64(n: u64) -> Option<$T> { n.$to_ty() }
#[inline] fn from_f32(n: f32) -> Option<$T> { n.$to_ty() }
#[inline] fn from_f64(n: f64) -> Option<$T> { n.$to_ty() }
macro_rules! impl_from_primitive_for_int {
($t:ident) => (
impl FromPrimitive for $t {
#[inline] fn from_isize(n: isize) -> Option<Self> { int_to_int!($t, n) }
#[inline] fn from_i8(n: i8) -> Option<Self> { int_to_int!($t, n) }
#[inline] fn from_i16(n: i16) -> Option<Self> { int_to_int!($t, n) }
#[inline] fn from_i32(n: i32) -> Option<Self> { int_to_int!($t, n) }
#[inline] fn from_i64(n: i64) -> Option<Self> { int_to_int!($t, n) }
#[inline] fn from_usize(n: usize) -> Option<Self> { uint_to!($t, n) }
#[inline] fn from_u8(n: u8) -> Option<Self> { uint_to!($t, n) }
#[inline] fn from_u16(n: u16) -> Option<Self> { uint_to!($t, n) }
#[inline] fn from_u32(n: u32) -> Option<Self> { uint_to!($t, n) }
#[inline] fn from_u64(n: u64) -> Option<Self> { uint_to!($t, n) }
}
)
}
impl_from_primitive! { isize, to_isize }
impl_from_primitive! { i8, to_i8 }
impl_from_primitive! { i16, to_i16 }
impl_from_primitive! { i32, to_i32 }
impl_from_primitive! { i64, to_i64 }
impl_from_primitive! { usize, to_usize }
impl_from_primitive! { u8, to_u8 }
impl_from_primitive! { u16, to_u16 }
impl_from_primitive! { u32, to_u32 }
impl_from_primitive! { u64, to_u64 }
impl_from_primitive! { f32, to_f32 }
impl_from_primitive! { f64, to_f64 }
macro_rules! impl_from_primitive_for_uint {
($t:ident) => (
impl FromPrimitive for $t {
#[inline] fn from_isize(n: isize) -> Option<Self> { int_to_uint!($t, n) }
#[inline] fn from_i8(n: i8) -> Option<Self> { int_to_uint!($t, n) }
#[inline] fn from_i16(n: i16) -> Option<Self> { int_to_uint!($t, n) }
#[inline] fn from_i32(n: i32) -> Option<Self> { int_to_uint!($t, n) }
#[inline] fn from_i64(n: i64) -> Option<Self> { int_to_uint!($t, n) }
#[inline] fn from_usize(n: usize) -> Option<Self> { uint_to!($t, n) }
#[inline] fn from_u8(n: u8) -> Option<Self> { uint_to!($t, n) }
#[inline] fn from_u16(n: u16) -> Option<Self> { uint_to!($t, n) }
#[inline] fn from_u32(n: u32) -> Option<Self> { uint_to!($t, n) }
#[inline] fn from_u64(n: u64) -> Option<Self> { uint_to!($t, n) }
}
)
}
macro_rules! impl_from_primitive_for_float {
($t:ident) => (
impl FromPrimitive for $t {
#[inline] fn from_isize(n: isize) -> Option<Self> { Some(n as Self) }
#[inline] fn from_i8(n: i8) -> Option<Self> { Some(n as Self) }
#[inline] fn from_i16(n: i16) -> Option<Self> { Some(n as Self) }
#[inline] fn from_i32(n: i32) -> Option<Self> { Some(n as Self) }
#[inline] fn from_i64(n: i64) -> Option<Self> { Some(n as Self) }
#[inline] fn from_usize(n: usize) -> Option<Self> { Some(n as Self) }
#[inline] fn from_u8(n: u8) -> Option<Self> { Some(n as Self) }
#[inline] fn from_u16(n: u16) -> Option<Self> { Some(n as Self) }
#[inline] fn from_u32(n: u32) -> Option<Self> { Some(n as Self) }
#[inline] fn from_u64(n: u64) -> Option<Self> { Some(n as Self) }
}
)
}
impl_from_primitive_for_int!(isize);
impl_from_primitive_for_int!(i8);
impl_from_primitive_for_int!(i16);
impl_from_primitive_for_int!(i32);
impl_from_primitive_for_int!(i64);
impl_from_primitive_for_uint!(usize);
impl_from_primitive_for_uint!(u8);
impl_from_primitive_for_uint!(u16);
impl_from_primitive_for_uint!(u32);
impl_from_primitive_for_uint!(u64);
impl_from_primitive_for_float!(f32);
impl_from_primitive_for_float!(f64);

View File

@ -0,0 +1,215 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
use de::{Deserialize, Deserializer, Visitor, SeqAccess, MapAccess, Error};
/// An efficient way of discarding data from a deserializer.
///
/// Think of this like `serde_json::Value` in that it can be deserialized from
/// any type, except that it does not store any information about the data that
/// gets deserialized.
///
/// ```rust
/// use std::fmt;
/// use std::marker::PhantomData;
///
/// use serde::de::{self, Deserialize, DeserializeSeed, Deserializer, Visitor, SeqAccess, IgnoredAny};
///
/// /// A seed that can be used to deserialize only the `n`th element of a sequence
/// /// while efficiently discarding elements of any type before or after index `n`.
/// ///
/// /// For example to deserialize only the element at index 3:
/// ///
/// /// ```rust
/// /// NthElement::new(3).deserialize(deserializer)
/// /// ```
/// pub struct NthElement<T> {
/// n: usize,
/// marker: PhantomData<T>,
/// }
///
/// impl<T> NthElement<T> {
/// pub fn new(n: usize) -> Self {
/// NthElement {
/// n: n,
/// marker: PhantomData,
/// }
/// }
/// }
///
/// impl<'de, T> Visitor<'de> for NthElement<T>
/// where T: Deserialize<'de>
/// {
/// type Value = T;
///
/// fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
/// write!(formatter, "a sequence in which we care about element {}", self.n)
/// }
///
/// fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
/// where A: SeqAccess<'de>
/// {
/// // Skip over the first `n` elements.
/// for i in 0..self.n {
/// // It is an error if the sequence ends before we get to element `n`.
/// if seq.next_element::<IgnoredAny>()?.is_none() {
/// return Err(de::Error::invalid_length(i, &self));
/// }
/// }
///
/// // Deserialize the one we care about.
/// let nth = match seq.next_element()? {
/// Some(nth) => nth,
/// None => {
/// return Err(de::Error::invalid_length(self.n, &self));
/// }
/// };
///
/// // Skip over any remaining elements in the sequence after `n`.
/// while let Some(IgnoredAny) = seq.next_element()? {
/// // ignore
/// }
///
/// Ok(nth)
/// }
/// }
///
/// impl<'de, T> DeserializeSeed<'de> for NthElement<T>
/// where T: Deserialize<'de>
/// {
/// type Value = T;
///
/// fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
/// where D: Deserializer<'de>
/// {
/// deserializer.deserialize_seq(self)
/// }
/// }
///
/// # fn example<'de, D>(deserializer: D) -> Result<(), D::Error>
/// # where D: Deserializer<'de>
/// # {
/// // Deserialize only the sequence element at index 3 from this deserializer.
/// // The element at index 3 is required to be a string. Elements before and
/// // after index 3 are allowed to be of any type.
/// let s: String = NthElement::new(3).deserialize(deserializer)?;
/// # Ok(())
/// # }
/// ```
#[derive(Copy, Clone, Debug, Default)]
pub struct IgnoredAny;
impl<'de> Visitor<'de> for IgnoredAny {
type Value = IgnoredAny;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("anything at all")
}
#[inline]
fn visit_bool<E>(self, x: bool) -> Result<Self::Value, E> {
let _ = x;
Ok(IgnoredAny)
}
#[inline]
fn visit_i64<E>(self, x: i64) -> Result<Self::Value, E> {
let _ = x;
Ok(IgnoredAny)
}
#[inline]
fn visit_u64<E>(self, x: u64) -> Result<Self::Value, E> {
let _ = x;
Ok(IgnoredAny)
}
#[inline]
fn visit_f64<E>(self, x: f64) -> Result<Self::Value, E> {
let _ = x;
Ok(IgnoredAny)
}
#[inline]
fn visit_str<E>(self, s: &str) -> Result<Self::Value, E>
where
E: Error,
{
let _ = s;
Ok(IgnoredAny)
}
#[inline]
fn visit_none<E>(self) -> Result<Self::Value, E> {
Ok(IgnoredAny)
}
#[inline]
fn visit_some<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
IgnoredAny::deserialize(deserializer)
}
#[inline]
fn visit_newtype_struct<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
where
D: Deserializer<'de>,
{
IgnoredAny::deserialize(deserializer)
}
#[inline]
fn visit_unit<E>(self) -> Result<Self::Value, E> {
Ok(IgnoredAny)
}
#[inline]
fn visit_seq<A>(self, mut seq: A) -> Result<Self::Value, A::Error>
where
A: SeqAccess<'de>,
{
while let Some(IgnoredAny) = try!(seq.next_element()) {
// Gobble
}
Ok(IgnoredAny)
}
#[inline]
fn visit_map<A>(self, mut map: A) -> Result<Self::Value, A::Error>
where
A: MapAccess<'de>,
{
while let Some((IgnoredAny, IgnoredAny)) = try!(map.next_entry()) {
// Gobble
}
Ok(IgnoredAny)
}
#[inline]
fn visit_bytes<E>(self, bytes: &[u8]) -> Result<Self::Value, E>
where
E: Error,
{
let _ = bytes;
Ok(IgnoredAny)
}
}
impl<'de> Deserialize<'de> for IgnoredAny {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<IgnoredAny, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_ignored_any(IgnoredAny)
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

54
third_party/rust/serde/src/de/utf8.rs vendored Normal file
View File

@ -0,0 +1,54 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
const TAG_CONT: u8 = 0b1000_0000;
const TAG_TWO_B: u8 = 0b1100_0000;
const TAG_THREE_B: u8 = 0b1110_0000;
const TAG_FOUR_B: u8 = 0b1111_0000;
const MAX_ONE_B: u32 = 0x80;
const MAX_TWO_B: u32 = 0x800;
const MAX_THREE_B: u32 = 0x10000;
#[inline]
pub fn encode(c: char) -> Encode {
let code = c as u32;
let mut buf = [0; 4];
let pos = if code < MAX_ONE_B {
buf[3] = code as u8;
3
} else if code < MAX_TWO_B {
buf[2] = (code >> 6 & 0x1F) as u8 | TAG_TWO_B;
buf[3] = (code & 0x3F) as u8 | TAG_CONT;
2
} else if code < MAX_THREE_B {
buf[1] = (code >> 12 & 0x0F) as u8 | TAG_THREE_B;
buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
buf[3] = (code & 0x3F) as u8 | TAG_CONT;
1
} else {
buf[0] = (code >> 18 & 0x07) as u8 | TAG_FOUR_B;
buf[1] = (code >> 12 & 0x3F) as u8 | TAG_CONT;
buf[2] = (code >> 6 & 0x3F) as u8 | TAG_CONT;
buf[3] = (code & 0x3F) as u8 | TAG_CONT;
0
};
Encode { buf: buf, pos: pos }
}
pub struct Encode {
buf: [u8; 4],
pos: usize,
}
impl Encode {
pub fn as_str(&self) -> &str {
str::from_utf8(&self.buf[self.pos..]).unwrap()
}
}

File diff suppressed because it is too large Load Diff

View File

@ -1,34 +1,41 @@
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::String;
#[cfg(feature = "std")]
use std::borrow::Cow;
#[cfg(all(feature = "collections", not(feature = "std")))]
use collections::borrow::Cow;
pub use core::default::Default;
pub use core::fmt;
pub use core::marker::PhantomData;
pub use core::option::Option::{self, None, Some};
pub use core::result::Result::{self, Ok, Err};
#[cfg(any(feature = "collections", feature = "std"))]
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
String::from_utf8_lossy(bytes)
}
// The generated code calls this like:
// Copyright 2017 Serde Developers
//
// let value = &_serde::export::from_utf8_lossy(bytes);
// Err(_serde::de::Error::unknown_variant(value, VARIANTS))
//
// so it is okay for the return type to be different from the std case as long
// as the above works.
#[cfg(not(any(feature = "collections", feature = "std")))]
pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
use core::str;
// Three unicode replacement characters if it fails. They look like a
// white-on-black question mark. The user will recognize it as invalid
// UTF-8.
str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}")
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
pub use lib::clone::Clone;
pub use lib::convert::{From, Into};
pub use lib::default::Default;
pub use lib::fmt::{self, Formatter};
pub use lib::marker::PhantomData;
pub use lib::option::Option::{self, None, Some};
pub use lib::result::Result::{self, Ok, Err};
pub use self::string::from_utf8_lossy;
mod string {
use lib::*;
#[cfg(any(feature = "std", feature = "collections"))]
pub fn from_utf8_lossy(bytes: &[u8]) -> Cow<str> {
String::from_utf8_lossy(bytes)
}
// The generated code calls this like:
//
// let value = &_serde::export::from_utf8_lossy(bytes);
// Err(_serde::de::Error::unknown_variant(value, VARIANTS))
//
// so it is okay for the return type to be different from the std case as long
// as the above works.
#[cfg(not(any(feature = "std", feature = "collections")))]
pub fn from_utf8_lossy(bytes: &[u8]) -> &str {
// Three unicode replacement characters if it fails. They look like a
// white-on-black question mark. The user will recognize it as invalid
// UTF-8.
str::from_utf8(bytes).unwrap_or("\u{fffd}\u{fffd}\u{fffd}")
}
}

View File

@ -1,3 +1,11 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! # Serde
//!
//! Serde is a framework for ***ser***ializing and ***de***serializing Rust data
@ -9,63 +17,92 @@
//! these two groups interact with each other, allowing any supported data
//! structure to be serialized and deserialized using any supported data format.
//!
//! See the Serde website https://serde.rs/ for additional documentation and
//! See the Serde website [https://serde.rs/] for additional documentation and
//! usage examples.
//!
//! ### Design
//! [https://serde.rs/]: https://serde.rs/
//!
//! ## Design
//!
//! Where many other languages rely on runtime reflection for serializing data,
//! Serde is instead built on Rust's powerful trait system. A data structure
//! that knows how to serialize and deserialize itself is one that implements
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's code
//! generation to automatically derive implementations at compile time). This
//! Serde's `Serialize` and `Deserialize` traits (or uses Serde's derive
//! attribute to automatically generate implementations at compile time). This
//! avoids any overhead of reflection or runtime type information. In fact in
//! many situations the interaction between data structure and data format can
//! be completely optimized away by the Rust compiler, leaving Serde
//! serialization to perform roughly the same speed as a handwritten serializer
//! for the specific selection of data structure and data format.
//! serialization to perform the same speed as a handwritten serializer for the
//! specific selection of data structure and data format.
//!
//! ### Data formats
//! ## Data formats
//!
//! The following is a partial list of data formats that have been implemented
//! for Serde by the community.
//!
//! - [JSON](https://github.com/serde-rs/json), the ubiquitous JavaScript Object
//! Notation used by many HTTP APIs.
//! - [Bincode](https://github.com/TyOverby/bincode), a compact binary format
//! - [JSON], the ubiquitous JavaScript Object Notation used by many HTTP APIs.
//! - [Bincode], a compact binary format
//! used for IPC within the Servo rendering engine.
//! - [CBOR](https://github.com/pyfisch/cbor), a Concise Binary Object
//! Representation designed for small message size without the need for
//! version negotiation.
//! - [YAML](https://github.com/dtolnay/serde-yaml), a popular human-friendly
//! configuration language that ain't markup language.
//! - [MessagePack](https://github.com/3Hren/msgpack-rust), an efficient binary
//! format that resembles a compact JSON.
//! - [TOML](https://github.com/alexcrichton/toml-rs), a minimal configuration
//! format used by [Cargo](http://doc.crates.io/manifest.html).
//! - [Pickle](https://github.com/birkenfeld/serde-pickle), a format common in
//! the Python world.
//! - [Hjson](https://github.com/laktak/hjson-rust), a variant of JSON designed
//! to be readable and writable by humans.
//! - [BSON](https://github.com/zonyitoo/bson-rs), the data storage and network
//! transfer format used by MongoDB.
//! - [URL](https://github.com/nox/serde_urlencoded), the x-www-form-urlencoded
//! format.
//! - [XML](https://github.com/serde-rs/xml), the flexible machine-friendly W3C
//! standard. *(deserialization only)*
//! - [Envy](https://github.com/softprops/envy), a way to deserialize
//! environment variables into Rust structs. *(deserialization only)*
//! - [Redis](https://github.com/OneSignal/serde-redis), deserialize values from
//! Redis when using [redis-rs](https://crates.io/crates/redis).
//! - [CBOR], a Concise Binary Object Representation designed for small message
//! size without the need for version negotiation.
//! - [YAML], a popular human-friendly configuration language that ain't markup
//! language.
//! - [MessagePack], an efficient binary format that resembles a compact JSON.
//! - [TOML], a minimal configuration format used by [Cargo].
//! - [Pickle], a format common in the Python world.
//! - [Hjson], a variant of JSON designed to be readable and writable by humans.
//! - [BSON], the data storage and network transfer format used by MongoDB.
//! - [URL], the x-www-form-urlencoded format.
//! - [XML], the flexible machine-friendly W3C standard.
//! *(deserialization only)*
//! - [Envy], a way to deserialize environment variables into Rust structs.
//! *(deserialization only)*
//! - [Redis], deserialize values from Redis when using [redis-rs].
//! *(deserialization only)*
//!
//! [JSON]: https://github.com/serde-rs/json
//! [Bincode]: https://github.com/TyOverby/bincode
//! [CBOR]: https://github.com/pyfisch/cbor
//! [YAML]: https://github.com/dtolnay/serde-yaml
//! [MessagePack]: https://github.com/3Hren/msgpack-rust
//! [TOML]: https://github.com/alexcrichton/toml-rs
//! [Pickle]: https://github.com/birkenfeld/serde-pickle
//! [Hjson]: https://github.com/laktak/hjson-rust
//! [BSON]: https://github.com/zonyitoo/bson-rs
//! [URL]: https://github.com/nox/serde_urlencoded
//! [XML]: https://github.com/RReverser/serde-xml-rs
//! [Envy]: https://github.com/softprops/envy
//! [Redis]: https://github.com/OneSignal/serde-redis
//! [Cargo]: http://doc.crates.io/manifest.html
//! [redis-rs]: https://crates.io/crates/redis
#![doc(html_root_url="https://docs.serde.rs")]
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
#![doc(html_root_url = "https://docs.rs/serde/1.0.7")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
#![cfg_attr(feature = "unstable", feature(inclusive_range, nonzero, specialization, zero_one))]
// Unstable functionality only if the user asks for it. For tracking and
// discussion of these features please refer to this issue:
//
// https://github.com/serde-rs/serde/issues/812
#![cfg_attr(feature = "unstable", feature(nonzero, specialization))]
#![cfg_attr(all(feature = "std", feature = "unstable"), feature(into_boxed_c_str))]
#![cfg_attr(feature = "alloc", feature(alloc))]
#![cfg_attr(feature = "collections", feature(collections))]
#![cfg_attr(feature = "cargo-clippy", allow(linkedlist, type_complexity, doc_markdown))]
#![deny(missing_docs)]
// Whitelisted clippy lints.
#![cfg_attr(feature = "cargo-clippy", allow(doc_markdown))]
#![cfg_attr(feature = "cargo-clippy", allow(linkedlist))]
#![cfg_attr(feature = "cargo-clippy", allow(type_complexity))]
#![cfg_attr(feature = "cargo-clippy", allow(zero_prefixed_literal))]
// Blacklisted Rust lints.
#![deny(missing_docs, unused_imports)]
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "collections")]
extern crate collections;
@ -73,35 +110,155 @@ extern crate collections;
#[cfg(feature = "alloc")]
extern crate alloc;
#[cfg(feature = "unstable")]
extern crate core as actual_core;
#[cfg(all(feature = "unstable", feature = "std"))]
extern crate core;
/// A facade around all the types we need from the `std`, `core`, `alloc`, and
/// `collections` crates. This avoids elaborate import wrangling having to
/// happen in every module.
mod lib {
mod core {
#[cfg(feature = "std")]
pub use std::*;
#[cfg(not(feature = "std"))]
pub use core::*;
}
pub use self::core::{cmp, iter, mem, ops, slice, str};
pub use self::core::{i8, i16, i32, i64, isize};
pub use self::core::{u8, u16, u32, u64, usize};
pub use self::core::{f32, f64};
pub use self::core::cell::{Cell, RefCell};
pub use self::core::clone::{self, Clone};
pub use self::core::convert::{self, From, Into};
pub use self::core::default::{self, Default};
pub use self::core::fmt::{self, Debug, Display};
pub use self::core::marker::{self, PhantomData};
pub use self::core::option::{self, Option};
pub use self::core::result::{self, Result};
#[cfg(feature = "std")]
pub use std::borrow::{Cow, ToOwned};
#[cfg(all(feature = "collections", not(feature = "std")))]
pub use collections::borrow::{Cow, ToOwned};
#[cfg(feature = "std")]
pub use std::string::String;
#[cfg(all(feature = "collections", not(feature = "std")))]
pub use collections::string::{String, ToString};
#[cfg(feature = "std")]
pub use std::vec::Vec;
#[cfg(all(feature = "collections", not(feature = "std")))]
pub use collections::vec::Vec;
#[cfg(feature = "std")]
pub use std::boxed::Box;
#[cfg(all(feature = "alloc", not(feature = "std")))]
pub use alloc::boxed::Box;
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::rc::Rc;
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::rc::Rc;
#[cfg(all(feature = "rc", feature = "std"))]
pub use std::sync::Arc;
#[cfg(all(feature = "rc", feature = "alloc", not(feature = "std")))]
pub use alloc::arc::Arc;
#[cfg(feature = "std")]
pub use std::collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
#[cfg(all(feature = "collections", not(feature = "std")))]
pub use collections::{BinaryHeap, BTreeMap, BTreeSet, LinkedList, VecDeque};
#[cfg(feature = "std")]
pub use std::{error, net};
#[cfg(feature = "std")]
pub use std::collections::{HashMap, HashSet};
#[cfg(feature = "std")]
pub use std::ffi::{CString, CStr, OsString, OsStr};
#[cfg(feature = "std")]
pub use std::hash::{Hash, BuildHasher};
#[cfg(feature = "std")]
pub use std::io::Write;
#[cfg(feature = "std")]
pub use std::path::{Path, PathBuf};
#[cfg(feature = "std")]
pub use std::time::Duration;
#[cfg(feature = "std")]
pub use std::sync::{Mutex, RwLock};
#[cfg(feature = "std")]
mod core {
pub use std::{ops, hash, fmt, cmp, marker, mem, i8, i16, i32, i64, u8, u16, u32, u64, isize,
usize, f32, f64, char, str, num, slice, iter, cell, default, result, option};
#[cfg(feature = "unstable")]
pub use actual_core::nonzero;
pub use core::nonzero::{NonZero, Zeroable};
}
////////////////////////////////////////////////////////////////////////////////
#[macro_use]
mod macros;
pub mod ser;
pub mod de;
#[doc(inline)]
pub use ser::{Serialize, Serializer};
#[doc(inline)]
pub use de::{Deserialize, Deserializer};
#[macro_use]
mod macros;
pub mod bytes;
pub mod de;
#[cfg(feature = "std")]
#[doc(hidden)]
pub mod iter;
pub mod ser;
#[cfg_attr(feature = "std", doc(hidden))]
pub mod error;
mod utils;
// Generated code uses these to support no_std. Not public API.
#[doc(hidden)]
pub mod export;
// Helpers used by generated code and doc tests. Not public API.
#[doc(hidden)]
pub mod private;
// Re-export #[derive(Serialize, Deserialize)].
//
// This is a workaround for https://github.com/rust-lang/cargo/issues/1286.
// Without this re-export, crates that put Serde derives behind a cfg_attr would
// need to use some silly feature name that depends on both serde and
// serde_derive.
//
// [features]
// serde-impls = ["serde", "serde_derive"]
//
// [dependencies]
// serde = { version = "1.0", optional = true }
// serde_derive = { version = "1.0", optional = true }
//
// # Used like this:
// # #[cfg(feature = "serde-impls")]
// # #[macro_use]
// # extern crate serde_derive;
// #
// # #[cfg_attr(feature = "serde-impls", derive(Serialize, Deserialize))]
// # struct S { /* ... */ }
//
// The re-exported derives allow crates to use "serde" as the name of their
// Serde feature which is more intuitive.
//
// [dependencies]
// serde = { version = "1.0", optional = true, features = ["derive"] }
//
// # Used like this:
// # #[cfg(feature = "serde")]
// # #[macro_use]
// # extern crate serde;
// #
// # #[cfg_attr(feature = "serde", derive(Serialize, Deserialize))]
// # struct S { /* ... */ }
//
// The reason re-exporting is not enabled by default is that disabling it would
// be annoying for crates that provide handwritten impls or data formats. They
// would need to disable default features and then explicitly re-enable std.
#[cfg(feature = "serde_derive")]
#[allow(unused_imports)]
#[macro_use]
extern crate serde_derive;
#[cfg(feature = "serde_derive")]
#[doc(hidden)]
pub use serde_derive::*;

View File

@ -1,122 +1,10 @@
#[cfg(feature = "std")]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_method {
($func:ident($($arg:ty),*)) => {
#[inline]
fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> ::std::result::Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor
{
self.deserialize(visitor)
}
};
}
#[cfg(not(feature = "std"))]
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_method {
($func:ident($($arg:ty),*)) => {
#[inline]
fn $func<__V>(self, $(_: $arg,)* visitor: __V) -> ::core::result::Result<__V::Value, Self::Error>
where __V: $crate::de::Visitor
{
self.deserialize(visitor)
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_helper {
(bool) => {
forward_to_deserialize_method!{deserialize_bool()}
};
(u8) => {
forward_to_deserialize_method!{deserialize_u8()}
};
(u16) => {
forward_to_deserialize_method!{deserialize_u16()}
};
(u32) => {
forward_to_deserialize_method!{deserialize_u32()}
};
(u64) => {
forward_to_deserialize_method!{deserialize_u64()}
};
(i8) => {
forward_to_deserialize_method!{deserialize_i8()}
};
(i16) => {
forward_to_deserialize_method!{deserialize_i16()}
};
(i32) => {
forward_to_deserialize_method!{deserialize_i32()}
};
(i64) => {
forward_to_deserialize_method!{deserialize_i64()}
};
(f32) => {
forward_to_deserialize_method!{deserialize_f32()}
};
(f64) => {
forward_to_deserialize_method!{deserialize_f64()}
};
(char) => {
forward_to_deserialize_method!{deserialize_char()}
};
(str) => {
forward_to_deserialize_method!{deserialize_str()}
};
(string) => {
forward_to_deserialize_method!{deserialize_string()}
};
(unit) => {
forward_to_deserialize_method!{deserialize_unit()}
};
(option) => {
forward_to_deserialize_method!{deserialize_option()}
};
(seq) => {
forward_to_deserialize_method!{deserialize_seq()}
};
(seq_fixed_size) => {
forward_to_deserialize_method!{deserialize_seq_fixed_size(usize)}
};
(bytes) => {
forward_to_deserialize_method!{deserialize_bytes()}
};
(byte_buf) => {
forward_to_deserialize_method!{deserialize_byte_buf()}
};
(map) => {
forward_to_deserialize_method!{deserialize_map()}
};
(unit_struct) => {
forward_to_deserialize_method!{deserialize_unit_struct(&'static str)}
};
(newtype_struct) => {
forward_to_deserialize_method!{deserialize_newtype_struct(&'static str)}
};
(tuple_struct) => {
forward_to_deserialize_method!{deserialize_tuple_struct(&'static str, usize)}
};
(struct) => {
forward_to_deserialize_method!{deserialize_struct(&'static str, &'static [&'static str])}
};
(struct_field) => {
forward_to_deserialize_method!{deserialize_struct_field()}
};
(tuple) => {
forward_to_deserialize_method!{deserialize_tuple(usize)}
};
(enum) => {
forward_to_deserialize_method!{deserialize_enum(&'static str, &'static [&'static str])}
};
(ignored_any) => {
forward_to_deserialize_method!{deserialize_ignored_any()}
};
}
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
// Super explicit first paragraph because this shows up at the top level and
// trips up people who are just looking for basic Serialize / Deserialize
@ -125,98 +13,230 @@ macro_rules! forward_to_deserialize_helper {
/// Helper macro when implementing the `Deserializer` part of a new data format
/// for Serde.
///
/// Some `Deserializer` implementations for self-describing formats do not care
/// what hint the `Visitor` gives them, they just want to blindly call the
/// `Visitor` method corresponding to the data they can tell is in the input.
/// This requires repetitive implementations of all the `Deserializer` trait
/// methods.
/// Some [`Deserializer`] implementations for self-describing formats do not
/// care what hint the [`Visitor`] gives them, they just want to blindly call
/// the [`Visitor`] method corresponding to the data they can tell is in the
/// input. This requires repetitive implementations of all the [`Deserializer`]
/// trait methods.
///
/// ```rust
/// # #[macro_use] extern crate serde;
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::de::{value, Deserializer, Visitor};
/// # pub struct MyDeserializer;
/// # impl Deserializer for MyDeserializer {
/// #
/// # struct MyDeserializer;
/// #
/// # impl<'de> Deserializer<'de> for MyDeserializer {
/// # type Error = value::Error;
/// # fn deserialize<V>(self, _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor
/// # { unimplemented!() }
/// #
/// # fn deserialize_any<V>(self, _: V) -> Result<V::Value, Self::Error>
/// # where V: Visitor<'de>
/// # {
/// # unimplemented!()
/// # }
/// #
/// #[inline]
/// fn deserialize_bool<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor
/// where V: Visitor<'de>
/// {
/// self.deserialize(visitor)
/// self.deserialize_any(visitor)
/// }
/// # forward_to_deserialize! {
/// # u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
/// # seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
/// # tuple_struct struct struct_field tuple enum ignored_any
/// #
/// # forward_to_deserialize_any! {
/// # i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
/// # byte_buf option unit unit_struct newtype_struct seq tuple
/// # tuple_struct map struct enum identifier ignored_any
/// # }
/// # }
/// #
/// # fn main() {}
/// ```
///
/// The `forward_to_deserialize!` macro implements these simple forwarding
/// methods so that they forward directly to `Deserializer::deserialize`. You
/// can choose which methods to forward.
/// The `forward_to_deserialize_any!` macro implements these simple forwarding
/// methods so that they forward directly to [`Deserializer::deserialize_any`].
/// You can choose which methods to forward.
///
/// ```rust
/// # #[macro_use] extern crate serde;
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::de::{value, Deserializer, Visitor};
/// # pub struct MyDeserializer;
/// impl Deserializer for MyDeserializer {
/// #
/// # struct MyDeserializer;
/// #
/// impl<'de> Deserializer<'de> for MyDeserializer {
/// # type Error = value::Error;
/// fn deserialize<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor
/// #
/// fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
/// where V: Visitor<'de>
/// {
/// /* ... */
/// # let _ = visitor;
/// # unimplemented!()
/// }
///
/// forward_to_deserialize! {
/// bool u8 u16 u32 u64 i8 i16 i32 i64 f32 f64 char str string unit option
/// seq seq_fixed_size bytes byte_buf map unit_struct newtype_struct
/// tuple_struct struct struct_field tuple enum ignored_any
/// forward_to_deserialize_any! {
/// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
/// byte_buf option unit unit_struct newtype_struct seq tuple
/// tuple_struct map struct enum identifier ignored_any
/// }
/// }
/// #
/// # fn main() {}
/// ```
///
/// The macro assumes the convention that your `Deserializer` lifetime parameter
/// is called `'de` and that the `Visitor` type parameters on each method are
/// called `V`. A different type parameter and a different lifetime can be
/// specified explicitly if necessary.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use std::marker::PhantomData;
/// #
/// # use serde::de::{value, Deserializer, Visitor};
/// #
/// # struct MyDeserializer<V>(PhantomData<V>);
/// #
/// # impl<'q, V> Deserializer<'q> for MyDeserializer<V> {
/// # type Error = value::Error;
/// #
/// # fn deserialize_any<W>(self, visitor: W) -> Result<W::Value, Self::Error>
/// # where W: Visitor<'q>
/// # {
/// # unimplemented!()
/// # }
/// #
/// forward_to_deserialize_any! {
/// <W: Visitor<'q>>
/// bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
/// byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
/// map struct enum identifier ignored_any
/// }
/// # }
/// #
/// # fn main() {}
/// ```
///
/// [`Deserializer`]: trait.Deserializer.html
/// [`Visitor`]: de/trait.Visitor.html
/// [`Deserializer::deserialize_any`]: trait.Deserializer.html#tymethod.deserialize_any
#[macro_export]
macro_rules! forward_to_deserialize {
macro_rules! forward_to_deserialize_any {
(<$visitor:ident: Visitor<$lifetime:tt>> $($func:ident)*) => {
$(forward_to_deserialize_any_helper!{$func<$lifetime, $visitor>})*
};
// This case must be after the previous one.
($($func:ident)*) => {
$(forward_to_deserialize_helper!{$func})*
$(forward_to_deserialize_any_helper!{$func<'de, V>})*
};
}
/// Seralize the `$value` that implements Display as a string,
/// when that string is statically known to never have more than
/// a constant `$MAX_LEN` bytes.
///
/// Panics if the Display impl tries to write more than `$MAX_LEN` bytes.
#[cfg(feature = "std")]
// Not exported
macro_rules! serialize_display_bounded_length {
($value: expr, $MAX_LEN: expr, $serializer: expr) => {
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_any_method {
($func:ident<$l:tt, $v:ident>($($arg:ident : $ty:ty),*)) => {
#[inline]
fn $func<$v>(self, $($arg: $ty,)* visitor: $v) -> $crate::export::Result<$v::Value, Self::Error>
where
$v: $crate::de::Visitor<$l>,
{
use std::io::Write;
let mut buffer: [u8; $MAX_LEN] = unsafe { ::std::mem::uninitialized() };
let remaining_len;
{
let mut remaining = &mut buffer[..];
write!(remaining, "{}", $value).unwrap();
remaining_len = remaining.len()
}
let written_len = buffer.len() - remaining_len;
let written = &buffer[..written_len];
// write! only provides std::fmt::Formatter to Display implementations,
// which has methods write_str and write_char but no method to write arbitrary bytes.
// Therefore, `written` is well-formed in UTF-8.
let written_str = unsafe {
::std::str::from_utf8_unchecked(written)
};
$serializer.serialize_str(written_str)
$(
let _ = $arg;
)*
self.deserialize_any(visitor)
}
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! forward_to_deserialize_any_helper {
(bool<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_bool<$l, $v>()}
};
(i8<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_i8<$l, $v>()}
};
(i16<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_i16<$l, $v>()}
};
(i32<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_i32<$l, $v>()}
};
(i64<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_i64<$l, $v>()}
};
(u8<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_u8<$l, $v>()}
};
(u16<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_u16<$l, $v>()}
};
(u32<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_u32<$l, $v>()}
};
(u64<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_u64<$l, $v>()}
};
(f32<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_f32<$l, $v>()}
};
(f64<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_f64<$l, $v>()}
};
(char<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_char<$l, $v>()}
};
(str<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_str<$l, $v>()}
};
(string<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_string<$l, $v>()}
};
(bytes<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_bytes<$l, $v>()}
};
(byte_buf<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_byte_buf<$l, $v>()}
};
(option<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_option<$l, $v>()}
};
(unit<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_unit<$l, $v>()}
};
(unit_struct<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_unit_struct<$l, $v>(name: &'static str)}
};
(newtype_struct<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_newtype_struct<$l, $v>(name: &'static str)}
};
(seq<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_seq<$l, $v>()}
};
(tuple<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_tuple<$l, $v>(len: usize)}
};
(tuple_struct<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_tuple_struct<$l, $v>(name: &'static str, len: usize)}
};
(map<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_map<$l, $v>()}
};
(struct<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_struct<$l, $v>(name: &'static str, fields: &'static [&'static str])}
};
(enum<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_enum<$l, $v>(name: &'static str, variants: &'static [&'static str])}
};
(identifier<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_identifier<$l, $v>()}
};
(ignored_any<$l:tt, $v:ident>) => {
forward_to_deserialize_any_method!{deserialize_ignored_any<$l, $v>()}
};
}

1952
third_party/rust/serde/src/private/de.rs vendored Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,148 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#[doc(hidden)]
#[macro_export]
macro_rules! __private_serialize {
() => {
trait Serialize {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: $crate::Serializer;
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __private_deserialize {
() => {
trait Deserialize<'de>: Sized {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: $crate::Deserializer<'de>;
}
};
}
/// Used only by Serde doc tests. Not public API.
#[doc(hidden)]
#[macro_export]
macro_rules! __serialize_unimplemented {
($($func:ident)*) => {
$(
__serialize_unimplemented_helper!($func);
)*
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __serialize_unimplemented_method {
($func:ident $(<$t:ident>)* ($($arg:ty),*) -> $ret:ident) => {
fn $func $(<$t: ?Sized + $crate::Serialize>)* (self $(, _: $arg)*) -> $crate::export::Result<Self::$ret, Self::Error> {
unimplemented!()
}
};
}
#[doc(hidden)]
#[macro_export]
macro_rules! __serialize_unimplemented_helper {
(bool) => {
__serialize_unimplemented_method!(serialize_bool(bool) -> Ok);
};
(i8) => {
__serialize_unimplemented_method!(serialize_i8(i8) -> Ok);
};
(i16) => {
__serialize_unimplemented_method!(serialize_i16(i16) -> Ok);
};
(i32) => {
__serialize_unimplemented_method!(serialize_i32(i32) -> Ok);
};
(i64) => {
__serialize_unimplemented_method!(serialize_i64(i64) -> Ok);
};
(u8) => {
__serialize_unimplemented_method!(serialize_u8(u8) -> Ok);
};
(u16) => {
__serialize_unimplemented_method!(serialize_u16(u16) -> Ok);
};
(u32) => {
__serialize_unimplemented_method!(serialize_u32(u32) -> Ok);
};
(u64) => {
__serialize_unimplemented_method!(serialize_u64(u64) -> Ok);
};
(f32) => {
__serialize_unimplemented_method!(serialize_f32(f32) -> Ok);
};
(f64) => {
__serialize_unimplemented_method!(serialize_f64(f64) -> Ok);
};
(char) => {
__serialize_unimplemented_method!(serialize_char(char) -> Ok);
};
(str) => {
__serialize_unimplemented_method!(serialize_str(&str) -> Ok);
};
(bytes) => {
__serialize_unimplemented_method!(serialize_bytes(&[u8]) -> Ok);
};
(none) => {
__serialize_unimplemented_method!(serialize_none() -> Ok);
};
(some) => {
__serialize_unimplemented_method!(serialize_some<T>(&T) -> Ok);
};
(unit) => {
__serialize_unimplemented_method!(serialize_unit() -> Ok);
};
(unit_struct) => {
__serialize_unimplemented_method!(serialize_unit_struct(&str) -> Ok);
};
(unit_variant) => {
__serialize_unimplemented_method!(serialize_unit_variant(&str, u32, &str) -> Ok);
};
(newtype_struct) => {
__serialize_unimplemented_method!(serialize_newtype_struct<T>(&str, &T) -> Ok);
};
(newtype_variant) => {
__serialize_unimplemented_method!(serialize_newtype_variant<T>(&str, u32, &str, &T) -> Ok);
};
(seq) => {
type SerializeSeq = $crate::ser::Impossible<Self::Ok, Self::Error>;
__serialize_unimplemented_method!(serialize_seq(Option<usize>) -> SerializeSeq);
};
(tuple) => {
type SerializeTuple = $crate::ser::Impossible<Self::Ok, Self::Error>;
__serialize_unimplemented_method!(serialize_tuple(usize) -> SerializeTuple);
};
(tuple_struct) => {
type SerializeTupleStruct = $crate::ser::Impossible<Self::Ok, Self::Error>;
__serialize_unimplemented_method!(serialize_tuple_struct(&str, usize) -> SerializeTupleStruct);
};
(tuple_variant) => {
type SerializeTupleVariant = $crate::ser::Impossible<Self::Ok, Self::Error>;
__serialize_unimplemented_method!(serialize_tuple_variant(&str, u32, &str, usize) -> SerializeTupleVariant);
};
(map) => {
type SerializeMap = $crate::ser::Impossible<Self::Ok, Self::Error>;
__serialize_unimplemented_method!(serialize_map(Option<usize>) -> SerializeMap);
};
(struct) => {
type SerializeStruct = $crate::ser::Impossible<Self::Ok, Self::Error>;
__serialize_unimplemented_method!(serialize_struct(&str, usize) -> SerializeStruct);
};
(struct_variant) => {
type SerializeStructVariant = $crate::ser::Impossible<Self::Ok, Self::Error>;
__serialize_unimplemented_method!(serialize_struct_variant(&str, u32, &str, usize) -> SerializeStructVariant);
};
}

View File

@ -0,0 +1,12 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
mod macros;
pub mod ser;
pub mod de;

1019
third_party/rust/serde/src/private/ser.rs vendored Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,14 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! This module contains `Impossible` serializer and its implementations.
use core::marker::PhantomData;
use lib::*;
use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct,
SerializeTupleVariant, SerializeMap, SerializeStruct, SerializeStructVariant};
@ -9,11 +17,19 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct,
/// serializing one of the compound types.
///
/// This type cannot be instantiated, but implements every one of the traits
/// corresponding to the `Serializer` compound types: `SerializeSeq`,
/// `SerializeTuple`, `SerializeTupleStruct`, `SerializeTupleVariant`,
/// `SerializeMap`, `SerializeStruct`, and `SerializeStructVariant`.
/// corresponding to the [`Serializer`] compound types: [`SerializeSeq`],
/// [`SerializeTuple`], [`SerializeTupleStruct`], [`SerializeTupleVariant`],
/// [`SerializeMap`], [`SerializeStruct`], and [`SerializeStructVariant`].
///
/// ```rust,ignore
/// ```rust
/// # #[macro_use]
/// # extern crate serde;
/// #
/// # use serde::ser::{Serializer, Impossible};
/// # use serde::private::ser::Error;
/// #
/// # struct MySerializer;
/// #
/// impl Serializer for MySerializer {
/// type Ok = ();
/// type Error = Error;
@ -27,130 +43,185 @@ use ser::{self, Serialize, SerializeSeq, SerializeTuple, SerializeTupleStruct,
/// -> Result<Self::SerializeSeq, Error> {
/// // Given Impossible cannot be instantiated, the only
/// // thing we can do here is to return an error.
/// # stringify! {
/// Err(...)
/// # };
/// # unimplemented!()
/// }
///
/// /* other Serializer methods */
/// # __serialize_unimplemented! {
/// # bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str bytes none some
/// # unit unit_struct unit_variant newtype_struct newtype_variant
/// # tuple tuple_struct tuple_variant map struct struct_variant
/// # }
/// }
/// #
/// # fn main() {}
/// ```
pub struct Impossible<Ok, E> {
///
/// [`Serializer`]: trait.Serializer.html
/// [`SerializeSeq`]: trait.SerializeSeq.html
/// [`SerializeTuple`]: trait.SerializeTuple.html
/// [`SerializeTupleStruct`]: trait.SerializeTupleStruct.html
/// [`SerializeTupleVariant`]: trait.SerializeTupleVariant.html
/// [`SerializeMap`]: trait.SerializeMap.html
/// [`SerializeStruct`]: trait.SerializeStruct.html
/// [`SerializeStructVariant`]: trait.SerializeStructVariant.html
pub struct Impossible<Ok, Error> {
void: Void,
_marker: PhantomData<(Ok, E)>,
ok: PhantomData<Ok>,
error: PhantomData<Error>,
}
enum Void {}
impl<Ok, E> SerializeSeq for Impossible<Ok, E>
where E: ser::Error
impl<Ok, Error> SerializeSeq for Impossible<Ok, Error>
where
Error: ser::Error,
{
type Ok = Ok;
type Error = E;
type Error = Error;
fn serialize_element<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<(), E> {
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
let _ = value;
match self.void {}
}
fn end(self) -> Result<Ok, E> {
fn end(self) -> Result<Ok, Error> {
match self.void {}
}
}
impl<Ok, E> SerializeTuple for Impossible<Ok, E>
where E: ser::Error
impl<Ok, Error> SerializeTuple for Impossible<Ok, Error>
where
Error: ser::Error,
{
type Ok = Ok;
type Error = E;
type Error = Error;
fn serialize_element<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<(), E> {
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
let _ = value;
match self.void {}
}
fn end(self) -> Result<Ok, E> {
fn end(self) -> Result<Ok, Error> {
match self.void {}
}
}
impl<Ok, E> SerializeTupleStruct for Impossible<Ok, E>
where E: ser::Error
impl<Ok, Error> SerializeTupleStruct for Impossible<Ok, Error>
where
Error: ser::Error,
{
type Ok = Ok;
type Error = E;
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<(), E> {
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
let _ = value;
match self.void {}
}
fn end(self) -> Result<Ok, E> {
fn end(self) -> Result<Ok, Error> {
match self.void {}
}
}
impl<Ok, E> SerializeTupleVariant for Impossible<Ok, E>
where E: ser::Error
impl<Ok, Error> SerializeTupleVariant for Impossible<Ok, Error>
where
Error: ser::Error,
{
type Ok = Ok;
type Error = E;
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<(), E> {
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
let _ = value;
match self.void {}
}
fn end(self) -> Result<Ok, E> {
fn end(self) -> Result<Ok, Error> {
match self.void {}
}
}
impl<Ok, E> SerializeMap for Impossible<Ok, E>
where E: ser::Error
impl<Ok, Error> SerializeMap for Impossible<Ok, Error>
where
Error: ser::Error,
{
type Ok = Ok;
type Error = E;
type Error = Error;
fn serialize_key<T: ?Sized + Serialize>(&mut self, _key: &T) -> Result<(), E> {
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Error>
where
T: Serialize,
{
let _ = key;
match self.void {}
}
fn serialize_value<T: ?Sized + Serialize>(&mut self, _value: &T) -> Result<(), E> {
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
let _ = value;
match self.void {}
}
fn end(self) -> Result<Ok, E> {
fn end(self) -> Result<Ok, Error> {
match self.void {}
}
}
impl<Ok, E> SerializeStruct for Impossible<Ok, E>
where E: ser::Error
impl<Ok, Error> SerializeStruct for Impossible<Ok, Error>
where
Error: ser::Error,
{
type Ok = Ok;
type Error = E;
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self,
_key: &'static str,
_value: &T)
-> Result<(), E> {
fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
where
T: Serialize,
{
let _ = key;
let _ = value;
match self.void {}
}
fn end(self) -> Result<Ok, E> {
fn end(self) -> Result<Ok, Error> {
match self.void {}
}
}
impl<Ok, E> SerializeStructVariant for Impossible<Ok, E>
where E: ser::Error
impl<Ok, Error> SerializeStructVariant for Impossible<Ok, Error>
where
Error: ser::Error,
{
type Ok = Ok;
type Error = E;
type Error = Error;
fn serialize_field<T: ?Sized + Serialize>(&mut self,
_key: &'static str,
_value: &T)
-> Result<(), E> {
fn serialize_field<T: ?Sized>(&mut self, key: &'static str, value: &T) -> Result<(), Error>
where
T: Serialize,
{
let _ = key;
let _ = value;
match self.void {}
}
fn end(self) -> Result<Ok, E> {
fn end(self) -> Result<Ok, Error> {
match self.void {}
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855","Cargo.toml":"3d0bef0a6066959e98c522891995538e3461a2bf565bbd05f1653959dd50b4a0","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"eedee04bddb61e99bc816656bb3b8ae2fa50ff00045ecdb5212682f3592d9ab2","src/assert.rs":"2306e36e685be5168d5507b53b2fa233ed38fcbb97ab7c73c0d3492920bdbc04","src/de.rs":"02ea551a4331375e0dd03b957520f3651c4f0277a30ad320a5936e9436e72405","src/error.rs":"a56408b85724e369ddae5e49f4facf5ef47291259e6127f823f39a1d0f3e6436","src/lib.rs":"b812f98562b33d513aa553a22323791cee8b565d6ec95734d772154c04d0a71b","src/ser.rs":"a632caf0b3f9f630f1f9305d153f89aea7d18c6335729aa98bf20a8f421df46a","src/token.rs":"97427e2bed0367d1c53beaced4a86f4fbead7abd2302805b38c41b3a5c90ffd6"},"package":"7d8c8022e0ec862cc1e0b73306bcd327c10de1873d1ab57794f344a7630ad46a"}

0
third_party/rust/serde_test/.cargo-ok vendored Normal file
View File

22
third_party/rust/serde_test/Cargo.toml vendored Normal file
View File

@ -0,0 +1,22 @@
[package]
name = "serde_test"
version = "1.0.7" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "Token De/Serializer for testing De/Serialize implementations"
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde_test/"
keywords = ["serde", "serialization"]
readme = "README.md"
include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
[dependencies]
serde = { version = "1.0", path = "../serde" }
[dev-dependencies]
serde = { version = "1.0", path = "../serde", features = ["rc"] }
serde_derive = { version = "1.0", path = "../serde_derive" }
[badges]
travis-ci = { repository = "serde-rs/serde" }

View File

@ -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.

25
third_party/rust/serde_test/LICENSE-MIT vendored Normal file
View File

@ -0,0 +1,25 @@
Copyright (c) 2014 The Rust Project Developers
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.

81
third_party/rust/serde_test/README.md vendored Normal file
View File

@ -0,0 +1,81 @@
# Serde &emsp; [![Build Status]][travis] [![Latest Version]][crates.io]
[Build Status]: https://api.travis-ci.org/serde-rs/serde.svg?branch=master
[travis]: https://travis-ci.org/serde-rs/serde
[Latest Version]: https://img.shields.io/crates/v/serde.svg
[crates.io]: https://crates.io/crates/serde
**Serde is a framework for *ser*ializing and *de*serializing Rust data structures efficiently and generically.**
---
You may be looking for:
- [An overview of Serde](https://serde.rs/)
- [Data formats supported by Serde](https://serde.rs/#data-formats)
- [Setting up `#[derive(Serialize, Deserialize)]`](https://serde.rs/codegen.html)
- [Examples](https://serde.rs/examples.html)
- [API documentation](https://docs.serde.rs/serde/)
- [Release notes](https://github.com/serde-rs/serde/releases)
## Serde in action
<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">
<img align="right" width="50" src="https://raw.githubusercontent.com/serde-rs/serde-rs.github.io/master/img/run.png">
</a>
```rust
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
#[derive(Serialize, Deserialize, Debug)]
struct Point {
x: i32,
y: i32,
}
fn main() {
let point = Point { x: 1, y: 2 };
// Convert the Point to a JSON string.
let serialized = serde_json::to_string(&point).unwrap();
// Prints serialized = {"x":1,"y":2}
println!("serialized = {}", serialized);
// Convert the JSON string back to a Point.
let deserialized: Point = serde_json::from_str(&serialized).unwrap();
// Prints deserialized = Point { x: 1, y: 2 }
println!("deserialized = {:?}", deserialized);
}
```
## Getting help
Serde developers live in the #serde channel on
[`irc.mozilla.org`](https://wiki.mozilla.org/IRC). The #rust channel is also a
good resource with generally faster response time but less specific knowledge
about Serde. If IRC is not your thing or you don't get a good response, we are
happy to respond to [GitHub issues](https://github.com/serde-rs/serde/issues/new)
as well.
## License
Serde is 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 Serde by you, as defined in the Apache-2.0 license, shall be
dual licensed as above, without any additional terms or conditions.

View File

@ -0,0 +1,241 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::{Serialize, Deserialize};
use de::Deserializer;
use ser::Serializer;
use token::Token;
use std::fmt::Debug;
/// Runs both `assert_ser_tokens` and `assert_de_tokens`.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct S {
/// a: u8,
/// b: u8,
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_tokens(&s, &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ]);
/// # }
/// ```
pub fn assert_tokens<'de, T>(value: &T, tokens: &'de [Token])
where
T: Serialize + Deserialize<'de> + PartialEq + Debug,
{
assert_ser_tokens(value, tokens);
assert_de_tokens(value, tokens);
}
/// Asserts that `value` serializes to the given `tokens`.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_ser_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct S {
/// a: u8,
/// b: u8,
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_ser_tokens(&s, &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ]);
/// # }
/// ```
pub fn assert_ser_tokens<T>(value: &T, tokens: &[Token])
where
T: Serialize,
{
let mut ser = Serializer::new(tokens);
match value.serialize(&mut ser) {
Ok(_) => {}
Err(err) => panic!("value failed to serialize: {}", err),
}
if ser.remaining() > 0 {
panic!("{} remaining tokens", ser.remaining());
}
}
/// Asserts that `value` serializes to the given `tokens`, and then yields `error`.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde_test;
/// #
/// # fn main() {
/// use std::sync::{Arc, Mutex};
/// use std::thread;
///
/// use serde_test::{assert_ser_tokens_error, Token};
///
/// #[derive(Serialize)]
/// struct Example {
/// lock: Arc<Mutex<u32>>,
/// }
///
/// let example = Example { lock: Arc::new(Mutex::new(0)) };
/// let lock = example.lock.clone();
///
/// let _ = thread::spawn(move || {
/// // This thread will acquire the mutex first, unwrapping the result
/// // of `lock` because the lock has not been poisoned.
/// let _guard = lock.lock().unwrap();
///
/// // This panic while holding the lock (`_guard` is in scope) will
/// // poison the mutex.
/// panic!()
/// }).join();
///
/// let expected = &[
/// Token::Struct { name: "Example", len: 1 },
/// Token::Str("lock"),
/// ];
/// let error = "lock poison error while serializing";
/// assert_ser_tokens_error(&example, expected, error);
/// # }
/// ```
pub fn assert_ser_tokens_error<T>(value: &T, tokens: &[Token], error: &str)
where
T: Serialize,
{
let mut ser = Serializer::new(tokens);
match value.serialize(&mut ser) {
Ok(_) => panic!("value serialized successfully"),
Err(e) => assert_eq!(e, *error),
}
if ser.remaining() > 0 {
panic!("{} remaining tokens", ser.remaining());
}
}
/// Asserts that the given `tokens` deserialize into `value`.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_de_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct S {
/// a: u8,
/// b: u8,
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_de_tokens(&s, &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ]);
/// # }
/// ```
pub fn assert_de_tokens<'de, T>(value: &T, tokens: &'de [Token])
where
T: Deserialize<'de> + PartialEq + Debug,
{
let mut de = Deserializer::new(tokens);
match T::deserialize(&mut de) {
Ok(v) => assert_eq!(v, *value),
Err(e) => panic!("tokens failed to deserialize: {}", e),
}
if de.remaining() > 0 {
panic!("{} remaining tokens", de.remaining());
}
}
/// Asserts that the given `tokens` yield `error` when deserializing.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_de_tokens_error, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// #[serde(deny_unknown_fields)]
/// struct S {
/// a: u8,
/// b: u8,
/// }
///
/// assert_de_tokens_error::<S>(
/// &[
/// Token::Struct { name: "S", len: 1 },
/// Token::Str("x"),
/// ],
/// "unknown field `x`, expected `a` or `b`",
/// );
/// # }
/// ```
pub fn assert_de_tokens_error<'de, T>(tokens: &'de [Token], error: &str)
where
T: Deserialize<'de>,
{
let mut de = Deserializer::new(tokens);
match T::deserialize(&mut de) {
Ok(_) => panic!("tokens deserialized successfully"),
Err(e) => assert_eq!(e, *error),
}
// There may be one token left if a peek caused the error
de.next_token_opt();
if de.remaining() > 0 {
panic!("{} remaining tokens", de.remaining());
}
}

641
third_party/rust/serde_test/src/de.rs vendored Normal file
View File

@ -0,0 +1,641 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::de::{self, Deserialize, DeserializeSeed, EnumAccess, IntoDeserializer, MapAccess,
SeqAccess, VariantAccess, Visitor};
use serde::de::value::{MapAccessDeserializer, SeqAccessDeserializer};
use error::Error;
use token::Token;
#[derive(Debug)]
pub struct Deserializer<'de> {
tokens: &'de [Token],
}
macro_rules! assert_next_token {
($de:expr, $expected:expr) => {
match $de.next_token_opt() {
Some(token) if token == $expected => {}
Some(other) => {
panic!("expected Token::{} but deserialization wants Token::{}",
other, $expected)
}
None => {
panic!("end of tokens but deserialization wants Token::{}",
$expected)
}
}
}
}
macro_rules! unexpected {
($token:expr) => {
panic!("deserialization did not expect this token: {}", $token)
}
}
macro_rules! end_of_tokens {
() => {
panic!("ran out of tokens to deserialize")
}
}
impl<'de> Deserializer<'de> {
pub fn new(tokens: &'de [Token]) -> Self {
Deserializer { tokens: tokens }
}
fn peek_token_opt(&self) -> Option<Token> {
self.tokens.first().cloned()
}
fn peek_token(&self) -> Token {
match self.peek_token_opt() {
Some(token) => token,
None => end_of_tokens!(),
}
}
pub fn next_token_opt(&mut self) -> Option<Token> {
match self.tokens.split_first() {
Some((&first, rest)) => {
self.tokens = rest;
Some(first)
}
None => None,
}
}
fn next_token(&mut self) -> Token {
match self.tokens.split_first() {
Some((&first, rest)) => {
self.tokens = rest;
first
}
None => end_of_tokens!(),
}
}
pub fn remaining(&self) -> usize {
self.tokens.len()
}
fn visit_seq<V>(
&mut self,
len: Option<usize>,
end: Token,
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
let value = try!(
visitor.visit_seq(
DeserializerSeqVisitor {
de: self,
len: len,
end: end.clone(),
},
)
);
assert_next_token!(self, end);
Ok(value)
}
fn visit_map<V>(
&mut self,
len: Option<usize>,
end: Token,
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
let value = try!(
visitor.visit_map(
DeserializerMapVisitor {
de: self,
len: len,
end: end.clone(),
},
)
);
assert_next_token!(self, end);
Ok(value)
}
}
impl<'de, 'a> de::Deserializer<'de> for &'a mut Deserializer<'de> {
type Error = Error;
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf unit seq map identifier ignored_any
}
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
let token = self.next_token();
match token {
Token::Bool(v) => visitor.visit_bool(v),
Token::I8(v) => visitor.visit_i8(v),
Token::I16(v) => visitor.visit_i16(v),
Token::I32(v) => visitor.visit_i32(v),
Token::I64(v) => visitor.visit_i64(v),
Token::U8(v) => visitor.visit_u8(v),
Token::U16(v) => visitor.visit_u16(v),
Token::U32(v) => visitor.visit_u32(v),
Token::U64(v) => visitor.visit_u64(v),
Token::F32(v) => visitor.visit_f32(v),
Token::F64(v) => visitor.visit_f64(v),
Token::Char(v) => visitor.visit_char(v),
Token::Str(v) => visitor.visit_str(v),
Token::BorrowedStr(v) => visitor.visit_borrowed_str(v),
Token::String(v) => visitor.visit_string(v.to_owned()),
Token::Bytes(v) => visitor.visit_bytes(v),
Token::BorrowedBytes(v) => visitor.visit_borrowed_bytes(v),
Token::ByteBuf(v) => visitor.visit_byte_buf(v.to_vec()),
Token::None => visitor.visit_none(),
Token::Some => visitor.visit_some(self),
Token::Unit => visitor.visit_unit(),
Token::UnitStruct { name: _ } => visitor.visit_unit(),
Token::NewtypeStruct { name: _ } => visitor.visit_newtype_struct(self),
Token::Seq { len } => self.visit_seq(len, Token::SeqEnd, visitor),
Token::Tuple { len } => self.visit_seq(Some(len), Token::TupleEnd, visitor),
Token::TupleStruct { name: _, len } => self.visit_seq(Some(len), Token::TupleStructEnd, visitor),
Token::Map { len } => self.visit_map(len, Token::MapEnd, visitor),
Token::Struct { name: _, len } => self.visit_map(Some(len), Token::StructEnd, visitor),
Token::Enum { name: _ } => {
let variant = self.next_token();
let next = self.peek_token();
match (variant, next) {
(Token::Str(variant), Token::Unit) => {
self.next_token();
visitor.visit_str(variant)
}
(Token::Bytes(variant), Token::Unit) => {
self.next_token();
visitor.visit_bytes(variant)
}
(Token::U32(variant), Token::Unit) => {
self.next_token();
visitor.visit_u32(variant)
}
(variant, Token::Unit) => unexpected!(variant),
(variant, _) => {
visitor.visit_map(EnumMapVisitor::new(self, variant, EnumFormat::Any))
}
}
}
Token::UnitVariant { name: _, variant } => visitor.visit_str(variant),
Token::NewtypeVariant { name: _, variant } => {
visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Any),)
}
Token::TupleVariant { name: _, variant, len: _ } => {
visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Seq),)
}
Token::StructVariant { name: _, variant, len: _ } => {
visitor.visit_map(EnumMapVisitor::new(self, Token::Str(variant), EnumFormat::Map),)
}
Token::SeqEnd | Token::TupleEnd | Token::TupleStructEnd | Token::MapEnd |
Token::StructEnd | Token::TupleVariantEnd | Token::StructVariantEnd => {
unexpected!(token);
}
}
}
fn deserialize_option<V>(self, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.peek_token() {
Token::Unit |
Token::None => {
self.next_token();
visitor.visit_none()
}
Token::Some => {
self.next_token();
visitor.visit_some(self)
}
_ => self.deserialize_any(visitor),
}
}
fn deserialize_enum<V>(
self,
name: &'static str,
_variants: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.peek_token() {
Token::Enum { name: n } if name == n => {
self.next_token();
visitor.visit_enum(DeserializerEnumVisitor { de: self })
}
Token::UnitVariant { name: n, variant: _ } |
Token::NewtypeVariant { name: n, variant: _ } |
Token::TupleVariant { name: n, variant: _, len: _ } |
Token::StructVariant { name: n, variant: _, len: _ } if name == n => {
visitor.visit_enum(DeserializerEnumVisitor { de: self })
}
_ => {
unexpected!(self.next_token());
}
}
}
fn deserialize_unit_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.peek_token() {
Token::UnitStruct { name: _ } => {
assert_next_token!(self, Token::UnitStruct { name: name });
visitor.visit_unit()
}
_ => self.deserialize_any(visitor),
}
}
fn deserialize_newtype_struct<V>(self, name: &'static str, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.peek_token() {
Token::NewtypeStruct { name: _ } => {
assert_next_token!(self, Token::NewtypeStruct { name: name });
visitor.visit_newtype_struct(self)
}
_ => self.deserialize_any(visitor),
}
}
fn deserialize_tuple<V>(self, len: usize, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.peek_token() {
Token::Unit |
Token::UnitStruct { name: _ } => {
self.next_token();
visitor.visit_unit()
}
Token::Seq { len: _ } => {
self.next_token();
self.visit_seq(Some(len), Token::SeqEnd, visitor)
}
Token::Tuple { len: _ } => {
self.next_token();
self.visit_seq(Some(len), Token::TupleEnd, visitor)
}
Token::TupleStruct { name: _, len: _ } => {
self.next_token();
self.visit_seq(Some(len), Token::TupleStructEnd, visitor)
}
_ => self.deserialize_any(visitor),
}
}
fn deserialize_tuple_struct<V>(
self,
name: &'static str,
len: usize,
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.peek_token() {
Token::Unit => {
self.next_token();
visitor.visit_unit()
}
Token::UnitStruct { name: _ } => {
assert_next_token!(self, Token::UnitStruct { name: name });
visitor.visit_unit()
}
Token::Seq { len: _ } => {
self.next_token();
self.visit_seq(Some(len), Token::SeqEnd, visitor)
}
Token::Tuple { len: _ } => {
self.next_token();
self.visit_seq(Some(len), Token::TupleEnd, visitor)
}
Token::TupleStruct { name: _, len: n } => {
assert_next_token!(self, Token::TupleStruct { name: name, len: n });
self.visit_seq(Some(len), Token::TupleStructEnd, visitor)
}
_ => self.deserialize_any(visitor),
}
}
fn deserialize_struct<V>(
self,
name: &'static str,
fields: &'static [&'static str],
visitor: V,
) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.peek_token() {
Token::Struct { name: _, len: n } => {
assert_next_token!(self, Token::Struct { name: name, len: n });
self.visit_map(Some(fields.len()), Token::StructEnd, visitor)
}
Token::Map { len: _ } => {
self.next_token();
self.visit_map(Some(fields.len()), Token::MapEnd, visitor)
}
_ => self.deserialize_any(visitor),
}
}
}
//////////////////////////////////////////////////////////////////////////
struct DeserializerSeqVisitor<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
len: Option<usize>,
end: Token,
}
impl<'de, 'a> SeqAccess<'de> for DeserializerSeqVisitor<'a, 'de> {
type Error = Error;
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Error>
where
T: DeserializeSeed<'de>,
{
if self.de.peek_token_opt() == Some(self.end) {
return Ok(None);
}
self.len = self.len.map(|len| len.saturating_sub(1));
seed.deserialize(&mut *self.de).map(Some)
}
fn size_hint(&self) -> Option<usize> {
self.len
}
}
//////////////////////////////////////////////////////////////////////////
struct DeserializerMapVisitor<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
len: Option<usize>,
end: Token,
}
impl<'de, 'a> MapAccess<'de> for DeserializerMapVisitor<'a, 'de> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
where
K: DeserializeSeed<'de>,
{
if self.de.peek_token_opt() == Some(self.end) {
return Ok(None);
}
self.len = self.len.map(|len| len.saturating_sub(1));
seed.deserialize(&mut *self.de).map(Some)
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
where
V: DeserializeSeed<'de>,
{
seed.deserialize(&mut *self.de)
}
fn size_hint(&self) -> Option<usize> {
self.len
}
}
//////////////////////////////////////////////////////////////////////////
struct DeserializerEnumVisitor<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
}
impl<'de, 'a> EnumAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
type Error = Error;
type Variant = Self;
fn variant_seed<V>(self, seed: V) -> Result<(V::Value, Self), Error>
where
V: DeserializeSeed<'de>,
{
match self.de.peek_token() {
Token::UnitVariant { name: _, variant: v } |
Token::NewtypeVariant { name: _, variant: v } |
Token::TupleVariant { name: _, variant: v, len: _ } |
Token::StructVariant { name: _, variant: v, len: _ } => {
let de = v.into_deserializer();
let value = try!(seed.deserialize(de));
Ok((value, self))
}
_ => {
let value = try!(seed.deserialize(&mut *self.de));
Ok((value, self))
}
}
}
}
impl<'de, 'a> VariantAccess<'de> for DeserializerEnumVisitor<'a, 'de> {
type Error = Error;
fn unit_variant(self) -> Result<(), Error> {
match self.de.peek_token() {
Token::UnitVariant { name: _, variant: _ } => {
self.de.next_token();
Ok(())
}
_ => Deserialize::deserialize(self.de),
}
}
fn newtype_variant_seed<T>(self, seed: T) -> Result<T::Value, Self::Error>
where
T: DeserializeSeed<'de>,
{
match self.de.peek_token() {
Token::NewtypeVariant { name: _, variant: _ } => {
self.de.next_token();
seed.deserialize(self.de)
}
_ => seed.deserialize(self.de),
}
}
fn tuple_variant<V>(self, len: usize, visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.de.peek_token() {
Token::TupleVariant { name: _, variant: _, len: enum_len } => {
let token = self.de.next_token();
if len == enum_len {
self.de
.visit_seq(Some(len), Token::TupleVariantEnd, visitor)
} else {
unexpected!(token);
}
}
Token::Seq { len: Some(enum_len) } => {
let token = self.de.next_token();
if len == enum_len {
self.de.visit_seq(Some(len), Token::SeqEnd, visitor)
} else {
unexpected!(token);
}
}
_ => de::Deserializer::deserialize_any(self.de, visitor),
}
}
fn struct_variant<V>(self, fields: &'static [&'static str], visitor: V) -> Result<V::Value, Error>
where
V: Visitor<'de>,
{
match self.de.peek_token() {
Token::StructVariant { name: _, variant: _, len: enum_len } => {
let token = self.de.next_token();
if fields.len() == enum_len {
self.de
.visit_map(Some(fields.len()), Token::StructVariantEnd, visitor)
} else {
unexpected!(token);
}
}
Token::Map { len: Some(enum_len) } => {
let token = self.de.next_token();
if fields.len() == enum_len {
self.de
.visit_map(Some(fields.len()), Token::MapEnd, visitor)
} else {
unexpected!(token);
}
}
_ => de::Deserializer::deserialize_any(self.de, visitor),
}
}
}
//////////////////////////////////////////////////////////////////////////
struct EnumMapVisitor<'a, 'de: 'a> {
de: &'a mut Deserializer<'de>,
variant: Option<Token>,
format: EnumFormat,
}
enum EnumFormat {
Seq,
Map,
Any,
}
impl<'a, 'de> EnumMapVisitor<'a, 'de> {
fn new(de: &'a mut Deserializer<'de>, variant: Token, format: EnumFormat) -> Self {
EnumMapVisitor {
de: de,
variant: Some(variant),
format: format,
}
}
}
impl<'de, 'a> MapAccess<'de> for EnumMapVisitor<'a, 'de> {
type Error = Error;
fn next_key_seed<K>(&mut self, seed: K) -> Result<Option<K::Value>, Error>
where
K: DeserializeSeed<'de>,
{
match self.variant.take() {
Some(Token::Str(variant)) => seed.deserialize(variant.into_deserializer()).map(Some),
Some(Token::Bytes(variant)) => {
seed.deserialize(BytesDeserializer { value: variant })
.map(Some)
}
Some(Token::U32(variant)) => seed.deserialize(variant.into_deserializer()).map(Some),
Some(other) => unexpected!(other),
None => Ok(None),
}
}
fn next_value_seed<V>(&mut self, seed: V) -> Result<V::Value, Error>
where
V: DeserializeSeed<'de>,
{
match self.format {
EnumFormat::Seq => {
let value = {
let visitor = DeserializerSeqVisitor {
de: self.de,
len: None,
end: Token::TupleVariantEnd,
};
try!(seed.deserialize(SeqAccessDeserializer::new(visitor)))
};
assert_next_token!(self.de, Token::TupleVariantEnd);
Ok(value)
}
EnumFormat::Map => {
let value = {
let visitor = DeserializerMapVisitor {
de: self.de,
len: None,
end: Token::StructVariantEnd,
};
try!(seed.deserialize(MapAccessDeserializer::new(visitor)))
};
assert_next_token!(self.de, Token::StructVariantEnd);
Ok(value)
}
EnumFormat::Any => seed.deserialize(&mut *self.de),
}
}
}
struct BytesDeserializer {
value: &'static [u8],
}
impl<'de> de::Deserializer<'de> for BytesDeserializer {
type Error = Error;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
visitor.visit_bytes(self.value)
}
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
byte_buf option unit unit_struct newtype_struct seq tuple tuple_struct
map struct enum identifier ignored_any
}
}

View File

@ -0,0 +1,47 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::error;
use std::fmt::{self, Display};
use serde::{ser, de};
#[derive(Clone, Debug)]
pub struct Error {
msg: String,
}
impl ser::Error for Error {
fn custom<T: Display>(msg: T) -> Error {
Error { msg: msg.to_string() }
}
}
impl de::Error for Error {
fn custom<T: Display>(msg: T) -> Error {
Error { msg: msg.to_string() }
}
}
impl fmt::Display for Error {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str(&self.msg)
}
}
impl error::Error for Error {
fn description(&self) -> &str {
&self.msg
}
}
impl PartialEq<str> for Error {
fn eq(&self, other: &str) -> bool {
self.msg == other
}
}

176
third_party/rust/serde_test/src/lib.rs vendored Normal file
View File

@ -0,0 +1,176 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! This crate provides a convenient concise way to write unit tests for
//! implementations of [`Serialize`] and [`Deserialize`].
//!
//! [`Serialize`]: https://docs.serde.rs/serde/ser/trait.Serialize.html
//! [`Deserialize`]: https://docs.serde.rs/serde/de/trait.Deserialize.html
//!
//! The `Serialize` impl for a value can be characterized by the sequence of
//! [`Serializer`] calls that are made in the course of serializing the value,
//! so `serde_test` provides a [`Token`] abstraction which corresponds roughly
//! to `Serializer` method calls. There is an [`assert_ser_tokens`] function to
//! test that a value serializes to a particular sequence of method calls, an
//! [`assert_de_tokens`] function to test that a value can be deserialized from
//! a particular sequence of method calls, and an [`assert_tokens`] function to
//! test both directions. There are also functions to test expected failure
//! conditions.
//!
//! [`Serializer`]: https://docs.serde.rs/serde/ser/trait.Serializer.html
//! [`Token`]: https://docs.serde.rs/serde_test/enum.Token.html
//! [`assert_ser_tokens`]: https://docs.serde.rs/serde_test/fn.assert_ser_tokens.html
//! [`assert_de_tokens`]: https://docs.serde.rs/serde_test/fn.assert_de_tokens.html
//! [`assert_tokens`]: https://docs.serde.rs/serde_test/fn.assert_tokens.html
//!
//! Here is an example from the [`linked-hash-map`] crate.
//!
//! [`linked-hash-map`]: https://github.com/contain-rs/linked-hash-map
//!
//! ```rust
//! # extern crate serde;
//! #
//! # macro_rules! ignore {
//! # ($($tt:tt)+) => {}
//! # }
//! #
//! # ignore! {
//! extern crate linked_hash_map;
//! use linked_hash_map::LinkedHashMap;
//! # }
//!
//! extern crate serde_test;
//! use serde_test::{Token, assert_tokens};
//!
//! # use std::fmt;
//! # use std::marker::PhantomData;
//! #
//! # use serde::ser::{Serialize, Serializer, SerializeMap};
//! # use serde::de::{Deserialize, Deserializer, Visitor, MapAccess};
//! #
//! # // Dumb immitation of LinkedHashMap.
//! # #[derive(PartialEq, Debug)]
//! # struct LinkedHashMap<K, V>(Vec<(K, V)>);
//! #
//! # impl<K, V> LinkedHashMap<K, V> {
//! # fn new() -> Self {
//! # LinkedHashMap(Vec::new())
//! # }
//! #
//! # fn insert(&mut self, k: K, v: V) {
//! # self.0.push((k, v));
//! # }
//! # }
//! #
//! # impl<K, V> Serialize for LinkedHashMap<K, V>
//! # where K: Serialize,
//! # V: Serialize
//! # {
//! # fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
//! # where S: Serializer
//! # {
//! # let mut map = serializer.serialize_map(Some(self.0.len()))?;
//! # for &(ref k, ref v) in &self.0 {
//! # map.serialize_entry(k, v)?;
//! # }
//! # map.end()
//! # }
//! # }
//! #
//! # struct LinkedHashMapVisitor<K, V>(PhantomData<(K, V)>);
//! #
//! # impl<'de, K, V> Visitor<'de> for LinkedHashMapVisitor<K, V>
//! # where K: Deserialize<'de>,
//! # V: Deserialize<'de>
//! # {
//! # type Value = LinkedHashMap<K, V>;
//! #
//! # fn expecting(&self, _: &mut fmt::Formatter) -> fmt::Result {
//! # unimplemented!()
//! # }
//! #
//! # fn visit_map<M>(self, mut access: M) -> Result<Self::Value, M::Error>
//! # where M: MapAccess<'de>
//! # {
//! # let mut map = LinkedHashMap::new();
//! # while let Some((key, value)) = access.next_entry()? {
//! # map.insert(key, value);
//! # }
//! # Ok(map)
//! # }
//! # }
//! #
//! # impl<'de, K, V> Deserialize<'de> for LinkedHashMap<K, V>
//! # where K: Deserialize<'de>,
//! # V: Deserialize<'de>
//! # {
//! # fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
//! # where D: Deserializer<'de>
//! # {
//! # deserializer.deserialize_map(LinkedHashMapVisitor(PhantomData))
//! # }
//! # }
//! #
//! #[test]
//! # fn not_a_test_ser_de_empty() {}
//! fn test_ser_de_empty() {
//! let map = LinkedHashMap::<char, u32>::new();
//!
//! assert_tokens(&map, &[
//! Token::Map { len: Some(0) },
//! Token::MapEnd,
//! ]);
//! }
//!
//! #[test]
//! # fn not_a_test_ser_de() {}
//! fn test_ser_de() {
//! let mut map = LinkedHashMap::new();
//! map.insert('b', 20);
//! map.insert('a', 10);
//! map.insert('c', 30);
//!
//! assert_tokens(&map, &[
//! Token::Map { len: Some(3) },
//! Token::Char('b'),
//! Token::I32(20),
//!
//! Token::Char('a'),
//! Token::I32(10),
//!
//! Token::Char('c'),
//! Token::I32(30),
//! Token::MapEnd,
//! ]);
//! }
//! #
//! # fn main() {
//! # test_ser_de_empty();
//! # test_ser_de();
//! # }
//! ```
#![doc(html_root_url = "https://docs.rs/serde_test/1.0.7")]
#[macro_use]
extern crate serde;
mod ser;
mod de;
mod error;
mod token;
mod assert;
pub use token::Token;
pub use assert::{assert_tokens, assert_ser_tokens, assert_ser_tokens_error, assert_de_tokens,
assert_de_tokens_error};
// Not public API.
#[doc(hidden)]
pub use de::Deserializer;

434
third_party/rust/serde_test/src/ser.rs vendored Normal file
View File

@ -0,0 +1,434 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use serde::{ser, Serialize};
use error::Error;
use token::Token;
/// A `Serializer` that ensures that a value serializes to a given list of tokens.
#[derive(Debug)]
pub struct Serializer<'a> {
tokens: &'a [Token],
}
impl<'a> Serializer<'a> {
/// Creates the serializer.
pub fn new(tokens: &'a [Token]) -> Self {
Serializer { tokens: tokens }
}
/// Pulls the next token off of the serializer, ignoring it.
fn next_token(&mut self) -> Option<Token> {
if let Some((&first, rest)) = self.tokens.split_first() {
self.tokens = rest;
Some(first)
} else {
None
}
}
pub fn remaining(&self) -> usize {
self.tokens.len()
}
}
macro_rules! assert_next_token {
($ser:expr, $expected:ident) => {
assert_next_token!($ser, $expected, Token::$expected, true);
};
($ser:expr, $expected:ident($v:expr)) => {
assert_next_token!($ser, $expected, Token::$expected(v), v == $v);
};
($ser:expr, $expected:ident { $($k:ident),* }) => {
let compare = ($($k,)*);
assert_next_token!($ser, $expected, Token::$expected { $($k),* }, ($($k,)*) == compare);
};
($ser:expr, $expected:ident, $pat:pat, $guard:expr) => {
match $ser.next_token() {
Some($pat) if $guard => {}
Some(other) => {
panic!("expected Token::{} but serialized as {}",
stringify!($expected), other);
}
None => {
panic!("expected Token::{} after end of serialized tokens",
stringify!($expected));
}
}
};
}
impl<'s, 'a> ser::Serializer for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
type SerializeSeq = Self;
type SerializeTuple = Self;
type SerializeTupleStruct = Self;
type SerializeTupleVariant = Variant<'s, 'a>;
type SerializeMap = Self;
type SerializeStruct = Self;
type SerializeStructVariant = Variant<'s, 'a>;
fn serialize_bool(self, v: bool) -> Result<(), Error> {
assert_next_token!(self, Bool(v));
Ok(())
}
fn serialize_i8(self, v: i8) -> Result<(), Error> {
assert_next_token!(self, I8(v));
Ok(())
}
fn serialize_i16(self, v: i16) -> Result<(), Error> {
assert_next_token!(self, I16(v));
Ok(())
}
fn serialize_i32(self, v: i32) -> Result<(), Error> {
assert_next_token!(self, I32(v));
Ok(())
}
fn serialize_i64(self, v: i64) -> Result<(), Error> {
assert_next_token!(self, I64(v));
Ok(())
}
fn serialize_u8(self, v: u8) -> Result<(), Error> {
assert_next_token!(self, U8(v));
Ok(())
}
fn serialize_u16(self, v: u16) -> Result<(), Error> {
assert_next_token!(self, U16(v));
Ok(())
}
fn serialize_u32(self, v: u32) -> Result<(), Error> {
assert_next_token!(self, U32(v));
Ok(())
}
fn serialize_u64(self, v: u64) -> Result<(), Error> {
assert_next_token!(self, U64(v));
Ok(())
}
fn serialize_f32(self, v: f32) -> Result<(), Error> {
assert_next_token!(self, F32(v));
Ok(())
}
fn serialize_f64(self, v: f64) -> Result<(), Error> {
assert_next_token!(self, F64(v));
Ok(())
}
fn serialize_char(self, v: char) -> Result<(), Error> {
assert_next_token!(self, Char(v));
Ok(())
}
fn serialize_str(self, v: &str) -> Result<(), Error> {
match self.tokens.first() {
Some(&Token::BorrowedStr(_)) => assert_next_token!(self, BorrowedStr(v)),
Some(&Token::String(_)) => assert_next_token!(self, String(v)),
_ => assert_next_token!(self, Str(v)),
}
Ok(())
}
fn serialize_bytes(self, v: &[u8]) -> Result<(), Self::Error> {
match self.tokens.first() {
Some(&Token::BorrowedBytes(_)) => assert_next_token!(self, BorrowedBytes(v)),
Some(&Token::ByteBuf(_)) => assert_next_token!(self, ByteBuf(v)),
_ => assert_next_token!(self, Bytes(v)),
}
Ok(())
}
fn serialize_unit(self) -> Result<(), Error> {
assert_next_token!(self, Unit);
Ok(())
}
fn serialize_unit_struct(self, name: &'static str) -> Result<(), Error> {
assert_next_token!(self, UnitStruct { name });
Ok(())
}
fn serialize_unit_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
) -> Result<(), Error> {
if self.tokens.first() == Some(&Token::Enum { name: name }) {
self.next_token();
assert_next_token!(self, Str(variant));
assert_next_token!(self, Unit);
} else {
assert_next_token!(self, UnitVariant { name, variant });
}
Ok(())
}
fn serialize_newtype_struct<T: ?Sized>(self, name: &'static str, value: &T) -> Result<(), Error>
where
T: Serialize,
{
assert_next_token!(self, NewtypeStruct { name });
value.serialize(self)
}
fn serialize_newtype_variant<T: ?Sized>(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
value: &T,
) -> Result<(), Error>
where
T: Serialize,
{
if self.tokens.first() == Some(&Token::Enum { name: name }) {
self.next_token();
assert_next_token!(self, Str(variant));
} else {
assert_next_token!(self, NewtypeVariant { name, variant });
}
value.serialize(self)
}
fn serialize_none(self) -> Result<(), Error> {
assert_next_token!(self, None);
Ok(())
}
fn serialize_some<T: ?Sized>(self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
assert_next_token!(self, Some);
value.serialize(self)
}
fn serialize_seq(self, len: Option<usize>) -> Result<Self, Error> {
assert_next_token!(self, Seq { len });
Ok(self)
}
fn serialize_tuple(self, len: usize) -> Result<Self, Error> {
assert_next_token!(self, Tuple { len });
Ok(self)
}
fn serialize_tuple_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
assert_next_token!(self, TupleStruct { name, len });
Ok(self)
}
fn serialize_tuple_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Error> {
if self.tokens.first() == Some(&Token::Enum { name: name }) {
self.next_token();
assert_next_token!(self, Str(variant));
let len = Some(len);
assert_next_token!(self, Seq { len });
Ok(Variant { ser: self, end: Token::SeqEnd })
} else {
assert_next_token!(self, TupleVariant { name, variant, len });
Ok(Variant { ser: self, end: Token::TupleVariantEnd })
}
}
fn serialize_map(self, len: Option<usize>) -> Result<Self, Error> {
assert_next_token!(self, Map { len });
Ok(self)
}
fn serialize_struct(self, name: &'static str, len: usize) -> Result<Self, Error> {
assert_next_token!(self, Struct { name, len });
Ok(self)
}
fn serialize_struct_variant(
self,
name: &'static str,
_variant_index: u32,
variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Error> {
if self.tokens.first() == Some(&Token::Enum { name: name }) {
self.next_token();
assert_next_token!(self, Str(variant));
let len = Some(len);
assert_next_token!(self, Map { len });
Ok(Variant { ser: self, end: Token::MapEnd })
} else {
assert_next_token!(self, StructVariant { name, variant, len });
Ok(Variant { ser: self, end: Token::StructVariantEnd })
}
}
}
pub struct Variant<'s, 'a: 's> {
ser: &'s mut Serializer<'a>,
end: Token,
}
impl<'s, 'a> ser::SerializeSeq for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Error> {
assert_next_token!(self, SeqEnd);
Ok(())
}
}
impl<'s, 'a> ser::SerializeTuple for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_element<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Error> {
assert_next_token!(self, TupleEnd);
Ok(())
}
}
impl<'s, 'a> ser::SerializeTupleStruct for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Error> {
assert_next_token!(self, TupleStructEnd);
Ok(())
}
}
impl<'s, 'a> ser::SerializeTupleVariant for Variant<'s, 'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(&mut self, value: &T) -> Result<(), Error>
where
T: Serialize,
{
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<(), Error> {
match self.end {
Token::TupleVariantEnd => assert_next_token!(self.ser, TupleVariantEnd),
Token::SeqEnd => assert_next_token!(self.ser, SeqEnd),
_ => unreachable!(),
}
Ok(())
}
}
impl<'s, 'a> ser::SerializeMap for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_key<T: ?Sized>(&mut self, key: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
key.serialize(&mut **self)
}
fn serialize_value<T: ?Sized>(&mut self, value: &T) -> Result<(), Self::Error>
where
T: Serialize,
{
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Self::Error> {
assert_next_token!(self, MapEnd);
Ok(())
}
}
impl<'s, 'a> ser::SerializeStruct for &'s mut Serializer<'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize,
{
try!(key.serialize(&mut **self));
value.serialize(&mut **self)
}
fn end(self) -> Result<(), Self::Error> {
assert_next_token!(self, StructEnd);
Ok(())
}
}
impl<'s, 'a> ser::SerializeStructVariant for Variant<'s, 'a> {
type Ok = ();
type Error = Error;
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize,
{
try!(key.serialize(&mut *self.ser));
value.serialize(&mut *self.ser)
}
fn end(self) -> Result<(), Self::Error> {
match self.end {
Token::StructVariantEnd => assert_next_token!(self.ser, StructVariantEnd),
Token::MapEnd => assert_next_token!(self.ser, MapEnd),
_ => unreachable!(),
}
Ok(())
}
}

558
third_party/rust/serde_test/src/token.rs vendored Normal file
View File

@ -0,0 +1,558 @@
// Copyright 2017 Serde Developers
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use std::fmt::{self, Debug, Display};
#[derive(Copy, Clone, PartialEq, Debug)]
pub enum Token {
/// A serialized `bool`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&true, &[Token::Bool(true)]);
/// ```
Bool(bool),
/// A serialized `i8`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i8, &[Token::I8(0)]);
/// ```
I8(i8),
/// A serialized `i16`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i16, &[Token::I16(0)]);
/// ```
I16(i16),
/// A serialized `i32`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i32, &[Token::I32(0)]);
/// ```
I32(i32),
/// A serialized `i64`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0i64, &[Token::I64(0)]);
/// ```
I64(i64),
/// A serialized `u8`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u8, &[Token::U8(0)]);
/// ```
U8(u8),
/// A serialized `u16`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u16, &[Token::U16(0)]);
/// ```
U16(u16),
/// A serialized `u32`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u32, &[Token::U32(0)]);
/// ```
U32(u32),
/// A serialized `u64`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0u64, &[Token::U64(0)]);
/// ```
U64(u64),
/// A serialized `f32`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0f32, &[Token::F32(0.0)]);
/// ```
F32(f32),
/// A serialized `f64`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&0f64, &[Token::F64(0.0)]);
/// ```
F64(f64),
/// A serialized `char`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&'\n', &[Token::Char('\n')]);
/// ```
Char(char),
/// A serialized `str`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// let s = String::from("transient");
/// assert_tokens(&s, &[Token::Str("transient")]);
/// ```
Str(&'static str),
/// A borrowed `str`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// let s: &str = "borrowed";
/// assert_tokens(&s, &[Token::BorrowedStr("borrowed")]);
/// ```
BorrowedStr(&'static str),
/// A serialized `String`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// let s = String::from("owned");
/// assert_tokens(&s, &[Token::String("owned")]);
/// ```
String(&'static str),
/// A serialized `[u8]`
Bytes(&'static [u8]),
/// A borrowed `[u8]`.
BorrowedBytes(&'static [u8]),
/// A serialized `ByteBuf`
ByteBuf(&'static [u8]),
/// A serialized `Option<T>` containing none.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// let opt = None::<char>;
/// assert_tokens(&opt, &[Token::None]);
/// ```
None,
/// The header to a serialized `Option<T>` containing some value.
///
/// The tokens of the value follow after this header.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// let opt = Some('c');
/// assert_tokens(&opt, &[
/// Token::Some,
/// Token::Char('c'),
/// ]);
/// ```
Some,
/// A serialized `()`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// assert_tokens(&(), &[Token::Unit]);
/// ```
Unit,
/// A serialized unit struct of the given name.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct X;
///
/// assert_tokens(&X, &[Token::UnitStruct { name: "X" }]);
/// # }
/// ```
UnitStruct { name: &'static str },
/// A unit variant of an enum.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// enum E {
/// A,
/// }
///
/// let a = E::A;
/// assert_tokens(&a, &[Token::UnitVariant { name: "E", variant: "A" }]);
/// # }
/// ```
UnitVariant { name: &'static str, variant: &'static str },
/// The header to a serialized newtype struct of the given name.
///
/// After this header is the value contained in the newtype struct.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct N(String);
///
/// let n = N("newtype".to_owned());
/// assert_tokens(&n, &[
/// Token::NewtypeStruct { name: "N" },
/// Token::String("newtype"),
/// ]);
/// # }
/// ```
NewtypeStruct { name: &'static str },
/// The header to a newtype variant of an enum.
///
/// After this header is the value contained in the newtype variant.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// enum E {
/// B(u8),
/// }
///
/// let b = E::B(0);
/// assert_tokens(&b, &[
/// Token::NewtypeVariant { name: "E", variant: "B" },
/// Token::U8(0),
/// ]);
/// # }
/// ```
NewtypeVariant { name: &'static str, variant: &'static str },
/// The header to a sequence.
///
/// After this header are the elements of the sequence, followed by
/// `SeqEnd`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// let vec = vec!['a', 'b', 'c'];
/// assert_tokens(&vec, &[
/// Token::Seq { len: Some(3) },
/// Token::Char('a'),
/// Token::Char('b'),
/// Token::Char('c'),
/// Token::SeqEnd,
/// ]);
/// ```
Seq { len: Option<usize> },
/// An indicator of the end of a sequence.
SeqEnd,
/// The header to a tuple.
///
/// After this header are the elements of the tuple, followed by `TupleEnd`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// let tuple = ('a', 100);
/// assert_tokens(&tuple, &[
/// Token::Tuple { len: 2 },
/// Token::Char('a'),
/// Token::I32(100),
/// Token::TupleEnd,
/// ]);
/// ```
Tuple { len: usize },
/// An indicator of the end of a tuple.
TupleEnd,
/// The header to a tuple struct.
///
/// After this header are the fields of the tuple struct, followed by
/// `TupleStructEnd`.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct T(u8, u8);
///
/// let t = T(0, 0);
/// assert_tokens(&t, &[
/// Token::TupleStruct { name: "T", len: 2 },
/// Token::U8(0),
/// Token::U8(0),
/// Token::TupleStructEnd,
/// ]);
/// # }
/// ```
TupleStruct { name: &'static str, len: usize },
/// An indicator of the end of a tuple struct.
TupleStructEnd,
/// The header to a tuple variant of an enum.
///
/// After this header are the fields of the tuple variant, followed by
/// `TupleVariantEnd`.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// enum E {
/// C(u8, u8),
/// }
///
/// let c = E::C(0, 0);
/// assert_tokens(&c, &[
/// Token::TupleVariant { name: "E", variant: "C", len: 2 },
/// Token::U8(0),
/// Token::U8(0),
/// Token::TupleVariantEnd,
/// ]);
/// # }
/// ```
TupleVariant { name: &'static str, variant: &'static str, len: usize },
/// An indicator of the end of a tuple variant.
TupleVariantEnd,
/// The header to a map.
///
/// After this header are the entries of the map, followed by `MapEnd`.
///
/// ```rust
/// # use serde_test::{assert_tokens, Token};
/// #
/// use std::collections::BTreeMap;
///
/// let mut map = BTreeMap::new();
/// map.insert('A', 65);
/// map.insert('Z', 90);
///
/// assert_tokens(&map, &[
/// Token::Map { len: Some(2) },
/// Token::Char('A'),
/// Token::I32(65),
/// Token::Char('Z'),
/// Token::I32(90),
/// Token::MapEnd,
/// ]);
/// ```
Map { len: Option<usize> },
/// An indicator of the end of a map.
MapEnd,
/// The header of a struct.
///
/// After this header are the fields of the struct, followed by `StructEnd`.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// struct S {
/// a: u8,
/// b: u8,
/// }
///
/// let s = S { a: 0, b: 0 };
/// assert_tokens(&s, &[
/// Token::Struct { name: "S", len: 2 },
/// Token::Str("a"),
/// Token::U8(0),
/// Token::Str("b"),
/// Token::U8(0),
/// Token::StructEnd,
/// ]);
/// # }
/// ```
Struct { name: &'static str, len: usize },
/// An indicator of the end of a struct.
StructEnd,
/// The header of a struct variant of an enum.
///
/// After this header are the fields of the struct variant, followed by
/// `StructVariantEnd`.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// enum E {
/// D { d: u8 },
/// }
///
/// let d = E::D { d: 0 };
/// assert_tokens(&d, &[
/// Token::StructVariant { name: "E", variant: "D", len: 1 },
/// Token::Str("d"),
/// Token::U8(0),
/// Token::StructVariantEnd,
/// ]);
/// # }
/// ```
StructVariant { name: &'static str, variant: &'static str, len: usize },
/// An indicator of the end of a struct variant.
StructVariantEnd,
/// The header to an enum of the given name.
///
/// ```rust
/// # #[macro_use]
/// # extern crate serde_derive;
/// #
/// # extern crate serde;
/// # extern crate serde_test;
/// #
/// # use serde_test::{assert_tokens, Token};
/// #
/// # fn main() {
/// #[derive(Serialize, Deserialize, PartialEq, Debug)]
/// enum E {
/// A,
/// B(u8),
/// C(u8, u8),
/// D { d: u8 },
/// }
///
/// let a = E::A;
/// assert_tokens(&a, &[
/// Token::Enum { name: "E" },
/// Token::Str("A"),
/// Token::Unit,
/// ]);
///
/// let b = E::B(0);
/// assert_tokens(&b, &[
/// Token::Enum { name: "E" },
/// Token::Str("B"),
/// Token::U8(0),
/// ]);
///
/// let c = E::C(0, 0);
/// assert_tokens(&c, &[
/// Token::Enum { name: "E" },
/// Token::Str("C"),
/// Token::Seq { len: Some(2) },
/// Token::U8(0),
/// Token::U8(0),
/// Token::SeqEnd,
/// ]);
///
/// let d = E::D { d: 0 };
/// assert_tokens(&d, &[
/// Token::Enum { name: "E" },
/// Token::Str("D"),
/// Token::Map { len: Some(1) },
/// Token::Str("d"),
/// Token::U8(0),
/// Token::MapEnd,
/// ]);
/// # }
/// ```
Enum { name: &'static str },
}
impl Display for Token {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
Debug::fmt(self, formatter)
}
}

View File

@ -0,0 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"ca9e613b65aadd1e89ff6bc5f76a1cd7989ca7441b4debfe1bde8c35cc165b59",".travis.yml":"5c3f9b92ab6ca79a98400b8c344f3a06fcc096b5df6f49fbae1a83dceb540170","AUTHORS":"6029da5a270f7047db642cfdaa521acdfd93dcae9f9cd02dc1bd43dfa526fc18","COPYRIGHT":"edb20b474f6cbd4f4db066b54a9e0f687d0009d309412a63431189b59b8e2a07","Cargo.toml":"4b649e28df32ff0d08dd5ab0dfffb62d96f2f81e85370f2112ecd4d7f800910a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"e764abd9a6abbe9517dd9dedc003dd64594351282437a509fec9362ef136686d","src/lib.rs":"ef549431c0da99908df0a91deaee977d658c54449ed4abe935d3b0ef01c0eb51","src/tables.rs":"a2bb982b051a0ce7b85ade1f755c5b89e7f0415cfa1cbb62beb118d7b29da587","tools/generate.py":"a7b4a0c097bea5e0c626a6d33cb862bf4c542e36ac837b99455535c4ab83da6d"},"package":"d3a078ebdd62c0e71a709c3d53d2af693fe09fe93fbff8344aebe289b78f9032"}

View File

View File

@ -0,0 +1,4 @@
Cargo.lock
target
src/ReadMe.txt
*.txt

View File

@ -0,0 +1,9 @@
sudo: false
language: rust
rust:
- nightly
- beta
- stable
notifications:
webhooks: http://build.servo.org:54856/travis

View File

@ -0,0 +1,3 @@
This software was written by the following people:
Matt Brubeck <mbrubeck@limpet.net>

View File

@ -0,0 +1,8 @@
This project is copyright 2015, The Servo Project Developers (given in the
file AUTHORS).
Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
http://www.apache.org/licenses/LICENSE-2.0> or the MIT license <LICENSE-MIT or
http://opensource.org/licenses/MIT>, at your option. All files in the project
carrying such notice may not be copied, modified, or distributed except
according to those terms.

View File

@ -0,0 +1,17 @@
[package]
name = "unicode-bidi"
version = "0.2.5"
authors = ["The Servo Project Developers"]
license = "MIT / Apache-2.0"
description = "Implementation of the Unicode Bidirectional Algorithm"
repository = "https://github.com/servo/unicode-bidi"
documentation = "http://doc.servo.org/unicode_bidi/"
keywords = ["rtl", "unicode", "text", "layout", "bidi"]
exclude = ["*.txt"]
[lib]
name = "unicode_bidi"
[dependencies]
matches = "0.1"

View File

@ -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.

View File

@ -0,0 +1,25 @@
Copyright (c) 2015 The Rust Project Developers
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.

View File

@ -0,0 +1,11 @@
# unicode-bidi
This crate implements the [Unicode Bidirectional Algorithm][tr9] for display
of mixed right-to-left and left-to-right text. It is written in safe Rust,
compatible with the current stable release.
[Documentation](http://doc.servo.org/unicode_bidi/)
[![Build Status](https://travis-ci.org/servo/unicode-bidi.svg?branch=master)](https://travis-ci.org/servo/unicode-bidi)
[tr9]: http://www.unicode.org/reports/tr9/

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,220 @@
#!/usr/bin/env python
#
# Based on src/etc/unicode.py from Rust 1.2.0.
#
# Copyright 2011-2013 The Rust Project Developers.
# Copyright 2015 The Servo Project Developers. See the COPYRIGHT
# file at the top-level directory of this distribution and at
# http://rust-lang.org/COPYRIGHT.
#
# Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
# http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
# <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
# option. This file may not be copied, modified, or distributed
# except according to those terms.
import fileinput, re, os, sys, operator
preamble = '''// NOTE:
// The following code was generated by "tools/generate.py". do not edit directly
#![allow(missing_docs, non_upper_case_globals, non_snake_case)]
'''
# these are the surrogate codepoints, which are not valid rust characters
surrogate_codepoints = (0xd800, 0xdfff)
def fetch(f):
if not os.path.exists(os.path.basename(f)):
os.system("curl -O http://www.unicode.org/Public/UNIDATA/%s"
% f)
if not os.path.exists(os.path.basename(f)):
sys.stderr.write("cannot load %s" % f)
exit(1)
def is_surrogate(n):
return surrogate_codepoints[0] <= n <= surrogate_codepoints[1]
def load_unicode_data(f):
fetch(f)
udict = {};
range_start = -1;
for line in fileinput.input(f):
data = line.split(';');
if len(data) != 15:
continue
cp = int(data[0], 16);
if is_surrogate(cp):
continue
if range_start >= 0:
for i in xrange(range_start, cp):
udict[i] = data;
range_start = -1;
if data[1].endswith(", First>"):
range_start = cp;
continue;
udict[cp] = data;
# Mapping of code point to Bidi_Class property:
bidi_class = {}
for code in udict:
[code_org, name, gencat, combine, bidi,
decomp, deci, digit, num, mirror,
old, iso, upcase, lowcase, titlecase ] = udict[code];
if bidi not in bidi_class:
bidi_class[bidi] = []
bidi_class[bidi].append(code)
# Default Bidi_Class for unassigned codepoints.
# http://www.unicode.org/Public/UNIDATA/extracted/DerivedBidiClass.txt
default_ranges = [
(0x0600, 0x07BF, "AL"), (0x08A0, 0x08FF, "AL"),
(0xFB50, 0xFDCF, "AL"), (0xFDF0, 0xFDFF, "AL"),
(0xFE70, 0xFEFF, "AL"), (0x1EE00, 0x0001EEFF, "AL"),
(0x0590, 0x05FF, "R"), (0x07C0, 0x089F, "R"),
(0xFB1D, 0xFB4F, "R"), (0x00010800, 0x00010FFF, "R"),
(0x0001E800, 0x0001EDFF, "R"), (0x0001EF00, 0x0001EFFF, "R"),
(0x20A0, 0x20CF, "ET")]
for (start, end, default) in default_ranges:
for code in range(start, end+1):
if not code in udict:
bidi_class[default].append(code)
bidi_class = group_cats(bidi_class)
return bidi_class
def group_cats(cats):
cats_out = []
for cat in cats:
cats_out.extend([(x, y, cat) for (x, y) in group_cat(cats[cat])])
cats_out.sort(key=lambda w: w[0])
return (sorted(cats.keys()), cats_out)
def group_cat(cat):
cat_out = []
letters = sorted(set(cat))
cur_start = letters.pop(0)
cur_end = cur_start
for letter in letters:
assert letter > cur_end, \
"cur_end: %s, letter: %s" % (hex(cur_end), hex(letter))
if letter == cur_end + 1:
cur_end = letter
else:
cat_out.append((cur_start, cur_end))
cur_start = cur_end = letter
cat_out.append((cur_start, cur_end))
return cat_out
def format_table_content(f, content, indent):
line = " "*indent
first = True
for chunk in content.split(","):
if len(line) + len(chunk) < 98:
if first:
line += chunk
else:
line += ", " + chunk
first = False
else:
f.write(line + ",\n")
line = " "*indent + chunk
f.write(line)
def escape_char(c):
return "'\\u{%x}'" % c
def emit_table(f, name, t_data, t_type = "&'static [(char, char)]", is_pub=True,
pfun=lambda x: "(%s,%s)" % (escape_char(x[0]), escape_char(x[1]))):
pub_string = ""
if is_pub:
pub_string = "pub "
f.write(" %sconst %s: %s = &[\n" % (pub_string, name, t_type))
data = ""
first = True
for dat in t_data:
if not first:
data += ","
first = False
data += pfun(dat)
format_table_content(f, data, 8)
f.write("\n ];\n\n")
def emit_bidi_module(f, bidi_class, cats):
f.write("""pub use self::BidiClass::*;
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
/// Represents the Unicode character property **Bidi_Class**, also known as
/// the *bidirectional character type*.
///
/// Use the `bidi_class` function to look up the BidiClass of a code point.
///
/// http://www.unicode.org/reports/tr9/#Bidirectional_Character_Types
pub enum BidiClass {
""")
for cat in cats:
f.write(" " + cat + ",\n")
f.write(""" }
fn bsearch_range_value_table(c: char, r: &'static [(char, char, BidiClass)]) -> BidiClass {
use ::std::cmp::Ordering::{Equal, Less, Greater};
match r.binary_search_by(|&(lo, hi, _)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
}) {
Ok(idx) => {
let (_, _, cat) = r[idx];
cat
}
// UCD/extracted/DerivedBidiClass.txt: "All code points not explicitly listed
// for Bidi_Class have the value Left_To_Right (L)."
Err(_) => L
}
}
/// Find the BidiClass of a single char.
pub fn bidi_class(c: char) -> BidiClass {
bsearch_range_value_table(c, bidi_class_table)
}
""")
emit_table(f, "bidi_class_table", bidi_class, "&'static [(char, char, BidiClass)]",
pfun=lambda x: "(%s,%s,%s)" % (escape_char(x[0]), escape_char(x[1]), x[2]),
is_pub=False)
if __name__ == "__main__":
os.chdir("../src/") # changing download path to /unicode-bidi/src/
r = "tables.rs"
# downloading the test case files
# fetch("BidiTest.txt")
# fetch("BidiCharacterTest.txt")
if os.path.exists(r):
os.remove(r)
with open(r, "w") as rf:
# write the file's preamble
rf.write(preamble)
# download and parse all the data
fetch("ReadMe.txt")
with open("ReadMe.txt") as readme:
pattern = "for Version (\d+)\.(\d+)\.(\d+) of the Unicode"
unicode_version = re.search(pattern, readme.read()).groups()
rf.write("""
/// The version of [Unicode](http://www.unicode.org/)
/// that the `bidi_class` function is based on.
pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
""" % unicode_version)
(bidi_cats, bidi_class) = load_unicode_data("UnicodeData.txt")
emit_bidi_module(rf, bidi_class, bidi_cats)

View File

@ -1 +1 @@
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"ca9e613b65aadd1e89ff6bc5f76a1cd7989ca7441b4debfe1bde8c35cc165b59",".travis.yml":"5c3f9b92ab6ca79a98400b8c344f3a06fcc096b5df6f49fbae1a83dceb540170","AUTHORS":"6029da5a270f7047db642cfdaa521acdfd93dcae9f9cd02dc1bd43dfa526fc18","COPYRIGHT":"edb20b474f6cbd4f4db066b54a9e0f687d0009d309412a63431189b59b8e2a07","Cargo.toml":"4b649e28df32ff0d08dd5ab0dfffb62d96f2f81e85370f2112ecd4d7f800910a","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"e764abd9a6abbe9517dd9dedc003dd64594351282437a509fec9362ef136686d","src/lib.rs":"ef549431c0da99908df0a91deaee977d658c54449ed4abe935d3b0ef01c0eb51","src/tables.rs":"a2bb982b051a0ce7b85ade1f755c5b89e7f0415cfa1cbb62beb118d7b29da587","tools/generate.py":"a7b4a0c097bea5e0c626a6d33cb862bf4c542e36ac837b99455535c4ab83da6d"},"package":"d3a078ebdd62c0e71a709c3d53d2af693fe09fe93fbff8344aebe289b78f9032"}
{"files":{".cargo-ok":"e3b0c44298fc1c149afbf4c8996fb92427ae41e4649b934ca495991b7852b855",".gitignore":"c4efd1043636b9b8f207ead7488fca41f56871884df3c1f51bafdd80daa60f24",".rustfmt.toml":"4587a30e695dc4afdd3b5d33370cf712c90a716de06ab0c5a2c023b0f269ab1a",".travis.yml":"e340419604a35e795fc3afdab237eb0ea3a31e71c98fb98fa88626d61b8a50f7","AUTHORS":"1ff3a7c8519b29544bb28ba9b1e7502df0cb764051fb9a1172e60006aa2b8dcc","COPYRIGHT":"edb20b474f6cbd4f4db066b54a9e0f687d0009d309412a63431189b59b8e2a07","Cargo.toml":"2da98c00ffb4e0f2977eefab077329e9b544cde3bb495432d4bb933b558c5b59","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"7b63ecd5f1902af1b63729947373683c32745c16a10e8e6292e2e2dcd7e90ae0","README.md":"e764abd9a6abbe9517dd9dedc003dd64594351282437a509fec9362ef136686d","benches/udhr.rs":"a4ada9ef6953e25d794ea8338356a8717d0f8ef32997cf5ee6a4e3db9d6eb369","benches/udhr_data/README.md":"103dd98f2777082f73dd90ce441245370169a6e889b329da81ee4b9c236c0e05","src/char_data/mod.rs":"3ae73b97dfbcea927a0dde160a8e328e550d270ef82bfc3137b8bfba5d13174c","src/char_data/tables.rs":"3742ed00360d3955b10ba690b1446e69ddf04f2cee13e86dd185ba6641bc6198","src/deprecated.rs":"ce1b62ac47d0d7ea547a1e03d17cd86b6b850e4e095642ba2e9c29130f13fa72","src/explicit.rs":"9ebe900dd42cba45de5348d52d60118fe880ed154b63b388536acb67e045bd7f","src/format_chars.rs":"ce14652d83a2227df31152cbabff30585b3ab2890ee290da8c46950c03969dc0","src/implicit.rs":"e28f215c821b601216872858c81c654c1812c5ce676d59e23eb2a7981bc2cadf","src/level.rs":"b8739d4dd84d9270140047972167d9e72db8637c769228eec17d12e07c5ab55f","src/lib.rs":"683409b531874e752b9233c6cb1650c14db7305030ce9c5aed803bce3af2dcb1","src/prepare.rs":"3d48eabc78cce98ca23957e3d24da817aad4fcd2fb8311d355be1858a4dead72","tests/conformance_tests.rs":"9f17d470806704faedac83ec4c4b11cb40a548b56f17dfa623d91a673b227f70","tools/generate.py":"12f94bdf2226f306d993fe2a0fa623b8dc9b1db1ac038a17ab44892ccdc8feeb"},"package":"c44d4e7ce691e2538b886bf33669fd6da1653a12d741b9390f351955c0949c03"}

View File

@ -1,4 +1,3 @@
Cargo.lock
target
src/ReadMe.txt
*.txt
/data/
/target/

View File

@ -0,0 +1,6 @@
array_layout = "Block"
array_width = 80
fn_args_layout = "Block"
fn_brace_style = "SameLineWhere"
fn_call_style = "Block"
generics_indent = "Block"

View File

@ -1,9 +1,24 @@
sudo: false
language: rust
rust:
- nightly
- beta
- stable
- 1.15.0
matrix:
fast_finish: true
notifications:
webhooks: http://build.servo.org:54856/travis
before_script:
- pip install git+https://github.com/euclio/travis-cargo@kcov --user && export PATH=$HOME/.local/bin:$PATH
script:
- cargo build --verbose
- cargo test --verbose
- cargo test --verbose --features with_serde
- cargo doc --verbose --no-deps
- travis-cargo bench

View File

@ -1,3 +1,4 @@
This software was written by the following people:
Matt Brubeck <mbrubeck@limpet.net>
Behnam Esfahbod <behnam@zwnj.org>

View File

@ -1,6 +1,6 @@
[package]
name = "unicode-bidi"
version = "0.2.5"
version = "0.3.1"
authors = ["The Servo Project Developers"]
license = "MIT / Apache-2.0"
description = "Implementation of the Unicode Bidirectional Algorithm"
@ -15,3 +15,11 @@ name = "unicode_bidi"
[dependencies]
matches = "0.1"
serde = {version = ">=0.8, <2.0", optional = true}
serde_test = {version = ">=0.8, <2.0", optional = true}
serde_derive = {version = ">=0.8, <2.0", optional = true}
[features]
default = []
unstable = [] # Use in benches/
with_serde = ["serde", "serde_test", "serde_derive"]

View File

@ -0,0 +1,92 @@
// Copyright 2014 The html5ever Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![cfg(all(test, feature = "unstable"))]
#![feature(test)]
extern crate test;
extern crate unicode_bidi;
use test::Bencher;
use unicode_bidi::BidiInfo;
const LTR_TEXTS: &[&str] = &[
include_str!("udhr_data/ltr/udhr_acu_1.txt"),
include_str!("udhr_data/ltr/udhr_auc.txt"),
include_str!("udhr_data/ltr/udhr_knc.txt"),
include_str!("udhr_data/ltr/udhr_krl.txt"),
include_str!("udhr_data/ltr/udhr_kwi.txt"),
include_str!("udhr_data/ltr/udhr_lot.txt"),
include_str!("udhr_data/ltr/udhr_piu.txt"),
include_str!("udhr_data/ltr/udhr_qug.txt"),
include_str!("udhr_data/ltr/udhr_snn.txt"),
include_str!("udhr_data/ltr/udhr_tiv.txt"),
];
const BIDI_TEXTS: &[&str] = &[
include_str!("udhr_data/bidi/udhr_aii.txt"),
include_str!("udhr_data/bidi/udhr_arb.txt"),
include_str!("udhr_data/bidi/udhr_mly_arab.txt"),
include_str!("udhr_data/bidi/udhr_pes_1.txt"),
include_str!("udhr_data/bidi/udhr_skr.txt"),
include_str!("udhr_data/bidi/udhr_urd.txt"),
include_str!("udhr_data/bidi/udhr_eng.txt"),
include_str!("udhr_data/bidi/udhr_mly_latn.txt"),
include_str!("udhr_data/bidi/udhr_pes_2.txt"),
include_str!("udhr_data/bidi/udhr_uig_arab.txt"),
include_str!("udhr_data/bidi/udhr_urd_2.txt"),
include_str!("udhr_data/bidi/udhr_heb.txt"),
include_str!("udhr_data/bidi/udhr_pbu.txt"),
include_str!("udhr_data/bidi/udhr_pnb.txt"),
include_str!("udhr_data/bidi/udhr_uig_latn.txt"),
include_str!("udhr_data/bidi/udhr_ydd.txt"),
];
#[bench]
fn bench_bidi_info_new_for_ltr_texts(b: &mut Bencher) {
b.iter(
|| for text in LTR_TEXTS {
BidiInfo::new(text, None);
},
);
}
#[bench]
fn bench_bidi_info_new_for_bidi_texts(b: &mut Bencher) {
b.iter(
|| for text in BIDI_TEXTS {
BidiInfo::new(text, None);
},
);
}
#[bench]
fn bench_bidi_info_new_and_reordered_for_ltr_texts(b: &mut Bencher) {
b.iter(
|| for text in LTR_TEXTS {
let bidi_info = BidiInfo::new(text, None);
let para = &bidi_info.paragraphs[0];
let line = para.range.clone();
bidi_info.reordered_levels(para, line);
},
);
}
#[bench]
fn bench_bidi_info_new_and_reordered_for_bidi_texts(b: &mut Bencher) {
b.iter(
|| for text in BIDI_TEXTS {
let bidi_info = BidiInfo::new(text, None);
let para = &bidi_info.paragraphs[0];
let line = para.range.clone();
bidi_info.reordered_levels(para, line);
},
);
}

View File

@ -0,0 +1,3 @@
# A collection of UDHR in Unicode text files
Source: http://unicode.org/udhr/

View File

@ -0,0 +1,116 @@
// Copyright 2015 The Servo Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Accessor for `Bidi_Class` property from Unicode Character Database (UCD)
mod tables;
pub use self::tables::{BidiClass, UNICODE_VERSION};
use std::cmp::Ordering::{Equal, Less, Greater};
use std::char;
use self::tables::bidi_class_table;
use BidiClass::*;
/// Find the BidiClass of a single char.
pub fn bidi_class(c: char) -> BidiClass {
bsearch_range_value_table(c, bidi_class_table)
}
pub fn is_rtl(bidi_class: BidiClass) -> bool {
match bidi_class {
RLE | RLO | RLI => true,
_ => false,
}
}
fn bsearch_range_value_table(c: char, r: &'static [(char, char, BidiClass)]) -> BidiClass {
match r.binary_search_by(
|&(lo, hi, _)| if lo <= c && c <= hi {
Equal
} else if hi < c {
Less
} else {
Greater
},
) {
Ok(idx) => {
let (_, _, cat) = r[idx];
cat
}
// UCD/extracted/DerivedBidiClass.txt: "All code points not explicitly listed
// for Bidi_Class have the value Left_To_Right (L)."
Err(_) => L,
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_bidi_class() {
for (input, expected) in
vec![
(0x0000, BN),
(0x0040, ON),
(0x0041, L),
(0x0062, L),
(0x007F, BN),
// Hebrew
(0x0590, R),
(0x05D0, R),
(0x05D1, R),
(0x05FF, R),
// Arabic
(0x0600, AN),
(0x0627, AL),
(0x07BF, AL),
// Default R + Arabic Extras
(0x07C0, R),
(0x085F, R),
(0x0860, R),
(0x089F, R),
(0x08A0, AL),
(0x089F, R),
(0x08FF, NSM),
// Default ET
(0x20A0, ET),
(0x20CF, ET),
// Arabic Presentation Forms
(0xFB1D, R),
(0xFB4F, R),
(0xFB50, AL),
(0xFDCF, AL),
(0xFDF0, AL),
(0xFDFF, AL),
(0xFE70, AL),
(0xFEFE, AL),
(0xFEFF, BN),
// Default AL + R
(0x10800, R),
(0x10FFF, R),
(0x1E800, R),
(0x1EDFF, R),
(0x1EE00, AL),
(0x1EEFF, AL),
(0x1EF00, R),
(0x1EFFF, R),
] {
assert_eq!(bidi_class(char::from_u32(input).unwrap()), expected);
}
}
}

View File

@ -0,0 +1,452 @@
// NOTE:
// The following code was generated by "tools/generate.py". do not edit directly
#![allow(missing_docs, non_upper_case_globals, non_snake_case)]
#![cfg_attr(rustfmt, rustfmt_skip)]
/// The [Unicode version](http://www.unicode.org/versions/) of data
pub const UNICODE_VERSION: (u64, u64, u64) = (9, 0, 0);
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
/// Represents values of the Unicode character property
/// [Bidi_Class](http://www.unicode.org/reports/tr44/#Bidi_Class), also
/// known as the *bidirectional character type*.
///
/// * http://www.unicode.org/reports/tr9/#Bidirectional_Character_Types
/// * http://www.unicode.org/reports/tr44/#Bidi_Class_Values
pub enum BidiClass {
AL,
AN,
B,
BN,
CS,
EN,
ES,
ET,
FSI,
L,
LRE,
LRI,
LRO,
NSM,
ON,
PDF,
PDI,
R,
RLE,
RLI,
RLO,
S,
WS,
}
use self::BidiClass::*;
pub const bidi_class_table: &'static [(char, char, BidiClass)] = &[
('\u{0}', '\u{8}', BN), ('\u{9}', '\u{9}', S), ('\u{a}', '\u{a}', B), ('\u{b}', '\u{b}', S),
('\u{c}', '\u{c}', WS), ('\u{d}', '\u{d}', B), ('\u{e}', '\u{1b}', BN), ('\u{1c}', '\u{1e}', B),
('\u{1f}', '\u{1f}', S), ('\u{20}', '\u{20}', WS), ('\u{21}', '\u{22}', ON), ('\u{23}',
'\u{25}', ET), ('\u{26}', '\u{2a}', ON), ('\u{2b}', '\u{2b}', ES), ('\u{2c}', '\u{2c}', CS),
('\u{2d}', '\u{2d}', ES), ('\u{2e}', '\u{2f}', CS), ('\u{30}', '\u{39}', EN), ('\u{3a}',
'\u{3a}', CS), ('\u{3b}', '\u{40}', ON), ('\u{41}', '\u{5a}', L), ('\u{5b}', '\u{60}', ON),
('\u{61}', '\u{7a}', L), ('\u{7b}', '\u{7e}', ON), ('\u{7f}', '\u{84}', BN), ('\u{85}',
'\u{85}', B), ('\u{86}', '\u{9f}', BN), ('\u{a0}', '\u{a0}', CS), ('\u{a1}', '\u{a1}', ON),
('\u{a2}', '\u{a5}', ET), ('\u{a6}', '\u{a9}', ON), ('\u{aa}', '\u{aa}', L), ('\u{ab}',
'\u{ac}', ON), ('\u{ad}', '\u{ad}', BN), ('\u{ae}', '\u{af}', ON), ('\u{b0}', '\u{b1}', ET),
('\u{b2}', '\u{b3}', EN), ('\u{b4}', '\u{b4}', ON), ('\u{b5}', '\u{b5}', L), ('\u{b6}',
'\u{b8}', ON), ('\u{b9}', '\u{b9}', EN), ('\u{ba}', '\u{ba}', L), ('\u{bb}', '\u{bf}', ON),
('\u{c0}', '\u{d6}', L), ('\u{d7}', '\u{d7}', ON), ('\u{d8}', '\u{f6}', L), ('\u{f7}', '\u{f7}',
ON), ('\u{f8}', '\u{2b8}', L), ('\u{2b9}', '\u{2ba}', ON), ('\u{2bb}', '\u{2c1}', L),
('\u{2c2}', '\u{2cf}', ON), ('\u{2d0}', '\u{2d1}', L), ('\u{2d2}', '\u{2df}', ON), ('\u{2e0}',
'\u{2e4}', L), ('\u{2e5}', '\u{2ed}', ON), ('\u{2ee}', '\u{2ee}', L), ('\u{2ef}', '\u{2ff}',
ON), ('\u{300}', '\u{36f}', NSM), ('\u{370}', '\u{373}', L), ('\u{374}', '\u{375}', ON),
('\u{376}', '\u{377}', L), ('\u{37a}', '\u{37d}', L), ('\u{37e}', '\u{37e}', ON), ('\u{37f}',
'\u{37f}', L), ('\u{384}', '\u{385}', ON), ('\u{386}', '\u{386}', L), ('\u{387}', '\u{387}',
ON), ('\u{388}', '\u{38a}', L), ('\u{38c}', '\u{38c}', L), ('\u{38e}', '\u{3a1}', L),
('\u{3a3}', '\u{3f5}', L), ('\u{3f6}', '\u{3f6}', ON), ('\u{3f7}', '\u{482}', L), ('\u{483}',
'\u{489}', NSM), ('\u{48a}', '\u{52f}', L), ('\u{531}', '\u{556}', L), ('\u{559}', '\u{55f}',
L), ('\u{561}', '\u{587}', L), ('\u{589}', '\u{589}', L), ('\u{58a}', '\u{58a}', ON),
('\u{58d}', '\u{58e}', ON), ('\u{58f}', '\u{58f}', ET), ('\u{590}', '\u{590}', R), ('\u{591}',
'\u{5bd}', NSM), ('\u{5be}', '\u{5be}', R), ('\u{5bf}', '\u{5bf}', NSM), ('\u{5c0}', '\u{5c0}',
R), ('\u{5c1}', '\u{5c2}', NSM), ('\u{5c3}', '\u{5c3}', R), ('\u{5c4}', '\u{5c5}', NSM),
('\u{5c6}', '\u{5c6}', R), ('\u{5c7}', '\u{5c7}', NSM), ('\u{5c8}', '\u{5ff}', R), ('\u{600}',
'\u{605}', AN), ('\u{606}', '\u{607}', ON), ('\u{608}', '\u{608}', AL), ('\u{609}', '\u{60a}',
ET), ('\u{60b}', '\u{60b}', AL), ('\u{60c}', '\u{60c}', CS), ('\u{60d}', '\u{60d}', AL),
('\u{60e}', '\u{60f}', ON), ('\u{610}', '\u{61a}', NSM), ('\u{61b}', '\u{64a}', AL), ('\u{64b}',
'\u{65f}', NSM), ('\u{660}', '\u{669}', AN), ('\u{66a}', '\u{66a}', ET), ('\u{66b}', '\u{66c}',
AN), ('\u{66d}', '\u{66f}', AL), ('\u{670}', '\u{670}', NSM), ('\u{671}', '\u{6d5}', AL),
('\u{6d6}', '\u{6dc}', NSM), ('\u{6dd}', '\u{6dd}', AN), ('\u{6de}', '\u{6de}', ON), ('\u{6df}',
'\u{6e4}', NSM), ('\u{6e5}', '\u{6e6}', AL), ('\u{6e7}', '\u{6e8}', NSM), ('\u{6e9}', '\u{6e9}',
ON), ('\u{6ea}', '\u{6ed}', NSM), ('\u{6ee}', '\u{6ef}', AL), ('\u{6f0}', '\u{6f9}', EN),
('\u{6fa}', '\u{710}', AL), ('\u{711}', '\u{711}', NSM), ('\u{712}', '\u{72f}', AL), ('\u{730}',
'\u{74a}', NSM), ('\u{74b}', '\u{7a5}', AL), ('\u{7a6}', '\u{7b0}', NSM), ('\u{7b1}', '\u{7bf}',
AL), ('\u{7c0}', '\u{7ea}', R), ('\u{7eb}', '\u{7f3}', NSM), ('\u{7f4}', '\u{7f5}', R),
('\u{7f6}', '\u{7f9}', ON), ('\u{7fa}', '\u{815}', R), ('\u{816}', '\u{819}', NSM), ('\u{81a}',
'\u{81a}', R), ('\u{81b}', '\u{823}', NSM), ('\u{824}', '\u{824}', R), ('\u{825}', '\u{827}',
NSM), ('\u{828}', '\u{828}', R), ('\u{829}', '\u{82d}', NSM), ('\u{82e}', '\u{858}', R),
('\u{859}', '\u{85b}', NSM), ('\u{85c}', '\u{89f}', R), ('\u{8a0}', '\u{8d3}', AL), ('\u{8d4}',
'\u{8e1}', NSM), ('\u{8e2}', '\u{8e2}', AN), ('\u{8e3}', '\u{902}', NSM), ('\u{903}', '\u{939}',
L), ('\u{93a}', '\u{93a}', NSM), ('\u{93b}', '\u{93b}', L), ('\u{93c}', '\u{93c}', NSM),
('\u{93d}', '\u{940}', L), ('\u{941}', '\u{948}', NSM), ('\u{949}', '\u{94c}', L), ('\u{94d}',
'\u{94d}', NSM), ('\u{94e}', '\u{950}', L), ('\u{951}', '\u{957}', NSM), ('\u{958}', '\u{961}',
L), ('\u{962}', '\u{963}', NSM), ('\u{964}', '\u{980}', L), ('\u{981}', '\u{981}', NSM),
('\u{982}', '\u{983}', L), ('\u{985}', '\u{98c}', L), ('\u{98f}', '\u{990}', L), ('\u{993}',
'\u{9a8}', L), ('\u{9aa}', '\u{9b0}', L), ('\u{9b2}', '\u{9b2}', L), ('\u{9b6}', '\u{9b9}', L),
('\u{9bc}', '\u{9bc}', NSM), ('\u{9bd}', '\u{9c0}', L), ('\u{9c1}', '\u{9c4}', NSM), ('\u{9c7}',
'\u{9c8}', L), ('\u{9cb}', '\u{9cc}', L), ('\u{9cd}', '\u{9cd}', NSM), ('\u{9ce}', '\u{9ce}',
L), ('\u{9d7}', '\u{9d7}', L), ('\u{9dc}', '\u{9dd}', L), ('\u{9df}', '\u{9e1}', L), ('\u{9e2}',
'\u{9e3}', NSM), ('\u{9e6}', '\u{9f1}', L), ('\u{9f2}', '\u{9f3}', ET), ('\u{9f4}', '\u{9fa}',
L), ('\u{9fb}', '\u{9fb}', ET), ('\u{a01}', '\u{a02}', NSM), ('\u{a03}', '\u{a03}', L),
('\u{a05}', '\u{a0a}', L), ('\u{a0f}', '\u{a10}', L), ('\u{a13}', '\u{a28}', L), ('\u{a2a}',
'\u{a30}', L), ('\u{a32}', '\u{a33}', L), ('\u{a35}', '\u{a36}', L), ('\u{a38}', '\u{a39}', L),
('\u{a3c}', '\u{a3c}', NSM), ('\u{a3e}', '\u{a40}', L), ('\u{a41}', '\u{a42}', NSM), ('\u{a47}',
'\u{a48}', NSM), ('\u{a4b}', '\u{a4d}', NSM), ('\u{a51}', '\u{a51}', NSM), ('\u{a59}',
'\u{a5c}', L), ('\u{a5e}', '\u{a5e}', L), ('\u{a66}', '\u{a6f}', L), ('\u{a70}', '\u{a71}',
NSM), ('\u{a72}', '\u{a74}', L), ('\u{a75}', '\u{a75}', NSM), ('\u{a81}', '\u{a82}', NSM),
('\u{a83}', '\u{a83}', L), ('\u{a85}', '\u{a8d}', L), ('\u{a8f}', '\u{a91}', L), ('\u{a93}',
'\u{aa8}', L), ('\u{aaa}', '\u{ab0}', L), ('\u{ab2}', '\u{ab3}', L), ('\u{ab5}', '\u{ab9}', L),
('\u{abc}', '\u{abc}', NSM), ('\u{abd}', '\u{ac0}', L), ('\u{ac1}', '\u{ac5}', NSM), ('\u{ac7}',
'\u{ac8}', NSM), ('\u{ac9}', '\u{ac9}', L), ('\u{acb}', '\u{acc}', L), ('\u{acd}', '\u{acd}',
NSM), ('\u{ad0}', '\u{ad0}', L), ('\u{ae0}', '\u{ae1}', L), ('\u{ae2}', '\u{ae3}', NSM),
('\u{ae6}', '\u{af0}', L), ('\u{af1}', '\u{af1}', ET), ('\u{af9}', '\u{af9}', L), ('\u{b01}',
'\u{b01}', NSM), ('\u{b02}', '\u{b03}', L), ('\u{b05}', '\u{b0c}', L), ('\u{b0f}', '\u{b10}',
L), ('\u{b13}', '\u{b28}', L), ('\u{b2a}', '\u{b30}', L), ('\u{b32}', '\u{b33}', L), ('\u{b35}',
'\u{b39}', L), ('\u{b3c}', '\u{b3c}', NSM), ('\u{b3d}', '\u{b3e}', L), ('\u{b3f}', '\u{b3f}',
NSM), ('\u{b40}', '\u{b40}', L), ('\u{b41}', '\u{b44}', NSM), ('\u{b47}', '\u{b48}', L),
('\u{b4b}', '\u{b4c}', L), ('\u{b4d}', '\u{b4d}', NSM), ('\u{b56}', '\u{b56}', NSM), ('\u{b57}',
'\u{b57}', L), ('\u{b5c}', '\u{b5d}', L), ('\u{b5f}', '\u{b61}', L), ('\u{b62}', '\u{b63}',
NSM), ('\u{b66}', '\u{b77}', L), ('\u{b82}', '\u{b82}', NSM), ('\u{b83}', '\u{b83}', L),
('\u{b85}', '\u{b8a}', L), ('\u{b8e}', '\u{b90}', L), ('\u{b92}', '\u{b95}', L), ('\u{b99}',
'\u{b9a}', L), ('\u{b9c}', '\u{b9c}', L), ('\u{b9e}', '\u{b9f}', L), ('\u{ba3}', '\u{ba4}', L),
('\u{ba8}', '\u{baa}', L), ('\u{bae}', '\u{bb9}', L), ('\u{bbe}', '\u{bbf}', L), ('\u{bc0}',
'\u{bc0}', NSM), ('\u{bc1}', '\u{bc2}', L), ('\u{bc6}', '\u{bc8}', L), ('\u{bca}', '\u{bcc}',
L), ('\u{bcd}', '\u{bcd}', NSM), ('\u{bd0}', '\u{bd0}', L), ('\u{bd7}', '\u{bd7}', L),
('\u{be6}', '\u{bf2}', L), ('\u{bf3}', '\u{bf8}', ON), ('\u{bf9}', '\u{bf9}', ET), ('\u{bfa}',
'\u{bfa}', ON), ('\u{c00}', '\u{c00}', NSM), ('\u{c01}', '\u{c03}', L), ('\u{c05}', '\u{c0c}',
L), ('\u{c0e}', '\u{c10}', L), ('\u{c12}', '\u{c28}', L), ('\u{c2a}', '\u{c39}', L), ('\u{c3d}',
'\u{c3d}', L), ('\u{c3e}', '\u{c40}', NSM), ('\u{c41}', '\u{c44}', L), ('\u{c46}', '\u{c48}',
NSM), ('\u{c4a}', '\u{c4d}', NSM), ('\u{c55}', '\u{c56}', NSM), ('\u{c58}', '\u{c5a}', L),
('\u{c60}', '\u{c61}', L), ('\u{c62}', '\u{c63}', NSM), ('\u{c66}', '\u{c6f}', L), ('\u{c78}',
'\u{c7e}', ON), ('\u{c7f}', '\u{c80}', L), ('\u{c81}', '\u{c81}', NSM), ('\u{c82}', '\u{c83}',
L), ('\u{c85}', '\u{c8c}', L), ('\u{c8e}', '\u{c90}', L), ('\u{c92}', '\u{ca8}', L), ('\u{caa}',
'\u{cb3}', L), ('\u{cb5}', '\u{cb9}', L), ('\u{cbc}', '\u{cbc}', NSM), ('\u{cbd}', '\u{cc4}',
L), ('\u{cc6}', '\u{cc8}', L), ('\u{cca}', '\u{ccb}', L), ('\u{ccc}', '\u{ccd}', NSM),
('\u{cd5}', '\u{cd6}', L), ('\u{cde}', '\u{cde}', L), ('\u{ce0}', '\u{ce1}', L), ('\u{ce2}',
'\u{ce3}', NSM), ('\u{ce6}', '\u{cef}', L), ('\u{cf1}', '\u{cf2}', L), ('\u{d01}', '\u{d01}',
NSM), ('\u{d02}', '\u{d03}', L), ('\u{d05}', '\u{d0c}', L), ('\u{d0e}', '\u{d10}', L),
('\u{d12}', '\u{d3a}', L), ('\u{d3d}', '\u{d40}', L), ('\u{d41}', '\u{d44}', NSM), ('\u{d46}',
'\u{d48}', L), ('\u{d4a}', '\u{d4c}', L), ('\u{d4d}', '\u{d4d}', NSM), ('\u{d4e}', '\u{d4f}',
L), ('\u{d54}', '\u{d61}', L), ('\u{d62}', '\u{d63}', NSM), ('\u{d66}', '\u{d7f}', L),
('\u{d82}', '\u{d83}', L), ('\u{d85}', '\u{d96}', L), ('\u{d9a}', '\u{db1}', L), ('\u{db3}',
'\u{dbb}', L), ('\u{dbd}', '\u{dbd}', L), ('\u{dc0}', '\u{dc6}', L), ('\u{dca}', '\u{dca}',
NSM), ('\u{dcf}', '\u{dd1}', L), ('\u{dd2}', '\u{dd4}', NSM), ('\u{dd6}', '\u{dd6}', NSM),
('\u{dd8}', '\u{ddf}', L), ('\u{de6}', '\u{def}', L), ('\u{df2}', '\u{df4}', L), ('\u{e01}',
'\u{e30}', L), ('\u{e31}', '\u{e31}', NSM), ('\u{e32}', '\u{e33}', L), ('\u{e34}', '\u{e3a}',
NSM), ('\u{e3f}', '\u{e3f}', ET), ('\u{e40}', '\u{e46}', L), ('\u{e47}', '\u{e4e}', NSM),
('\u{e4f}', '\u{e5b}', L), ('\u{e81}', '\u{e82}', L), ('\u{e84}', '\u{e84}', L), ('\u{e87}',
'\u{e88}', L), ('\u{e8a}', '\u{e8a}', L), ('\u{e8d}', '\u{e8d}', L), ('\u{e94}', '\u{e97}', L),
('\u{e99}', '\u{e9f}', L), ('\u{ea1}', '\u{ea3}', L), ('\u{ea5}', '\u{ea5}', L), ('\u{ea7}',
'\u{ea7}', L), ('\u{eaa}', '\u{eab}', L), ('\u{ead}', '\u{eb0}', L), ('\u{eb1}', '\u{eb1}',
NSM), ('\u{eb2}', '\u{eb3}', L), ('\u{eb4}', '\u{eb9}', NSM), ('\u{ebb}', '\u{ebc}', NSM),
('\u{ebd}', '\u{ebd}', L), ('\u{ec0}', '\u{ec4}', L), ('\u{ec6}', '\u{ec6}', L), ('\u{ec8}',
'\u{ecd}', NSM), ('\u{ed0}', '\u{ed9}', L), ('\u{edc}', '\u{edf}', L), ('\u{f00}', '\u{f17}',
L), ('\u{f18}', '\u{f19}', NSM), ('\u{f1a}', '\u{f34}', L), ('\u{f35}', '\u{f35}', NSM),
('\u{f36}', '\u{f36}', L), ('\u{f37}', '\u{f37}', NSM), ('\u{f38}', '\u{f38}', L), ('\u{f39}',
'\u{f39}', NSM), ('\u{f3a}', '\u{f3d}', ON), ('\u{f3e}', '\u{f47}', L), ('\u{f49}', '\u{f6c}',
L), ('\u{f71}', '\u{f7e}', NSM), ('\u{f7f}', '\u{f7f}', L), ('\u{f80}', '\u{f84}', NSM),
('\u{f85}', '\u{f85}', L), ('\u{f86}', '\u{f87}', NSM), ('\u{f88}', '\u{f8c}', L), ('\u{f8d}',
'\u{f97}', NSM), ('\u{f99}', '\u{fbc}', NSM), ('\u{fbe}', '\u{fc5}', L), ('\u{fc6}', '\u{fc6}',
NSM), ('\u{fc7}', '\u{fcc}', L), ('\u{fce}', '\u{fda}', L), ('\u{1000}', '\u{102c}', L),
('\u{102d}', '\u{1030}', NSM), ('\u{1031}', '\u{1031}', L), ('\u{1032}', '\u{1037}', NSM),
('\u{1038}', '\u{1038}', L), ('\u{1039}', '\u{103a}', NSM), ('\u{103b}', '\u{103c}', L),
('\u{103d}', '\u{103e}', NSM), ('\u{103f}', '\u{1057}', L), ('\u{1058}', '\u{1059}', NSM),
('\u{105a}', '\u{105d}', L), ('\u{105e}', '\u{1060}', NSM), ('\u{1061}', '\u{1070}', L),
('\u{1071}', '\u{1074}', NSM), ('\u{1075}', '\u{1081}', L), ('\u{1082}', '\u{1082}', NSM),
('\u{1083}', '\u{1084}', L), ('\u{1085}', '\u{1086}', NSM), ('\u{1087}', '\u{108c}', L),
('\u{108d}', '\u{108d}', NSM), ('\u{108e}', '\u{109c}', L), ('\u{109d}', '\u{109d}', NSM),
('\u{109e}', '\u{10c5}', L), ('\u{10c7}', '\u{10c7}', L), ('\u{10cd}', '\u{10cd}', L),
('\u{10d0}', '\u{1248}', L), ('\u{124a}', '\u{124d}', L), ('\u{1250}', '\u{1256}', L),
('\u{1258}', '\u{1258}', L), ('\u{125a}', '\u{125d}', L), ('\u{1260}', '\u{1288}', L),
('\u{128a}', '\u{128d}', L), ('\u{1290}', '\u{12b0}', L), ('\u{12b2}', '\u{12b5}', L),
('\u{12b8}', '\u{12be}', L), ('\u{12c0}', '\u{12c0}', L), ('\u{12c2}', '\u{12c5}', L),
('\u{12c8}', '\u{12d6}', L), ('\u{12d8}', '\u{1310}', L), ('\u{1312}', '\u{1315}', L),
('\u{1318}', '\u{135a}', L), ('\u{135d}', '\u{135f}', NSM), ('\u{1360}', '\u{137c}', L),
('\u{1380}', '\u{138f}', L), ('\u{1390}', '\u{1399}', ON), ('\u{13a0}', '\u{13f5}', L),
('\u{13f8}', '\u{13fd}', L), ('\u{1400}', '\u{1400}', ON), ('\u{1401}', '\u{167f}', L),
('\u{1680}', '\u{1680}', WS), ('\u{1681}', '\u{169a}', L), ('\u{169b}', '\u{169c}', ON),
('\u{16a0}', '\u{16f8}', L), ('\u{1700}', '\u{170c}', L), ('\u{170e}', '\u{1711}', L),
('\u{1712}', '\u{1714}', NSM), ('\u{1720}', '\u{1731}', L), ('\u{1732}', '\u{1734}', NSM),
('\u{1735}', '\u{1736}', L), ('\u{1740}', '\u{1751}', L), ('\u{1752}', '\u{1753}', NSM),
('\u{1760}', '\u{176c}', L), ('\u{176e}', '\u{1770}', L), ('\u{1772}', '\u{1773}', NSM),
('\u{1780}', '\u{17b3}', L), ('\u{17b4}', '\u{17b5}', NSM), ('\u{17b6}', '\u{17b6}', L),
('\u{17b7}', '\u{17bd}', NSM), ('\u{17be}', '\u{17c5}', L), ('\u{17c6}', '\u{17c6}', NSM),
('\u{17c7}', '\u{17c8}', L), ('\u{17c9}', '\u{17d3}', NSM), ('\u{17d4}', '\u{17da}', L),
('\u{17db}', '\u{17db}', ET), ('\u{17dc}', '\u{17dc}', L), ('\u{17dd}', '\u{17dd}', NSM),
('\u{17e0}', '\u{17e9}', L), ('\u{17f0}', '\u{17f9}', ON), ('\u{1800}', '\u{180a}', ON),
('\u{180b}', '\u{180d}', NSM), ('\u{180e}', '\u{180e}', BN), ('\u{1810}', '\u{1819}', L),
('\u{1820}', '\u{1877}', L), ('\u{1880}', '\u{1884}', L), ('\u{1885}', '\u{1886}', NSM),
('\u{1887}', '\u{18a8}', L), ('\u{18a9}', '\u{18a9}', NSM), ('\u{18aa}', '\u{18aa}', L),
('\u{18b0}', '\u{18f5}', L), ('\u{1900}', '\u{191e}', L), ('\u{1920}', '\u{1922}', NSM),
('\u{1923}', '\u{1926}', L), ('\u{1927}', '\u{1928}', NSM), ('\u{1929}', '\u{192b}', L),
('\u{1930}', '\u{1931}', L), ('\u{1932}', '\u{1932}', NSM), ('\u{1933}', '\u{1938}', L),
('\u{1939}', '\u{193b}', NSM), ('\u{1940}', '\u{1940}', ON), ('\u{1944}', '\u{1945}', ON),
('\u{1946}', '\u{196d}', L), ('\u{1970}', '\u{1974}', L), ('\u{1980}', '\u{19ab}', L),
('\u{19b0}', '\u{19c9}', L), ('\u{19d0}', '\u{19da}', L), ('\u{19de}', '\u{19ff}', ON),
('\u{1a00}', '\u{1a16}', L), ('\u{1a17}', '\u{1a18}', NSM), ('\u{1a19}', '\u{1a1a}', L),
('\u{1a1b}', '\u{1a1b}', NSM), ('\u{1a1e}', '\u{1a55}', L), ('\u{1a56}', '\u{1a56}', NSM),
('\u{1a57}', '\u{1a57}', L), ('\u{1a58}', '\u{1a5e}', NSM), ('\u{1a60}', '\u{1a60}', NSM),
('\u{1a61}', '\u{1a61}', L), ('\u{1a62}', '\u{1a62}', NSM), ('\u{1a63}', '\u{1a64}', L),
('\u{1a65}', '\u{1a6c}', NSM), ('\u{1a6d}', '\u{1a72}', L), ('\u{1a73}', '\u{1a7c}', NSM),
('\u{1a7f}', '\u{1a7f}', NSM), ('\u{1a80}', '\u{1a89}', L), ('\u{1a90}', '\u{1a99}', L),
('\u{1aa0}', '\u{1aad}', L), ('\u{1ab0}', '\u{1abe}', NSM), ('\u{1b00}', '\u{1b03}', NSM),
('\u{1b04}', '\u{1b33}', L), ('\u{1b34}', '\u{1b34}', NSM), ('\u{1b35}', '\u{1b35}', L),
('\u{1b36}', '\u{1b3a}', NSM), ('\u{1b3b}', '\u{1b3b}', L), ('\u{1b3c}', '\u{1b3c}', NSM),
('\u{1b3d}', '\u{1b41}', L), ('\u{1b42}', '\u{1b42}', NSM), ('\u{1b43}', '\u{1b4b}', L),
('\u{1b50}', '\u{1b6a}', L), ('\u{1b6b}', '\u{1b73}', NSM), ('\u{1b74}', '\u{1b7c}', L),
('\u{1b80}', '\u{1b81}', NSM), ('\u{1b82}', '\u{1ba1}', L), ('\u{1ba2}', '\u{1ba5}', NSM),
('\u{1ba6}', '\u{1ba7}', L), ('\u{1ba8}', '\u{1ba9}', NSM), ('\u{1baa}', '\u{1baa}', L),
('\u{1bab}', '\u{1bad}', NSM), ('\u{1bae}', '\u{1be5}', L), ('\u{1be6}', '\u{1be6}', NSM),
('\u{1be7}', '\u{1be7}', L), ('\u{1be8}', '\u{1be9}', NSM), ('\u{1bea}', '\u{1bec}', L),
('\u{1bed}', '\u{1bed}', NSM), ('\u{1bee}', '\u{1bee}', L), ('\u{1bef}', '\u{1bf1}', NSM),
('\u{1bf2}', '\u{1bf3}', L), ('\u{1bfc}', '\u{1c2b}', L), ('\u{1c2c}', '\u{1c33}', NSM),
('\u{1c34}', '\u{1c35}', L), ('\u{1c36}', '\u{1c37}', NSM), ('\u{1c3b}', '\u{1c49}', L),
('\u{1c4d}', '\u{1c88}', L), ('\u{1cc0}', '\u{1cc7}', L), ('\u{1cd0}', '\u{1cd2}', NSM),
('\u{1cd3}', '\u{1cd3}', L), ('\u{1cd4}', '\u{1ce0}', NSM), ('\u{1ce1}', '\u{1ce1}', L),
('\u{1ce2}', '\u{1ce8}', NSM), ('\u{1ce9}', '\u{1cec}', L), ('\u{1ced}', '\u{1ced}', NSM),
('\u{1cee}', '\u{1cf3}', L), ('\u{1cf4}', '\u{1cf4}', NSM), ('\u{1cf5}', '\u{1cf6}', L),
('\u{1cf8}', '\u{1cf9}', NSM), ('\u{1d00}', '\u{1dbf}', L), ('\u{1dc0}', '\u{1df5}', NSM),
('\u{1dfb}', '\u{1dff}', NSM), ('\u{1e00}', '\u{1f15}', L), ('\u{1f18}', '\u{1f1d}', L),
('\u{1f20}', '\u{1f45}', L), ('\u{1f48}', '\u{1f4d}', L), ('\u{1f50}', '\u{1f57}', L),
('\u{1f59}', '\u{1f59}', L), ('\u{1f5b}', '\u{1f5b}', L), ('\u{1f5d}', '\u{1f5d}', L),
('\u{1f5f}', '\u{1f7d}', L), ('\u{1f80}', '\u{1fb4}', L), ('\u{1fb6}', '\u{1fbc}', L),
('\u{1fbd}', '\u{1fbd}', ON), ('\u{1fbe}', '\u{1fbe}', L), ('\u{1fbf}', '\u{1fc1}', ON),
('\u{1fc2}', '\u{1fc4}', L), ('\u{1fc6}', '\u{1fcc}', L), ('\u{1fcd}', '\u{1fcf}', ON),
('\u{1fd0}', '\u{1fd3}', L), ('\u{1fd6}', '\u{1fdb}', L), ('\u{1fdd}', '\u{1fdf}', ON),
('\u{1fe0}', '\u{1fec}', L), ('\u{1fed}', '\u{1fef}', ON), ('\u{1ff2}', '\u{1ff4}', L),
('\u{1ff6}', '\u{1ffc}', L), ('\u{1ffd}', '\u{1ffe}', ON), ('\u{2000}', '\u{200a}', WS),
('\u{200b}', '\u{200d}', BN), ('\u{200e}', '\u{200e}', L), ('\u{200f}', '\u{200f}', R),
('\u{2010}', '\u{2027}', ON), ('\u{2028}', '\u{2028}', WS), ('\u{2029}', '\u{2029}', B),
('\u{202a}', '\u{202a}', LRE), ('\u{202b}', '\u{202b}', RLE), ('\u{202c}', '\u{202c}', PDF),
('\u{202d}', '\u{202d}', LRO), ('\u{202e}', '\u{202e}', RLO), ('\u{202f}', '\u{202f}', CS),
('\u{2030}', '\u{2034}', ET), ('\u{2035}', '\u{2043}', ON), ('\u{2044}', '\u{2044}', CS),
('\u{2045}', '\u{205e}', ON), ('\u{205f}', '\u{205f}', WS), ('\u{2060}', '\u{2064}', BN),
('\u{2066}', '\u{2066}', LRI), ('\u{2067}', '\u{2067}', RLI), ('\u{2068}', '\u{2068}', FSI),
('\u{2069}', '\u{2069}', PDI), ('\u{206a}', '\u{206f}', BN), ('\u{2070}', '\u{2070}', EN),
('\u{2071}', '\u{2071}', L), ('\u{2074}', '\u{2079}', EN), ('\u{207a}', '\u{207b}', ES),
('\u{207c}', '\u{207e}', ON), ('\u{207f}', '\u{207f}', L), ('\u{2080}', '\u{2089}', EN),
('\u{208a}', '\u{208b}', ES), ('\u{208c}', '\u{208e}', ON), ('\u{2090}', '\u{209c}', L),
('\u{20a0}', '\u{20cf}', ET), ('\u{20d0}', '\u{20f0}', NSM), ('\u{2100}', '\u{2101}', ON),
('\u{2102}', '\u{2102}', L), ('\u{2103}', '\u{2106}', ON), ('\u{2107}', '\u{2107}', L),
('\u{2108}', '\u{2109}', ON), ('\u{210a}', '\u{2113}', L), ('\u{2114}', '\u{2114}', ON),
('\u{2115}', '\u{2115}', L), ('\u{2116}', '\u{2118}', ON), ('\u{2119}', '\u{211d}', L),
('\u{211e}', '\u{2123}', ON), ('\u{2124}', '\u{2124}', L), ('\u{2125}', '\u{2125}', ON),
('\u{2126}', '\u{2126}', L), ('\u{2127}', '\u{2127}', ON), ('\u{2128}', '\u{2128}', L),
('\u{2129}', '\u{2129}', ON), ('\u{212a}', '\u{212d}', L), ('\u{212e}', '\u{212e}', ET),
('\u{212f}', '\u{2139}', L), ('\u{213a}', '\u{213b}', ON), ('\u{213c}', '\u{213f}', L),
('\u{2140}', '\u{2144}', ON), ('\u{2145}', '\u{2149}', L), ('\u{214a}', '\u{214d}', ON),
('\u{214e}', '\u{214f}', L), ('\u{2150}', '\u{215f}', ON), ('\u{2160}', '\u{2188}', L),
('\u{2189}', '\u{218b}', ON), ('\u{2190}', '\u{2211}', ON), ('\u{2212}', '\u{2212}', ES),
('\u{2213}', '\u{2213}', ET), ('\u{2214}', '\u{2335}', ON), ('\u{2336}', '\u{237a}', L),
('\u{237b}', '\u{2394}', ON), ('\u{2395}', '\u{2395}', L), ('\u{2396}', '\u{23fe}', ON),
('\u{2400}', '\u{2426}', ON), ('\u{2440}', '\u{244a}', ON), ('\u{2460}', '\u{2487}', ON),
('\u{2488}', '\u{249b}', EN), ('\u{249c}', '\u{24e9}', L), ('\u{24ea}', '\u{26ab}', ON),
('\u{26ac}', '\u{26ac}', L), ('\u{26ad}', '\u{27ff}', ON), ('\u{2800}', '\u{28ff}', L),
('\u{2900}', '\u{2b73}', ON), ('\u{2b76}', '\u{2b95}', ON), ('\u{2b98}', '\u{2bb9}', ON),
('\u{2bbd}', '\u{2bc8}', ON), ('\u{2bca}', '\u{2bd1}', ON), ('\u{2bec}', '\u{2bef}', ON),
('\u{2c00}', '\u{2c2e}', L), ('\u{2c30}', '\u{2c5e}', L), ('\u{2c60}', '\u{2ce4}', L),
('\u{2ce5}', '\u{2cea}', ON), ('\u{2ceb}', '\u{2cee}', L), ('\u{2cef}', '\u{2cf1}', NSM),
('\u{2cf2}', '\u{2cf3}', L), ('\u{2cf9}', '\u{2cff}', ON), ('\u{2d00}', '\u{2d25}', L),
('\u{2d27}', '\u{2d27}', L), ('\u{2d2d}', '\u{2d2d}', L), ('\u{2d30}', '\u{2d67}', L),
('\u{2d6f}', '\u{2d70}', L), ('\u{2d7f}', '\u{2d7f}', NSM), ('\u{2d80}', '\u{2d96}', L),
('\u{2da0}', '\u{2da6}', L), ('\u{2da8}', '\u{2dae}', L), ('\u{2db0}', '\u{2db6}', L),
('\u{2db8}', '\u{2dbe}', L), ('\u{2dc0}', '\u{2dc6}', L), ('\u{2dc8}', '\u{2dce}', L),
('\u{2dd0}', '\u{2dd6}', L), ('\u{2dd8}', '\u{2dde}', L), ('\u{2de0}', '\u{2dff}', NSM),
('\u{2e00}', '\u{2e44}', ON), ('\u{2e80}', '\u{2e99}', ON), ('\u{2e9b}', '\u{2ef3}', ON),
('\u{2f00}', '\u{2fd5}', ON), ('\u{2ff0}', '\u{2ffb}', ON), ('\u{3000}', '\u{3000}', WS),
('\u{3001}', '\u{3004}', ON), ('\u{3005}', '\u{3007}', L), ('\u{3008}', '\u{3020}', ON),
('\u{3021}', '\u{3029}', L), ('\u{302a}', '\u{302d}', NSM), ('\u{302e}', '\u{302f}', L),
('\u{3030}', '\u{3030}', ON), ('\u{3031}', '\u{3035}', L), ('\u{3036}', '\u{3037}', ON),
('\u{3038}', '\u{303c}', L), ('\u{303d}', '\u{303f}', ON), ('\u{3041}', '\u{3096}', L),
('\u{3099}', '\u{309a}', NSM), ('\u{309b}', '\u{309c}', ON), ('\u{309d}', '\u{309f}', L),
('\u{30a0}', '\u{30a0}', ON), ('\u{30a1}', '\u{30fa}', L), ('\u{30fb}', '\u{30fb}', ON),
('\u{30fc}', '\u{30ff}', L), ('\u{3105}', '\u{312d}', L), ('\u{3131}', '\u{318e}', L),
('\u{3190}', '\u{31ba}', L), ('\u{31c0}', '\u{31e3}', ON), ('\u{31f0}', '\u{321c}', L),
('\u{321d}', '\u{321e}', ON), ('\u{3220}', '\u{324f}', L), ('\u{3250}', '\u{325f}', ON),
('\u{3260}', '\u{327b}', L), ('\u{327c}', '\u{327e}', ON), ('\u{327f}', '\u{32b0}', L),
('\u{32b1}', '\u{32bf}', ON), ('\u{32c0}', '\u{32cb}', L), ('\u{32cc}', '\u{32cf}', ON),
('\u{32d0}', '\u{32fe}', L), ('\u{3300}', '\u{3376}', L), ('\u{3377}', '\u{337a}', ON),
('\u{337b}', '\u{33dd}', L), ('\u{33de}', '\u{33df}', ON), ('\u{33e0}', '\u{33fe}', L),
('\u{33ff}', '\u{33ff}', ON), ('\u{3400}', '\u{4db5}', L), ('\u{4dc0}', '\u{4dff}', ON),
('\u{4e00}', '\u{9fd5}', L), ('\u{a000}', '\u{a48c}', L), ('\u{a490}', '\u{a4c6}', ON),
('\u{a4d0}', '\u{a60c}', L), ('\u{a60d}', '\u{a60f}', ON), ('\u{a610}', '\u{a62b}', L),
('\u{a640}', '\u{a66e}', L), ('\u{a66f}', '\u{a672}', NSM), ('\u{a673}', '\u{a673}', ON),
('\u{a674}', '\u{a67d}', NSM), ('\u{a67e}', '\u{a67f}', ON), ('\u{a680}', '\u{a69d}', L),
('\u{a69e}', '\u{a69f}', NSM), ('\u{a6a0}', '\u{a6ef}', L), ('\u{a6f0}', '\u{a6f1}', NSM),
('\u{a6f2}', '\u{a6f7}', L), ('\u{a700}', '\u{a721}', ON), ('\u{a722}', '\u{a787}', L),
('\u{a788}', '\u{a788}', ON), ('\u{a789}', '\u{a7ae}', L), ('\u{a7b0}', '\u{a7b7}', L),
('\u{a7f7}', '\u{a801}', L), ('\u{a802}', '\u{a802}', NSM), ('\u{a803}', '\u{a805}', L),
('\u{a806}', '\u{a806}', NSM), ('\u{a807}', '\u{a80a}', L), ('\u{a80b}', '\u{a80b}', NSM),
('\u{a80c}', '\u{a824}', L), ('\u{a825}', '\u{a826}', NSM), ('\u{a827}', '\u{a827}', L),
('\u{a828}', '\u{a82b}', ON), ('\u{a830}', '\u{a837}', L), ('\u{a838}', '\u{a839}', ET),
('\u{a840}', '\u{a873}', L), ('\u{a874}', '\u{a877}', ON), ('\u{a880}', '\u{a8c3}', L),
('\u{a8c4}', '\u{a8c5}', NSM), ('\u{a8ce}', '\u{a8d9}', L), ('\u{a8e0}', '\u{a8f1}', NSM),
('\u{a8f2}', '\u{a8fd}', L), ('\u{a900}', '\u{a925}', L), ('\u{a926}', '\u{a92d}', NSM),
('\u{a92e}', '\u{a946}', L), ('\u{a947}', '\u{a951}', NSM), ('\u{a952}', '\u{a953}', L),
('\u{a95f}', '\u{a97c}', L), ('\u{a980}', '\u{a982}', NSM), ('\u{a983}', '\u{a9b2}', L),
('\u{a9b3}', '\u{a9b3}', NSM), ('\u{a9b4}', '\u{a9b5}', L), ('\u{a9b6}', '\u{a9b9}', NSM),
('\u{a9ba}', '\u{a9bb}', L), ('\u{a9bc}', '\u{a9bc}', NSM), ('\u{a9bd}', '\u{a9cd}', L),
('\u{a9cf}', '\u{a9d9}', L), ('\u{a9de}', '\u{a9e4}', L), ('\u{a9e5}', '\u{a9e5}', NSM),
('\u{a9e6}', '\u{a9fe}', L), ('\u{aa00}', '\u{aa28}', L), ('\u{aa29}', '\u{aa2e}', NSM),
('\u{aa2f}', '\u{aa30}', L), ('\u{aa31}', '\u{aa32}', NSM), ('\u{aa33}', '\u{aa34}', L),
('\u{aa35}', '\u{aa36}', NSM), ('\u{aa40}', '\u{aa42}', L), ('\u{aa43}', '\u{aa43}', NSM),
('\u{aa44}', '\u{aa4b}', L), ('\u{aa4c}', '\u{aa4c}', NSM), ('\u{aa4d}', '\u{aa4d}', L),
('\u{aa50}', '\u{aa59}', L), ('\u{aa5c}', '\u{aa7b}', L), ('\u{aa7c}', '\u{aa7c}', NSM),
('\u{aa7d}', '\u{aaaf}', L), ('\u{aab0}', '\u{aab0}', NSM), ('\u{aab1}', '\u{aab1}', L),
('\u{aab2}', '\u{aab4}', NSM), ('\u{aab5}', '\u{aab6}', L), ('\u{aab7}', '\u{aab8}', NSM),
('\u{aab9}', '\u{aabd}', L), ('\u{aabe}', '\u{aabf}', NSM), ('\u{aac0}', '\u{aac0}', L),
('\u{aac1}', '\u{aac1}', NSM), ('\u{aac2}', '\u{aac2}', L), ('\u{aadb}', '\u{aaeb}', L),
('\u{aaec}', '\u{aaed}', NSM), ('\u{aaee}', '\u{aaf5}', L), ('\u{aaf6}', '\u{aaf6}', NSM),
('\u{ab01}', '\u{ab06}', L), ('\u{ab09}', '\u{ab0e}', L), ('\u{ab11}', '\u{ab16}', L),
('\u{ab20}', '\u{ab26}', L), ('\u{ab28}', '\u{ab2e}', L), ('\u{ab30}', '\u{ab65}', L),
('\u{ab70}', '\u{abe4}', L), ('\u{abe5}', '\u{abe5}', NSM), ('\u{abe6}', '\u{abe7}', L),
('\u{abe8}', '\u{abe8}', NSM), ('\u{abe9}', '\u{abec}', L), ('\u{abed}', '\u{abed}', NSM),
('\u{abf0}', '\u{abf9}', L), ('\u{ac00}', '\u{d7a3}', L), ('\u{d7b0}', '\u{d7c6}', L),
('\u{d7cb}', '\u{d7fb}', L), ('\u{e000}', '\u{fa6d}', L), ('\u{fa70}', '\u{fad9}', L),
('\u{fb00}', '\u{fb06}', L), ('\u{fb13}', '\u{fb17}', L), ('\u{fb1d}', '\u{fb1d}', R),
('\u{fb1e}', '\u{fb1e}', NSM), ('\u{fb1f}', '\u{fb28}', R), ('\u{fb29}', '\u{fb29}', ES),
('\u{fb2a}', '\u{fb4f}', R), ('\u{fb50}', '\u{fd3d}', AL), ('\u{fd3e}', '\u{fd3f}', ON),
('\u{fd40}', '\u{fdcf}', AL), ('\u{fdf0}', '\u{fdfc}', AL), ('\u{fdfd}', '\u{fdfd}', ON),
('\u{fdfe}', '\u{fdff}', AL), ('\u{fe00}', '\u{fe0f}', NSM), ('\u{fe10}', '\u{fe19}', ON),
('\u{fe20}', '\u{fe2f}', NSM), ('\u{fe30}', '\u{fe4f}', ON), ('\u{fe50}', '\u{fe50}', CS),
('\u{fe51}', '\u{fe51}', ON), ('\u{fe52}', '\u{fe52}', CS), ('\u{fe54}', '\u{fe54}', ON),
('\u{fe55}', '\u{fe55}', CS), ('\u{fe56}', '\u{fe5e}', ON), ('\u{fe5f}', '\u{fe5f}', ET),
('\u{fe60}', '\u{fe61}', ON), ('\u{fe62}', '\u{fe63}', ES), ('\u{fe64}', '\u{fe66}', ON),
('\u{fe68}', '\u{fe68}', ON), ('\u{fe69}', '\u{fe6a}', ET), ('\u{fe6b}', '\u{fe6b}', ON),
('\u{fe70}', '\u{fefe}', AL), ('\u{feff}', '\u{feff}', BN), ('\u{ff01}', '\u{ff02}', ON),
('\u{ff03}', '\u{ff05}', ET), ('\u{ff06}', '\u{ff0a}', ON), ('\u{ff0b}', '\u{ff0b}', ES),
('\u{ff0c}', '\u{ff0c}', CS), ('\u{ff0d}', '\u{ff0d}', ES), ('\u{ff0e}', '\u{ff0f}', CS),
('\u{ff10}', '\u{ff19}', EN), ('\u{ff1a}', '\u{ff1a}', CS), ('\u{ff1b}', '\u{ff20}', ON),
('\u{ff21}', '\u{ff3a}', L), ('\u{ff3b}', '\u{ff40}', ON), ('\u{ff41}', '\u{ff5a}', L),
('\u{ff5b}', '\u{ff65}', ON), ('\u{ff66}', '\u{ffbe}', L), ('\u{ffc2}', '\u{ffc7}', L),
('\u{ffca}', '\u{ffcf}', L), ('\u{ffd2}', '\u{ffd7}', L), ('\u{ffda}', '\u{ffdc}', L),
('\u{ffe0}', '\u{ffe1}', ET), ('\u{ffe2}', '\u{ffe4}', ON), ('\u{ffe5}', '\u{ffe6}', ET),
('\u{ffe8}', '\u{ffee}', ON), ('\u{fff9}', '\u{fffd}', ON), ('\u{10000}', '\u{1000b}', L),
('\u{1000d}', '\u{10026}', L), ('\u{10028}', '\u{1003a}', L), ('\u{1003c}', '\u{1003d}', L),
('\u{1003f}', '\u{1004d}', L), ('\u{10050}', '\u{1005d}', L), ('\u{10080}', '\u{100fa}', L),
('\u{10100}', '\u{10100}', L), ('\u{10101}', '\u{10101}', ON), ('\u{10102}', '\u{10102}', L),
('\u{10107}', '\u{10133}', L), ('\u{10137}', '\u{1013f}', L), ('\u{10140}', '\u{1018c}', ON),
('\u{1018d}', '\u{1018e}', L), ('\u{10190}', '\u{1019b}', ON), ('\u{101a0}', '\u{101a0}', ON),
('\u{101d0}', '\u{101fc}', L), ('\u{101fd}', '\u{101fd}', NSM), ('\u{10280}', '\u{1029c}', L),
('\u{102a0}', '\u{102d0}', L), ('\u{102e0}', '\u{102e0}', NSM), ('\u{102e1}', '\u{102fb}', EN),
('\u{10300}', '\u{10323}', L), ('\u{10330}', '\u{1034a}', L), ('\u{10350}', '\u{10375}', L),
('\u{10376}', '\u{1037a}', NSM), ('\u{10380}', '\u{1039d}', L), ('\u{1039f}', '\u{103c3}', L),
('\u{103c8}', '\u{103d5}', L), ('\u{10400}', '\u{1049d}', L), ('\u{104a0}', '\u{104a9}', L),
('\u{104b0}', '\u{104d3}', L), ('\u{104d8}', '\u{104fb}', L), ('\u{10500}', '\u{10527}', L),
('\u{10530}', '\u{10563}', L), ('\u{1056f}', '\u{1056f}', L), ('\u{10600}', '\u{10736}', L),
('\u{10740}', '\u{10755}', L), ('\u{10760}', '\u{10767}', L), ('\u{10800}', '\u{1091e}', R),
('\u{1091f}', '\u{1091f}', ON), ('\u{10920}', '\u{10a00}', R), ('\u{10a01}', '\u{10a03}', NSM),
('\u{10a04}', '\u{10a04}', R), ('\u{10a05}', '\u{10a06}', NSM), ('\u{10a07}', '\u{10a0b}', R),
('\u{10a0c}', '\u{10a0f}', NSM), ('\u{10a10}', '\u{10a37}', R), ('\u{10a38}', '\u{10a3a}', NSM),
('\u{10a3b}', '\u{10a3e}', R), ('\u{10a3f}', '\u{10a3f}', NSM), ('\u{10a40}', '\u{10ae4}', R),
('\u{10ae5}', '\u{10ae6}', NSM), ('\u{10ae7}', '\u{10b38}', R), ('\u{10b39}', '\u{10b3f}', ON),
('\u{10b40}', '\u{10e5f}', R), ('\u{10e60}', '\u{10e7e}', AN), ('\u{10e7f}', '\u{10fff}', R),
('\u{11000}', '\u{11000}', L), ('\u{11001}', '\u{11001}', NSM), ('\u{11002}', '\u{11037}', L),
('\u{11038}', '\u{11046}', NSM), ('\u{11047}', '\u{1104d}', L), ('\u{11052}', '\u{11065}', ON),
('\u{11066}', '\u{1106f}', L), ('\u{1107f}', '\u{11081}', NSM), ('\u{11082}', '\u{110b2}', L),
('\u{110b3}', '\u{110b6}', NSM), ('\u{110b7}', '\u{110b8}', L), ('\u{110b9}', '\u{110ba}', NSM),
('\u{110bb}', '\u{110c1}', L), ('\u{110d0}', '\u{110e8}', L), ('\u{110f0}', '\u{110f9}', L),
('\u{11100}', '\u{11102}', NSM), ('\u{11103}', '\u{11126}', L), ('\u{11127}', '\u{1112b}', NSM),
('\u{1112c}', '\u{1112c}', L), ('\u{1112d}', '\u{11134}', NSM), ('\u{11136}', '\u{11143}', L),
('\u{11150}', '\u{11172}', L), ('\u{11173}', '\u{11173}', NSM), ('\u{11174}', '\u{11176}', L),
('\u{11180}', '\u{11181}', NSM), ('\u{11182}', '\u{111b5}', L), ('\u{111b6}', '\u{111be}', NSM),
('\u{111bf}', '\u{111c9}', L), ('\u{111ca}', '\u{111cc}', NSM), ('\u{111cd}', '\u{111cd}', L),
('\u{111d0}', '\u{111df}', L), ('\u{111e1}', '\u{111f4}', L), ('\u{11200}', '\u{11211}', L),
('\u{11213}', '\u{1122e}', L), ('\u{1122f}', '\u{11231}', NSM), ('\u{11232}', '\u{11233}', L),
('\u{11234}', '\u{11234}', NSM), ('\u{11235}', '\u{11235}', L), ('\u{11236}', '\u{11237}', NSM),
('\u{11238}', '\u{1123d}', L), ('\u{1123e}', '\u{1123e}', NSM), ('\u{11280}', '\u{11286}', L),
('\u{11288}', '\u{11288}', L), ('\u{1128a}', '\u{1128d}', L), ('\u{1128f}', '\u{1129d}', L),
('\u{1129f}', '\u{112a9}', L), ('\u{112b0}', '\u{112de}', L), ('\u{112df}', '\u{112df}', NSM),
('\u{112e0}', '\u{112e2}', L), ('\u{112e3}', '\u{112ea}', NSM), ('\u{112f0}', '\u{112f9}', L),
('\u{11300}', '\u{11301}', NSM), ('\u{11302}', '\u{11303}', L), ('\u{11305}', '\u{1130c}', L),
('\u{1130f}', '\u{11310}', L), ('\u{11313}', '\u{11328}', L), ('\u{1132a}', '\u{11330}', L),
('\u{11332}', '\u{11333}', L), ('\u{11335}', '\u{11339}', L), ('\u{1133c}', '\u{1133c}', NSM),
('\u{1133d}', '\u{1133f}', L), ('\u{11340}', '\u{11340}', NSM), ('\u{11341}', '\u{11344}', L),
('\u{11347}', '\u{11348}', L), ('\u{1134b}', '\u{1134d}', L), ('\u{11350}', '\u{11350}', L),
('\u{11357}', '\u{11357}', L), ('\u{1135d}', '\u{11363}', L), ('\u{11366}', '\u{1136c}', NSM),
('\u{11370}', '\u{11374}', NSM), ('\u{11400}', '\u{11437}', L), ('\u{11438}', '\u{1143f}', NSM),
('\u{11440}', '\u{11441}', L), ('\u{11442}', '\u{11444}', NSM), ('\u{11445}', '\u{11445}', L),
('\u{11446}', '\u{11446}', NSM), ('\u{11447}', '\u{11459}', L), ('\u{1145b}', '\u{1145b}', L),
('\u{1145d}', '\u{1145d}', L), ('\u{11480}', '\u{114b2}', L), ('\u{114b3}', '\u{114b8}', NSM),
('\u{114b9}', '\u{114b9}', L), ('\u{114ba}', '\u{114ba}', NSM), ('\u{114bb}', '\u{114be}', L),
('\u{114bf}', '\u{114c0}', NSM), ('\u{114c1}', '\u{114c1}', L), ('\u{114c2}', '\u{114c3}', NSM),
('\u{114c4}', '\u{114c7}', L), ('\u{114d0}', '\u{114d9}', L), ('\u{11580}', '\u{115b1}', L),
('\u{115b2}', '\u{115b5}', NSM), ('\u{115b8}', '\u{115bb}', L), ('\u{115bc}', '\u{115bd}', NSM),
('\u{115be}', '\u{115be}', L), ('\u{115bf}', '\u{115c0}', NSM), ('\u{115c1}', '\u{115db}', L),
('\u{115dc}', '\u{115dd}', NSM), ('\u{11600}', '\u{11632}', L), ('\u{11633}', '\u{1163a}', NSM),
('\u{1163b}', '\u{1163c}', L), ('\u{1163d}', '\u{1163d}', NSM), ('\u{1163e}', '\u{1163e}', L),
('\u{1163f}', '\u{11640}', NSM), ('\u{11641}', '\u{11644}', L), ('\u{11650}', '\u{11659}', L),
('\u{11660}', '\u{1166c}', ON), ('\u{11680}', '\u{116aa}', L), ('\u{116ab}', '\u{116ab}', NSM),
('\u{116ac}', '\u{116ac}', L), ('\u{116ad}', '\u{116ad}', NSM), ('\u{116ae}', '\u{116af}', L),
('\u{116b0}', '\u{116b5}', NSM), ('\u{116b6}', '\u{116b6}', L), ('\u{116b7}', '\u{116b7}', NSM),
('\u{116c0}', '\u{116c9}', L), ('\u{11700}', '\u{11719}', L), ('\u{1171d}', '\u{1171f}', NSM),
('\u{11720}', '\u{11721}', L), ('\u{11722}', '\u{11725}', NSM), ('\u{11726}', '\u{11726}', L),
('\u{11727}', '\u{1172b}', NSM), ('\u{11730}', '\u{1173f}', L), ('\u{118a0}', '\u{118f2}', L),
('\u{118ff}', '\u{118ff}', L), ('\u{11ac0}', '\u{11af8}', L), ('\u{11c00}', '\u{11c08}', L),
('\u{11c0a}', '\u{11c2f}', L), ('\u{11c30}', '\u{11c36}', NSM), ('\u{11c38}', '\u{11c3d}', NSM),
('\u{11c3e}', '\u{11c45}', L), ('\u{11c50}', '\u{11c6c}', L), ('\u{11c70}', '\u{11c8f}', L),
('\u{11c92}', '\u{11ca7}', NSM), ('\u{11ca9}', '\u{11ca9}', L), ('\u{11caa}', '\u{11cb0}', NSM),
('\u{11cb1}', '\u{11cb1}', L), ('\u{11cb2}', '\u{11cb3}', NSM), ('\u{11cb4}', '\u{11cb4}', L),
('\u{11cb5}', '\u{11cb6}', NSM), ('\u{12000}', '\u{12399}', L), ('\u{12400}', '\u{1246e}', L),
('\u{12470}', '\u{12474}', L), ('\u{12480}', '\u{12543}', L), ('\u{13000}', '\u{1342e}', L),
('\u{14400}', '\u{14646}', L), ('\u{16800}', '\u{16a38}', L), ('\u{16a40}', '\u{16a5e}', L),
('\u{16a60}', '\u{16a69}', L), ('\u{16a6e}', '\u{16a6f}', L), ('\u{16ad0}', '\u{16aed}', L),
('\u{16af0}', '\u{16af4}', NSM), ('\u{16af5}', '\u{16af5}', L), ('\u{16b00}', '\u{16b2f}', L),
('\u{16b30}', '\u{16b36}', NSM), ('\u{16b37}', '\u{16b45}', L), ('\u{16b50}', '\u{16b59}', L),
('\u{16b5b}', '\u{16b61}', L), ('\u{16b63}', '\u{16b77}', L), ('\u{16b7d}', '\u{16b8f}', L),
('\u{16f00}', '\u{16f44}', L), ('\u{16f50}', '\u{16f7e}', L), ('\u{16f8f}', '\u{16f92}', NSM),
('\u{16f93}', '\u{16f9f}', L), ('\u{16fe0}', '\u{16fe0}', L), ('\u{17000}', '\u{187ec}', L),
('\u{18800}', '\u{18af2}', L), ('\u{1b000}', '\u{1b001}', L), ('\u{1bc00}', '\u{1bc6a}', L),
('\u{1bc70}', '\u{1bc7c}', L), ('\u{1bc80}', '\u{1bc88}', L), ('\u{1bc90}', '\u{1bc99}', L),
('\u{1bc9c}', '\u{1bc9c}', L), ('\u{1bc9d}', '\u{1bc9e}', NSM), ('\u{1bc9f}', '\u{1bc9f}', L),
('\u{1bca0}', '\u{1bca3}', BN), ('\u{1d000}', '\u{1d0f5}', L), ('\u{1d100}', '\u{1d126}', L),
('\u{1d129}', '\u{1d166}', L), ('\u{1d167}', '\u{1d169}', NSM), ('\u{1d16a}', '\u{1d172}', L),
('\u{1d173}', '\u{1d17a}', BN), ('\u{1d17b}', '\u{1d182}', NSM), ('\u{1d183}', '\u{1d184}', L),
('\u{1d185}', '\u{1d18b}', NSM), ('\u{1d18c}', '\u{1d1a9}', L), ('\u{1d1aa}', '\u{1d1ad}', NSM),
('\u{1d1ae}', '\u{1d1e8}', L), ('\u{1d200}', '\u{1d241}', ON), ('\u{1d242}', '\u{1d244}', NSM),
('\u{1d245}', '\u{1d245}', ON), ('\u{1d300}', '\u{1d356}', ON), ('\u{1d360}', '\u{1d371}', L),
('\u{1d400}', '\u{1d454}', L), ('\u{1d456}', '\u{1d49c}', L), ('\u{1d49e}', '\u{1d49f}', L),
('\u{1d4a2}', '\u{1d4a2}', L), ('\u{1d4a5}', '\u{1d4a6}', L), ('\u{1d4a9}', '\u{1d4ac}', L),
('\u{1d4ae}', '\u{1d4b9}', L), ('\u{1d4bb}', '\u{1d4bb}', L), ('\u{1d4bd}', '\u{1d4c3}', L),
('\u{1d4c5}', '\u{1d505}', L), ('\u{1d507}', '\u{1d50a}', L), ('\u{1d50d}', '\u{1d514}', L),
('\u{1d516}', '\u{1d51c}', L), ('\u{1d51e}', '\u{1d539}', L), ('\u{1d53b}', '\u{1d53e}', L),
('\u{1d540}', '\u{1d544}', L), ('\u{1d546}', '\u{1d546}', L), ('\u{1d54a}', '\u{1d550}', L),
('\u{1d552}', '\u{1d6a5}', L), ('\u{1d6a8}', '\u{1d6da}', L), ('\u{1d6db}', '\u{1d6db}', ON),
('\u{1d6dc}', '\u{1d714}', L), ('\u{1d715}', '\u{1d715}', ON), ('\u{1d716}', '\u{1d74e}', L),
('\u{1d74f}', '\u{1d74f}', ON), ('\u{1d750}', '\u{1d788}', L), ('\u{1d789}', '\u{1d789}', ON),
('\u{1d78a}', '\u{1d7c2}', L), ('\u{1d7c3}', '\u{1d7c3}', ON), ('\u{1d7c4}', '\u{1d7cb}', L),
('\u{1d7ce}', '\u{1d7ff}', EN), ('\u{1d800}', '\u{1d9ff}', L), ('\u{1da00}', '\u{1da36}', NSM),
('\u{1da37}', '\u{1da3a}', L), ('\u{1da3b}', '\u{1da6c}', NSM), ('\u{1da6d}', '\u{1da74}', L),
('\u{1da75}', '\u{1da75}', NSM), ('\u{1da76}', '\u{1da83}', L), ('\u{1da84}', '\u{1da84}', NSM),
('\u{1da85}', '\u{1da8b}', L), ('\u{1da9b}', '\u{1da9f}', NSM), ('\u{1daa1}', '\u{1daaf}', NSM),
('\u{1e000}', '\u{1e006}', NSM), ('\u{1e008}', '\u{1e018}', NSM), ('\u{1e01b}', '\u{1e021}',
NSM), ('\u{1e023}', '\u{1e024}', NSM), ('\u{1e026}', '\u{1e02a}', NSM), ('\u{1e800}',
'\u{1e8cf}', R), ('\u{1e8d0}', '\u{1e8d6}', NSM), ('\u{1e8d7}', '\u{1e943}', R), ('\u{1e944}',
'\u{1e94a}', NSM), ('\u{1e94b}', '\u{1edff}', R), ('\u{1ee00}', '\u{1eeef}', AL), ('\u{1eef0}',
'\u{1eef1}', ON), ('\u{1eef2}', '\u{1eeff}', AL), ('\u{1ef00}', '\u{1efff}', R), ('\u{1f000}',
'\u{1f02b}', ON), ('\u{1f030}', '\u{1f093}', ON), ('\u{1f0a0}', '\u{1f0ae}', ON), ('\u{1f0b1}',
'\u{1f0bf}', ON), ('\u{1f0c1}', '\u{1f0cf}', ON), ('\u{1f0d1}', '\u{1f0f5}', ON), ('\u{1f100}',
'\u{1f10a}', EN), ('\u{1f10b}', '\u{1f10c}', ON), ('\u{1f110}', '\u{1f12e}', L), ('\u{1f130}',
'\u{1f169}', L), ('\u{1f16a}', '\u{1f16b}', ON), ('\u{1f170}', '\u{1f1ac}', L), ('\u{1f1e6}',
'\u{1f202}', L), ('\u{1f210}', '\u{1f23b}', L), ('\u{1f240}', '\u{1f248}', L), ('\u{1f250}',
'\u{1f251}', L), ('\u{1f300}', '\u{1f6d2}', ON), ('\u{1f6e0}', '\u{1f6ec}', ON), ('\u{1f6f0}',
'\u{1f6f6}', ON), ('\u{1f700}', '\u{1f773}', ON), ('\u{1f780}', '\u{1f7d4}', ON), ('\u{1f800}',
'\u{1f80b}', ON), ('\u{1f810}', '\u{1f847}', ON), ('\u{1f850}', '\u{1f859}', ON), ('\u{1f860}',
'\u{1f887}', ON), ('\u{1f890}', '\u{1f8ad}', ON), ('\u{1f910}', '\u{1f91e}', ON), ('\u{1f920}',
'\u{1f927}', ON), ('\u{1f930}', '\u{1f930}', ON), ('\u{1f933}', '\u{1f93e}', ON), ('\u{1f940}',
'\u{1f94b}', ON), ('\u{1f950}', '\u{1f95e}', ON), ('\u{1f980}', '\u{1f991}', ON), ('\u{1f9c0}',
'\u{1f9c0}', ON), ('\u{20000}', '\u{2a6d6}', L), ('\u{2a700}', '\u{2b734}', L), ('\u{2b740}',
'\u{2b81d}', L), ('\u{2b820}', '\u{2cea1}', L), ('\u{2f800}', '\u{2fa1d}', L), ('\u{e0001}',
'\u{e0001}', BN), ('\u{e0020}', '\u{e007f}', BN), ('\u{e0100}', '\u{e01ef}', NSM), ('\u{f0000}',
'\u{ffffd}', L), ('\u{100000}', '\u{10fffd}', L)
];

View File

@ -0,0 +1,88 @@
// Copyright 2015 The Servo Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! This module holds deprecated assets only.
use super::*;
/// Find the level runs within a line and return them in visual order.
///
/// NOTE: This implementation is incomplete. The algorithm needs information about the text,
/// including original BidiClass property of each character, to be able to perform correctly.
/// Please see [`BidiInfo::visual_runs()`](../struct.BidiInfo.html#method.visual_runs) for the
/// improved implementation.
///
/// `line` is a range of bytes indices within `levels`.
///
/// http://www.unicode.org/reports/tr9/#Reordering_Resolved_Levels
#[deprecated(since="0.3.0", note="please use `BidiInfo::visual_runs()` instead.")]
pub fn visual_runs(line: Range<usize>, levels: &[Level]) -> Vec<LevelRun> {
assert!(line.start <= levels.len());
assert!(line.end <= levels.len());
let mut runs = Vec::new();
// Find consecutive level runs.
let mut start = line.start;
let mut level = levels[start];
let mut min_level = level;
let mut max_level = level;
for i in (start + 1)..line.end {
let new_level = levels[i];
if new_level != level {
// End of the previous run, start of a new one.
runs.push(start..i);
start = i;
level = new_level;
min_level = min(level, min_level);
max_level = max(level, max_level);
}
}
runs.push(start..line.end);
let run_count = runs.len();
// Re-order the odd runs.
// http://www.unicode.org/reports/tr9/#L2
// Stop at the lowest *odd* level.
min_level = min_level.new_lowest_ge_rtl().expect("Level error");
while max_level >= min_level {
// Look for the start of a sequence of consecutive runs of max_level or higher.
let mut seq_start = 0;
while seq_start < run_count {
if levels[runs[seq_start].start] < max_level {
seq_start += 1;
continue;
}
// Found the start of a sequence. Now find the end.
let mut seq_end = seq_start + 1;
while seq_end < run_count {
if levels[runs[seq_end].start] < max_level {
break;
}
seq_end += 1;
}
// Reverse the runs within this sequence.
runs[seq_start..seq_end].reverse();
seq_start = seq_end;
}
max_level
.lower(1)
.expect("Lowering embedding level below zero");
}
runs
}

View File

@ -0,0 +1,190 @@
// Copyright 2015 The Servo Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! 3.3.2 Explicit Levels and Directions
//!
//! http://www.unicode.org/reports/tr9/#Explicit_Levels_and_Directions
use super::char_data::{BidiClass, is_rtl};
use super::level::Level;
use BidiClass::*;
/// Compute explicit embedding levels for one paragraph of text (X1-X8).
///
/// `processing_classes[i]` must contain the BidiClass of the char at byte index `i`,
/// for each char in `text`.
pub fn compute(
text: &str,
para_level: Level,
initial_classes: &[BidiClass],
levels: &mut [Level],
processing_classes: &mut [BidiClass],
) {
assert!(text.len() == initial_classes.len());
// http://www.unicode.org/reports/tr9/#X1
let mut stack = DirectionalStatusStack::new();
stack.push(para_level, OverrideStatus::Neutral);
let mut overflow_isolate_count = 0u32;
let mut overflow_embedding_count = 0u32;
let mut valid_isolate_count = 0u32;
for (i, c) in text.char_indices() {
match initial_classes[i] {
// Rules X2-X5c
RLE | LRE | RLO | LRO | RLI | LRI | FSI => {
let last_level = stack.last().level;
// X5a-X5c: Isolate initiators get the level of the last entry on the stack.
let is_isolate = matches!(initial_classes[i], RLI | LRI | FSI);
if is_isolate {
levels[i] = last_level;
match stack.last().status {
OverrideStatus::RTL => processing_classes[i] = R,
OverrideStatus::LTR => processing_classes[i] = L,
_ => {}
}
}
let new_level = if is_rtl(initial_classes[i]) {
last_level.new_explicit_next_rtl()
} else {
last_level.new_explicit_next_ltr()
};
if new_level.is_ok() && overflow_isolate_count == 0 &&
overflow_embedding_count == 0 {
let new_level = new_level.unwrap();
stack.push(
new_level,
match initial_classes[i] {
RLO => OverrideStatus::RTL,
LRO => OverrideStatus::LTR,
RLI | LRI | FSI => OverrideStatus::Isolate,
_ => OverrideStatus::Neutral,
},
);
if is_isolate {
valid_isolate_count += 1;
} else {
// The spec doesn't explicitly mention this step, but it is necessary.
// See the reference implementations for comparison.
levels[i] = new_level;
}
} else if is_isolate {
overflow_isolate_count += 1;
} else if overflow_isolate_count == 0 {
overflow_embedding_count += 1;
}
}
// http://www.unicode.org/reports/tr9/#X6a
PDI => {
if overflow_isolate_count > 0 {
overflow_isolate_count -= 1;
} else if valid_isolate_count > 0 {
overflow_embedding_count = 0;
loop {
// Pop everything up to and including the last Isolate status.
match stack.vec.pop() {
Some(Status { status: OverrideStatus::Isolate, .. }) => break,
None => break,
_ => continue,
}
}
valid_isolate_count -= 1;
}
let last = stack.last();
levels[i] = last.level;
match last.status {
OverrideStatus::RTL => processing_classes[i] = R,
OverrideStatus::LTR => processing_classes[i] = L,
_ => {}
}
}
// http://www.unicode.org/reports/tr9/#X7
PDF => {
if overflow_isolate_count > 0 {
continue;
}
if overflow_embedding_count > 0 {
overflow_embedding_count -= 1;
continue;
}
if stack.last().status != OverrideStatus::Isolate && stack.vec.len() >= 2 {
stack.vec.pop();
}
// The spec doesn't explicitly mention this step, but it is necessary.
// See the reference implementations for comparison.
levels[i] = stack.last().level;
}
// Nothing
B | BN => {}
// http://www.unicode.org/reports/tr9/#X6
_ => {
let last = stack.last();
levels[i] = last.level;
match last.status {
OverrideStatus::RTL => processing_classes[i] = R,
OverrideStatus::LTR => processing_classes[i] = L,
_ => {}
}
}
}
// Handle multi-byte characters.
for j in 1..c.len_utf8() {
levels[i + j] = levels[i];
processing_classes[i + j] = processing_classes[i];
}
}
}
/// Entries in the directional status stack:
struct Status {
level: Level,
status: OverrideStatus,
}
#[derive(PartialEq)]
enum OverrideStatus {
Neutral,
RTL,
LTR,
Isolate,
}
struct DirectionalStatusStack {
vec: Vec<Status>,
}
impl DirectionalStatusStack {
fn new() -> Self {
DirectionalStatusStack { vec: Vec::with_capacity(Level::max_explicit_depth() as usize + 2) }
}
fn push(&mut self, level: Level, status: OverrideStatus) {
self.vec
.push(
Status {
level: level,
status: status,
},
);
}
fn last(&self) -> &Status {
self.vec.last().unwrap()
}
}

View File

@ -0,0 +1,42 @@
// Copyright 2014 The html5ever Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Directional Formatting Characters
//!
//! http://www.unicode.org/reports/tr9/#Directional_Formatting_Characters
// == Implicit ==
/// ARABIC LETTER MARK
pub const ALM: char = '\u{061C}';
/// LEFT-TO-RIGHT MARK
pub const LRM: char = '\u{200E}';
/// RIGHT-TO-LEFT MARK
pub const RLM: char = '\u{200F}';
// == Explicit Isolates ==
/// LEFTTORIGHT ISOLATE
pub const LRI: char = '\u{2066}';
/// RIGHTTOLEFT ISOLATE
pub const RLI: char = '\u{2067}';
/// FIRST STRONG ISOLATE
pub const FSI: char = '\u{2068}';
/// POP DIRECTIONAL ISOLATE
pub const PDI: char = '\u{2069}';
// == Explicit Embeddings and Overrides ==
/// LEFT-TO-RIGHT EMBEDDING
pub const LRE: char = '\u{202A}';
/// RIGHT-TO-LEFT EMBEDDING
pub const RLE: char = '\u{202B}';
/// LEFT-TO-RIGHT OVERRIDE
pub const LRO: char = '\u{202D}';
/// RIGHT-TO-LEFT OVERRIDE
pub const RLO: char = '\u{202E}';
/// POP DIRECTIONAL FORMATTING
pub const PDF: char = '\u{202C}';

View File

@ -0,0 +1,220 @@
// Copyright 2015 The Servo Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! 3.3.4 - 3.3.6. Resolve implicit levels and types.
use std::cmp::max;
use super::char_data::BidiClass;
use super::prepare::{IsolatingRunSequence, LevelRun, not_removed_by_x9, removed_by_x9};
use super::level::Level;
use BidiClass::*;
/// 3.3.4 Resolving Weak Types
///
/// http://www.unicode.org/reports/tr9/#Resolving_Weak_Types
pub fn resolve_weak(sequence: &IsolatingRunSequence, processing_classes: &mut [BidiClass]) {
// FIXME (#8): This function applies steps W1-W6 in a single pass. This can produce
// incorrect results in cases where a "later" rule changes the value of `prev_class` seen
// by an "earlier" rule. We should either split this into separate passes, or preserve
// extra state so each rule can see the correct previous class.
let mut prev_class = sequence.sos;
let mut last_strong_is_al = false;
let mut et_run_indices = Vec::new(); // for W5
// Like sequence.runs.iter().flat_map(Clone::clone), but make indices itself clonable.
fn id(x: LevelRun) -> LevelRun {
x
}
let mut indices = sequence
.runs
.iter()
.cloned()
.flat_map(id as fn(LevelRun) -> LevelRun);
while let Some(i) = indices.next() {
match processing_classes[i] {
// http://www.unicode.org/reports/tr9/#W1
NSM => {
processing_classes[i] = match prev_class {
RLI | LRI | FSI | PDI => ON,
_ => prev_class,
};
}
EN => {
if last_strong_is_al {
// W2. If previous strong char was AL, change EN to AN.
processing_classes[i] = AN;
} else {
// W5. If a run of ETs is adjacent to an EN, change the ETs to EN.
for j in &et_run_indices {
processing_classes[*j] = EN;
}
et_run_indices.clear();
}
}
// http://www.unicode.org/reports/tr9/#W3
AL => processing_classes[i] = R,
// http://www.unicode.org/reports/tr9/#W4
ES | CS => {
let next_class = indices
.clone()
.map(|j| processing_classes[j])
.filter(not_removed_by_x9)
.next()
.unwrap_or(sequence.eos);
processing_classes[i] = match (prev_class, processing_classes[i], next_class) {
(EN, ES, EN) | (EN, CS, EN) => EN,
(AN, CS, AN) => AN,
(_, _, _) => ON,
}
}
// http://www.unicode.org/reports/tr9/#W5
ET => {
match prev_class {
EN => processing_classes[i] = EN,
_ => et_run_indices.push(i), // In case this is followed by an EN.
}
}
class => {
if removed_by_x9(class) {
continue;
}
}
}
prev_class = processing_classes[i];
match prev_class {
L | R => {
last_strong_is_al = false;
}
AL => {
last_strong_is_al = true;
}
_ => {}
}
if prev_class != ET {
// W6. If we didn't find an adjacent EN, turn any ETs into ON instead.
for j in &et_run_indices {
processing_classes[*j] = ON;
}
et_run_indices.clear();
}
}
// W7. If the previous strong char was L, change EN to L.
let mut last_strong_is_l = sequence.sos == L;
for run in &sequence.runs {
for i in run.clone() {
match processing_classes[i] {
EN if last_strong_is_l => {
processing_classes[i] = L;
}
L => {
last_strong_is_l = true;
}
R | AL => {
last_strong_is_l = false;
}
_ => {}
}
}
}
}
/// 3.3.5 Resolving Neutral Types
///
/// http://www.unicode.org/reports/tr9/#Resolving_Neutral_Types
pub fn resolve_neutral(
sequence: &IsolatingRunSequence,
levels: &[Level],
processing_classes: &mut [BidiClass],
) {
let mut indices = sequence.runs.iter().flat_map(Clone::clone);
let mut prev_class = sequence.sos;
// Neutral or Isolate formatting characters (NI).
// http://www.unicode.org/reports/tr9/#NI
fn ni(class: BidiClass) -> bool {
matches!(class, B | S | WS | ON | FSI | LRI | RLI | PDI)
}
while let Some(mut i) = indices.next() {
// N0. Process bracket pairs.
// TODO
// Process sequences of NI characters.
let mut ni_run = Vec::new();
if ni(processing_classes[i]) {
// Consume a run of consecutive NI characters.
ni_run.push(i);
let mut next_class;
loop {
match indices.next() {
Some(j) => {
i = j;
if removed_by_x9(processing_classes[i]) {
continue;
}
next_class = processing_classes[j];
if ni(next_class) {
ni_run.push(i);
} else {
break;
}
}
None => {
next_class = sequence.eos;
break;
}
};
}
// N1-N2.
let new_class = match (prev_class, next_class) {
(L, L) => L,
(R, R) | (R, AN) | (R, EN) | (AN, R) | (AN, AN) | (AN, EN) | (EN, R) |
(EN, AN) | (EN, EN) => R,
(_, _) => levels[i].bidi_class(),
};
for j in &ni_run {
processing_classes[*j] = new_class;
}
ni_run.clear();
}
prev_class = processing_classes[i];
}
}
/// 3.3.6 Resolving Implicit Levels
///
/// Returns the maximum embedding level in the paragraph.
///
/// http://www.unicode.org/reports/tr9/#Resolving_Implicit_Levels
pub fn resolve_levels(original_classes: &[BidiClass], levels: &mut [Level]) -> Level {
let mut max_level = Level::ltr();
assert!(original_classes.len() == levels.len());
for i in 0..levels.len() {
match (levels[i].is_rtl(), original_classes[i]) {
// http://www.unicode.org/reports/tr9/#I1
(false, R) => levels[i].raise(1).expect("Level number error"),
(false, AN) | (false, EN) => levels[i].raise(2).expect("Level number error"),
// http://www.unicode.org/reports/tr9/#I2
(true, L) | (true, EN) | (true, AN) => levels[i].raise(1).expect("Level number error"),
(_, _) => {}
}
max_level = max(max_level, levels[i]);
}
max_level
}

View File

@ -0,0 +1,382 @@
// Copyright 2017 The Servo Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! Bidi Embedding Level
//!
//! See [`Level`](struct.Level.html) for more details.
//!
//! http://www.unicode.org/reports/tr9/#BD2
use std::convert::{From, Into};
use super::char_data::BidiClass;
/// Embedding Level
///
/// Embedding Levels are numbers between 0 and 126 (inclusive), where even values denote a
/// left-to-right (LTR) direction and odd values a right-to-left (RTL) direction.
///
/// This struct maintains a *valid* status for level numbers, meaning that creating a new level, or
/// mutating an existing level, with the value smaller than `0` (before conversion to `u8`) or
/// larger than 125 results in an `Error`.
///
/// http://www.unicode.org/reports/tr9/#BD2
#[derive(Copy, Clone, Debug, Eq, Ord, PartialEq, PartialOrd)]
#[cfg_attr(feature = "with_serde", derive(Serialize, Deserialize))]
pub struct Level(u8);
pub const LTR_LEVEL: Level = Level(0);
pub const RTL_LEVEL: Level = Level(1);
const MAX_DEPTH: u8 = 125;
/// During explicit level resolution, embedding level can go as high as `max_depth`.
pub const MAX_EXPLICIT_DEPTH: u8 = MAX_DEPTH;
/// During implicit level resolution, embedding level can go as high as `max_depth + 1`.
pub const MAX_IMPLICIT_DEPTH: u8 = MAX_DEPTH + 1;
/// Errors that can occur on Level creation or mutation
#[derive(Debug, PartialEq)]
pub enum Error {
/// Out-of-range (invalid) embedding level number.
OutOfRangeNumber,
}
impl Level {
/// New LTR level with smallest number value (0).
#[inline]
pub fn ltr() -> Level {
LTR_LEVEL
}
/// New RTL level with smallest number value (1).
#[inline]
pub fn rtl() -> Level {
RTL_LEVEL
}
/// Maximum depth of the directional status stack during implicit resolutions.
pub fn max_implicit_depth() -> u8 {
MAX_IMPLICIT_DEPTH
}
/// Maximum depth of the directional status stack during explicit resolutions.
pub fn max_explicit_depth() -> u8 {
MAX_EXPLICIT_DEPTH
}
// == Inquiries ==
/// Create new level, fail if number is larger than `max_depth + 1`.
#[inline]
pub fn new(number: u8) -> Result<Level, Error> {
if number <= MAX_IMPLICIT_DEPTH {
Ok(Level(number))
} else {
Err(Error::OutOfRangeNumber)
}
}
/// Create new level, fail if number is larger than `max_depth`.
#[inline]
pub fn new_explicit(number: u8) -> Result<Level, Error> {
if number <= MAX_EXPLICIT_DEPTH {
Ok(Level(number))
} else {
Err(Error::OutOfRangeNumber)
}
}
// == Inquiries ==
/// The level number.
#[inline]
pub fn number(&self) -> u8 {
self.0
}
/// If this level is left-to-right.
#[inline]
pub fn is_ltr(&self) -> bool {
self.0 % 2 == 0
}
/// If this level is right-to-left.
#[inline]
pub fn is_rtl(&self) -> bool {
self.0 % 2 == 1
}
// == Mutators ==
/// Raise level by `amount`, fail if number is larger than `max_depth + 1`.
#[inline]
pub fn raise(&mut self, amount: u8) -> Result<(), Error> {
match self.0.checked_add(amount) {
Some(number) => {
if number <= MAX_IMPLICIT_DEPTH {
self.0 = number;
Ok(())
} else {
Err(Error::OutOfRangeNumber)
}
}
None => Err(Error::OutOfRangeNumber),
}
}
/// Raise level by `amount`, fail if number is larger than `max_depth`.
#[inline]
pub fn raise_explicit(&mut self, amount: u8) -> Result<(), Error> {
match self.0.checked_add(amount) {
Some(number) => {
if number <= MAX_EXPLICIT_DEPTH {
self.0 = number;
Ok(())
} else {
Err(Error::OutOfRangeNumber)
}
}
None => Err(Error::OutOfRangeNumber),
}
}
/// Lower level by `amount`, fail if number goes below zero.
#[inline]
pub fn lower(&mut self, amount: u8) -> Result<(), Error> {
match self.0.checked_sub(amount) {
Some(number) => {
self.0 = number;
Ok(())
}
None => Err(Error::OutOfRangeNumber),
}
}
// == Helpers ==
/// The next LTR (even) level greater than this, or fail if number is larger than `max_depth`.
#[inline]
pub fn new_explicit_next_ltr(&self) -> Result<Level, Error> {
Level::new_explicit(self.0 + 2 & !1)
}
/// The next RTL (odd) level greater than this, or fail if number is larger than `max_depth`.
#[inline]
pub fn new_explicit_next_rtl(&self) -> Result<Level, Error> {
Level::new_explicit((self.0 + 1) | 1)
}
/// The lowest RTL (odd) level greater than or equal to this, or fail if number is larger than
/// `max_depth + 1`.
#[inline]
pub fn new_lowest_ge_rtl(&self) -> Result<Level, Error> {
Level::new(self.0 | 1)
}
/// Generate a character type based on a level (as specified in steps X10 and N2).
#[inline]
pub fn bidi_class(&self) -> BidiClass {
if self.is_rtl() {
BidiClass::R
} else {
BidiClass::L
}
}
pub fn vec(v: &[u8]) -> Vec<Level> {
v.iter().map(|&x| x.into()).collect()
}
}
/// If levels has any RTL (odd) level
///
/// This information is usually used to skip re-ordering of text when no RTL level is present
#[inline]
pub fn has_rtl(levels: &[Level]) -> bool {
levels.iter().any(|&lvl| lvl.is_rtl())
}
impl Into<u8> for Level {
/// Convert to the level number
#[inline]
fn into(self) -> u8 {
self.number()
}
}
impl From<u8> for Level {
/// Create level by number
#[inline]
fn from(number: u8) -> Level {
Level::new(number).expect("Level number error")
}
}
/// Used for matching levels in conformance tests
impl<'a> PartialEq<&'a str> for Level {
#[inline]
fn eq(&self, s: &&'a str) -> bool {
*s == "x" || *s == self.0.to_string()
}
}
/// Used for matching levels in conformance tests
impl<'a> PartialEq<String> for Level {
#[inline]
fn eq(&self, s: &String) -> bool {
self == &s.as_str()
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_new() {
assert_eq!(Level::new(0), Ok(Level(0)));
assert_eq!(Level::new(1), Ok(Level(1)));
assert_eq!(Level::new(10), Ok(Level(10)));
assert_eq!(Level::new(125), Ok(Level(125)));
assert_eq!(Level::new(126), Ok(Level(126)));
assert_eq!(Level::new(127), Err(Error::OutOfRangeNumber));
assert_eq!(Level::new(255), Err(Error::OutOfRangeNumber));
}
#[test]
fn test_new_explicit() {
assert_eq!(Level::new_explicit(0), Ok(Level(0)));
assert_eq!(Level::new_explicit(1), Ok(Level(1)));
assert_eq!(Level::new_explicit(10), Ok(Level(10)));
assert_eq!(Level::new_explicit(125), Ok(Level(125)));
assert_eq!(Level::new_explicit(126), Err(Error::OutOfRangeNumber));
assert_eq!(Level::new_explicit(255), Err(Error::OutOfRangeNumber));
}
#[test]
fn test_is_ltr() {
assert_eq!(Level(0).is_ltr(), true);
assert_eq!(Level(1).is_ltr(), false);
assert_eq!(Level(10).is_ltr(), true);
assert_eq!(Level(11).is_ltr(), false);
assert_eq!(Level(124).is_ltr(), true);
assert_eq!(Level(125).is_ltr(), false);
}
#[test]
fn test_is_rtl() {
assert_eq!(Level(0).is_rtl(), false);
assert_eq!(Level(1).is_rtl(), true);
assert_eq!(Level(10).is_rtl(), false);
assert_eq!(Level(11).is_rtl(), true);
assert_eq!(Level(124).is_rtl(), false);
assert_eq!(Level(125).is_rtl(), true);
}
#[test]
fn test_raise() {
let mut level = Level::ltr();
assert_eq!(level.number(), 0);
assert!(level.raise(100).is_ok());
assert_eq!(level.number(), 100);
assert!(level.raise(26).is_ok());
assert_eq!(level.number(), 126);
assert!(level.raise(1).is_err()); // invalid!
assert!(level.raise(250).is_err()); // overflow!
assert_eq!(level.number(), 126);
}
#[test]
fn test_raise_explicit() {
let mut level = Level::ltr();
assert_eq!(level.number(), 0);
assert!(level.raise_explicit(100).is_ok());
assert_eq!(level.number(), 100);
assert!(level.raise_explicit(25).is_ok());
assert_eq!(level.number(), 125);
assert!(level.raise_explicit(1).is_err()); // invalid!
assert!(level.raise_explicit(250).is_err()); // overflow!
assert_eq!(level.number(), 125);
}
#[test]
fn test_lower() {
let mut level = Level::rtl();
assert_eq!(level.number(), 1);
assert!(level.lower(1).is_ok());
assert_eq!(level.number(), 0);
assert!(level.lower(1).is_err()); // underflow!
assert!(level.lower(250).is_err()); // underflow!
assert_eq!(level.number(), 0);
}
#[test]
fn test_has_rtl() {
assert_eq!(has_rtl(&Level::vec(&[0, 0, 0])), false);
assert_eq!(has_rtl(&Level::vec(&[0, 1, 0])), true);
assert_eq!(has_rtl(&Level::vec(&[0, 2, 0])), false);
assert_eq!(has_rtl(&Level::vec(&[0, 125, 0])), true);
assert_eq!(has_rtl(&Level::vec(&[0, 126, 0])), false);
}
#[test]
fn test_into() {
let level = Level::rtl();
assert_eq!(1u8, level.into());
}
#[test]
fn test_vec() {
assert_eq!(
Level::vec(&[0, 1, 125]),
vec![Level(0), Level(1), Level(125)]
);
}
#[test]
fn test_str_eq() {
assert_eq!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "x", "125"]);
assert_ne!(Level::vec(&[0, 1, 4, 125]), vec!["0", "1", "5", "125"]);
}
#[test]
fn test_string_eq() {
assert_eq!(
Level::vec(&[0, 1, 4, 125]),
vec!["0".to_string(), "1".to_string(), "x".to_string(), "125".to_string()]
);
}
}
#[cfg(all(feature = "with_serde", test))]
mod serde_tests {
use serde_test::{Token, assert_tokens};
use super::*;
#[test]
fn test_statics() {
assert_tokens(
&Level::ltr(),
&[Token::NewtypeStruct { name: "Level" }, Token::U8(0)],
);
assert_tokens(
&Level::rtl(),
&[Token::NewtypeStruct { name: "Level" }, Token::U8(1)],
);
}
#[test]
fn test_new() {
let level = Level::new(42).unwrap();
assert_tokens(
&level,
&[Token::NewtypeStruct { name: "Level" }, Token::U8(42)],
);
}
}

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,215 @@
// Copyright 2015 The Servo Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
//! 3.3.3 Preparations for Implicit Processing
//!
//! http://www.unicode.org/reports/tr9/#Preparations_for_Implicit_Processing
use std::cmp::max;
use std::ops::Range;
use super::char_data::BidiClass;
use super::level::Level;
use BidiClass::*;
/// A maximal substring of characters with the same embedding level.
///
/// Represented as a range of byte indices.
pub type LevelRun = Range<usize>;
/// Output of `isolating_run_sequences` (steps X9-X10)
pub struct IsolatingRunSequence {
pub runs: Vec<LevelRun>,
pub sos: BidiClass, // Start-of-sequence type.
pub eos: BidiClass, // End-of-sequence type.
}
/// Compute the set of isolating run sequences.
///
/// An isolating run sequence is a maximal sequence of level runs such that for all level runs
/// except the last one in the sequence, the last character of the run is an isolate initiator
/// whose matching PDI is the first character of the next level run in the sequence.
///
/// Note: This function does *not* return the sequences in order by their first characters.
pub fn isolating_run_sequences(
para_level: Level,
initial_classes: &[BidiClass],
levels: &[Level],
) -> Vec<IsolatingRunSequence> {
let runs = level_runs(levels, initial_classes);
// Compute the set of isolating run sequences.
// http://www.unicode.org/reports/tr9/#BD13
let mut sequences = Vec::with_capacity(runs.len());
// When we encounter an isolate initiator, we push the current sequence onto the
// stack so we can resume it after the matching PDI.
let mut stack = vec![Vec::new()];
for run in runs {
assert!(run.len() > 0);
assert!(stack.len() > 0);
let start_class = initial_classes[run.start];
let end_class = initial_classes[run.end - 1];
let mut sequence = if start_class == PDI && stack.len() > 1 {
// Continue a previous sequence interrupted by an isolate.
stack.pop().unwrap()
} else {
// Start a new sequence.
Vec::new()
};
sequence.push(run);
if matches!(end_class, RLI | LRI | FSI) {
// Resume this sequence after the isolate.
stack.push(sequence);
} else {
// This sequence is finished.
sequences.push(sequence);
}
}
// Pop any remaning sequences off the stack.
sequences.extend(stack.into_iter().rev().filter(|seq| seq.len() > 0));
// Determine the `sos` and `eos` class for each sequence.
// http://www.unicode.org/reports/tr9/#X10
return sequences
.into_iter()
.map(
|sequence| {
assert!(!sequence.len() > 0);
let start = sequence[0].start;
let end = sequence[sequence.len() - 1].end;
// Get the level inside these level runs.
let level = levels[start];
// Get the level of the last non-removed char before the runs.
let pred_level = match initial_classes[..start]
.iter()
.rposition(not_removed_by_x9) {
Some(idx) => levels[idx],
None => para_level,
};
// Get the level of the next non-removed char after the runs.
let succ_level = if matches!(initial_classes[end - 1], RLI | LRI | FSI) {
para_level
} else {
match initial_classes[end..].iter().position(not_removed_by_x9) {
Some(idx) => levels[idx],
None => para_level,
}
};
IsolatingRunSequence {
runs: sequence,
sos: max(level, pred_level).bidi_class(),
eos: max(level, succ_level).bidi_class(),
}
},
)
.collect();
}
/// Finds the level runs in a paragraph.
///
/// http://www.unicode.org/reports/tr9/#BD7
fn level_runs(levels: &[Level], original_classes: &[BidiClass]) -> Vec<LevelRun> {
assert!(levels.len() == original_classes.len());
let mut runs = Vec::new();
if levels.len() == 0 {
return runs;
}
let mut current_run_level = levels[0];
let mut current_run_start = 0;
for i in 1..levels.len() {
if !removed_by_x9(original_classes[i]) {
if levels[i] != current_run_level {
// End the last run and start a new one.
runs.push(current_run_start..i);
current_run_level = levels[i];
current_run_start = i;
}
}
}
runs.push(current_run_start..levels.len());
runs
}
/// Should this character be ignored in steps after X9?
///
/// http://www.unicode.org/reports/tr9/#X9
pub fn removed_by_x9(class: BidiClass) -> bool {
matches!(class, RLE | LRE | RLO | LRO | PDF | BN)
}
// For use as a predicate for `position` / `rposition`
pub fn not_removed_by_x9(class: &BidiClass) -> bool {
!removed_by_x9(*class)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_level_runs() {
let levels = &[0, 0, 0, 1, 1, 2, 0, 0];
assert_eq!(
level_runs(&Level::vec(levels), &[L; 8]),
&[0..3, 3..5, 5..6, 6..8]
);
}
/// Example 3 from http://www.unicode.org/reports/tr9/#BD13:
#[cfg_attr(rustfmt, rustfmt_skip)]
#[test]
fn test_isolating_run_sequences() {
// char index 0 1 2 3 4 5 6 7 8 9 10
let classes = &[L, RLI, AL, LRI, L, R, L, PDI, AL, PDI, L];
let levels = &[0, 0, 1, 1, 2, 3, 2, 1, 1, 0, 0];
let para_level = Level::ltr();
let sequences = isolating_run_sequences(para_level, classes, &Level::vec(levels));
let runs: Vec<Vec<LevelRun>> = sequences.iter().map(|s| s.runs.clone()).collect();
assert_eq!(
runs,
vec![vec![4..5], vec![5..6], vec![6..7], vec![2..4, 7..9], vec![0..2, 9..11]]
);
}
#[test]
fn test_removed_by_x9() {
let rem_classes = &[RLE, LRE, RLO, LRO, PDF, BN];
let not_classes = &[L, RLI, AL, LRI, PDI];
for x in rem_classes {
assert_eq!(removed_by_x9(*x), true);
}
for x in not_classes {
assert_eq!(removed_by_x9(*x), false);
}
}
#[test]
fn test_not_removed_by_x9() {
let non_x9_classes = &[L, R, AL, EN, ES, ET, AN, CS, NSM, B, S, WS, ON, LRI, RLI, FSI, PDI];
for x in non_x9_classes {
assert_eq!(not_removed_by_x9(&x), true);
}
}
}

View File

@ -0,0 +1,312 @@
// Copyright 2014 The html5ever Project Developers. See the
// COPYRIGHT file at the top-level directory of this distribution.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.
#![cfg(all(test, not(feature = "unstable")))]
extern crate unicode_bidi;
use unicode_bidi::{bidi_class, BidiInfo, format_chars, level, Level};
#[derive(Debug)]
struct Fail {
pub line_num: usize,
pub input_base_level: Option<Level>,
pub input_classes: Vec<String>,
pub input_string: String,
pub exp_base_level: Option<Level>,
pub exp_levels: Vec<String>,
pub exp_ordering: Vec<String>,
pub actual_base_level: Option<Level>,
pub actual_levels: Vec<Level>,
// TODO pub actual_ordering: Vec<String>,
}
#[test]
#[should_panic(expected = "12827 test cases failed! (243920 passed)")]
fn test_basic_conformance() {
let test_data = include_str!("data/BidiTest.txt");
// Test set state
let mut passed_num: i32 = 0;
let mut fails: Vec<Fail> = Vec::new();
let mut exp_levels: Vec<String> = Vec::new();
let mut exp_ordering: Vec<String> = Vec::new();
for (line_num, line) in test_data.lines().enumerate() {
let line = line.trim();
// Empty and comment lines
if line.is_empty() || line.starts_with('#') {
// Ignore
continue;
}
// State setting lines
if line.starts_with('@') {
let tokens: Vec<String> = line.split_whitespace().map(|x| x.to_owned()).collect();
let (setting, values) = (tokens[0].as_ref(), tokens[1..].to_vec());
match setting {
"@Levels:" => {
exp_levels = values.to_owned();
}
"@Reorder:" => {
exp_ordering = values.to_owned();
}
_ => {
// Ignore, to allow some degree of forward compatibility
}
}
continue;
}
// Data lines
{
// Levels and ordering need to be set before any data line
assert!(!exp_levels.is_empty());
assert!(exp_ordering.len() <= exp_levels.len());
let fields: Vec<&str> = line.split(';').collect();
let input_classes: Vec<&str> = fields[0].split_whitespace().collect();
let bitset: u8 = fields[1].trim().parse().unwrap();
assert!(!input_classes.is_empty());
assert!(bitset > 0);
let input_string = get_sample_string_from_bidi_classes(&input_classes);
for input_base_level in gen_base_levels_for_base_tests(bitset) {
let bidi_info = BidiInfo::new(&input_string, input_base_level);
// Check levels
let exp_levels: Vec<String> = exp_levels.iter().map(|x| x.to_owned()).collect();
let levels = gen_levels_list_from_bidi_info(&input_string, &bidi_info);
if levels != exp_levels {
fails.push(
Fail {
line_num: line_num,
input_base_level: input_base_level,
input_classes: input_classes.iter().map(|x| x.to_string()).collect(),
input_string: input_string.to_owned(),
exp_base_level: None,
exp_levels: exp_levels.to_owned(),
exp_ordering: exp_ordering.to_owned(),
actual_base_level: None,
actual_levels: levels.to_owned(),
}
);
} else {
passed_num += 1;
}
// Check reorder map
// TODO: Add reorder map to API output and test the map here
}
}
}
if !fails.is_empty() {
// TODO: Show a list of failed cases when the number is less than 1K
panic!(
"{} test cases failed! ({} passed) {{\n\
\n\
0: {:?}\n\
\n\
...\n\
\n\
{}: {:?}\n\
\n\
}}",
fails.len(),
passed_num,
fails[0],
fails.len() - 1,
fails[fails.len() - 1],
);
}
}
#[test]
#[should_panic(expected = "14558 test cases failed! (77141 passed)")]
fn test_character_conformance() {
let test_data = include_str!("data/BidiCharacterTest.txt");
// Test set state
let mut passed_num: i32 = 0;
let mut fails: Vec<Fail> = Vec::new();
for (line_num, line) in test_data.lines().enumerate() {
let line = line.trim();
// Empty and comment lines
if line.is_empty() || line.starts_with('#') {
// Ignore
continue;
}
// Data lines
{
let fields: Vec<&str> = line.split(';').collect();
let input_chars: Vec<char> = fields[0]
.split_whitespace()
.map(|cp_hex| u32::from_str_radix(cp_hex, 16).unwrap())
.map(|cp_u32| std::char::from_u32(cp_u32).unwrap())
.collect();
let input_string: String = input_chars.into_iter().collect();
let input_base_level: Option<Level> =
gen_base_level_for_characters_tests(fields[1].trim().parse().unwrap());
let exp_base_level: Level = Level::new(fields[2].trim().parse().unwrap()).unwrap();
let exp_levels: Vec<String> =
fields[3].split_whitespace().map(|x| x.to_owned()).collect();
let exp_ordering: Vec<String> =
fields[4].split_whitespace().map(|x| x.to_owned()).collect();
let bidi_info = BidiInfo::new(&input_string, input_base_level);
// Check levels
let levels = gen_levels_list_from_bidi_info(&input_string, &bidi_info);
if levels != exp_levels {
fails.push(
Fail {
line_num: line_num,
input_base_level: input_base_level,
input_classes: vec![],
input_string: input_string.to_owned(),
exp_base_level: Some(exp_base_level),
exp_levels: exp_levels.to_owned(),
exp_ordering: exp_ordering.to_owned(),
actual_base_level: None,
actual_levels: levels.to_owned(),
}
);
} else {
passed_num += 1;
}
// Check reorder map
// TODO: Add reorder map to API output and test the map here
}
}
if !fails.is_empty() {
// TODO: Show a list of failed cases when the number is less than 1K
panic!(
"{} test cases failed! ({} passed) {{\n\
\n\
0: {:?}\n\
\n\
...\n\
\n\
{}: {:?}\n\
\n\
}}",
fails.len(),
passed_num,
fails[0],
fails.len() - 1,
fails[fails.len() - 1],
);
}
}
// TODO: Support auto-RTL
fn gen_base_levels_for_base_tests(bitset: u8) -> Vec<Option<Level>> {
/// Values: auto-LTR, LTR, RTL
const VALUES: &'static [Option<Level>] = &[None, Some(level::LTR_LEVEL), Some(level::RTL_LEVEL)];
assert!(bitset < (1 << VALUES.len()));
(0..VALUES.len())
.filter(|bit| bitset & (1u8 << bit) == 1)
.map(|idx| VALUES[idx])
.collect()
}
// TODO: Support auto-RTL
fn gen_base_level_for_characters_tests(idx: usize) -> Option<Level> {
/// Values: LTR, RTL, auto-LTR
const VALUES: &'static [Option<Level>] = &[Some(level::LTR_LEVEL), Some(level::RTL_LEVEL), None];
assert!(idx < VALUES.len());
VALUES[idx]
}
/// We need to collaps levels to one-per-character from one-per-byte format.
fn gen_levels_list_from_bidi_info(input_str: &str, bidi_info: &BidiInfo) -> Vec<Level> {
let para = &bidi_info.paragraphs[0];
let levels = bidi_info.reordered_levels(para, para.range.clone());
// TODO: Move to impl BidiInfo as pub api
input_str.char_indices().map(|(i, _)| levels[i]).collect()
}
fn get_sample_string_from_bidi_classes(class_names: &[&str]) -> String {
class_names
.iter()
.map(|class_name| gen_char_from_bidi_class(class_name))
.collect()
}
/// TODO: Auto-gen in tables.rs ?
fn gen_char_from_bidi_class(class_name: &str) -> char {
match class_name {
"AL" => '\u{060b}',
"AN" => '\u{0605}',
"B" => '\u{000a}',
"BN" => '\u{0000}',
"CS" => '\u{002c}',
"EN" => '\u{0039}',
"ES" => '\u{002b}',
"ET" => '\u{0023}',
"FSI" => format_chars::FSI,
"L" => '\u{0041}',
"LRE" => format_chars::LRE,
"LRI" => format_chars::LRI,
"LRO" => format_chars::LRO,
"NSM" => '\u{0300}',
"ON" => '\u{0021}',
"PDF" => format_chars::PDF,
"PDI" => format_chars::PDI,
"R" => '\u{0590}',
"RLE" => format_chars::RLE,
"RLI" => format_chars::RLI,
"RLO" => format_chars::RLO,
"S" => '\u{0009}',
"WS" => '\u{000c}',
&_ => panic!("Invalid Bidi_Class name: {}", class_name),
}
}
#[test]
fn test_gen_char_from_bidi_class() {
use unicode_bidi::BidiClass::*;
for &class in &[
AL,
AN,
B,
BN,
CS,
EN,
ES,
ET,
FSI,
L,
LRE,
LRI,
LRO,
NSM,
ON,
PDF,
PDI,
R,
RLE,
RLI,
RLO,
S,
WS,
] {
let class_name = format!("{:?}", class);
let sample_char = gen_char_from_bidi_class(&class_name);
assert_eq!(bidi_class(sample_char), class);
}
}

View File

@ -16,33 +16,50 @@
import fileinput, re, os, sys, operator
preamble = '''// NOTE:
DATA_DIR = 'data'
TESTS_DATA_DIR = 'tests/data'
README_NAME = "ReadMe.txt"
UNICODE_DATA_NAME = "UnicodeData.txt"
TABLES_PATH = os.path.join("src", "char_data", "tables.rs")
PREAMBLE = '''// NOTE:
// The following code was generated by "tools/generate.py". do not edit directly
#![allow(missing_docs, non_upper_case_globals, non_snake_case)]
#![cfg_attr(rustfmt, rustfmt_skip)]
'''
# these are the surrogate codepoints, which are not valid rust characters
surrogate_codepoints = (0xd800, 0xdfff)
surrogate_codepoints = (0xD800, 0xDFFF)
def fetch(f):
if not os.path.exists(os.path.basename(f)):
os.system("curl -O http://www.unicode.org/Public/UNIDATA/%s"
% f)
if not os.path.exists(os.path.basename(f)):
sys.stderr.write("cannot load %s" % f)
def fetch(name, dst):
if not os.path.exists(dst):
os.system("curl -o '%s' 'http://www.unicode.org/Public/UNIDATA/%s'" % (dst, name))
if not os.path.exists(dst):
sys.stderr.write("cannot fetch %s" % name)
exit(1)
def fetch_data(name):
dst = os.path.join(DATA_DIR, os.path.basename(name))
fetch(name, dst)
def fetch_test_data(name):
dst = os.path.join(TESTS_DATA_DIR, os.path.basename(name))
fetch(name, dst)
def open_data(name):
return open(os.path.join(DATA_DIR, name))
def is_surrogate(n):
return surrogate_codepoints[0] <= n <= surrogate_codepoints[1]
def load_unicode_data(f):
fetch(f)
def load_unicode_data():
fetch_data(UNICODE_DATA_NAME)
udict = {};
range_start = -1;
for line in fileinput.input(f):
for line in fileinput.input(os.path.join(DATA_DIR, UNICODE_DATA_NAME)):
data = line.split(';');
if len(data) != 15:
continue
@ -73,25 +90,25 @@ def load_unicode_data(f):
# Default Bidi_Class for unassigned codepoints.
# http://www.unicode.org/Public/UNIDATA/extracted/DerivedBidiClass.txt
default_ranges = [
(0x0600, 0x07BF, "AL"), (0x08A0, 0x08FF, "AL"),
(0xFB50, 0xFDCF, "AL"), (0xFDF0, 0xFDFF, "AL"),
(0xFE70, 0xFEFF, "AL"), (0x1EE00, 0x0001EEFF, "AL"),
(0x0600, 0x07BF, "AL"), (0x08A0, 0x08FF, "AL"),
(0xFB50, 0xFDCF, "AL"), (0xFDF0, 0xFDFF, "AL"),
(0xFE70, 0xFEFF, "AL"), (0x1EE00, 0x1EEFF, "AL"),
(0x0590, 0x05FF, "R"), (0x07C0, 0x089F, "R"),
(0xFB1D, 0xFB4F, "R"), (0x00010800, 0x00010FFF, "R"),
(0x0001E800, 0x0001EDFF, "R"), (0x0001EF00, 0x0001EFFF, "R"),
(0x0590, 0x05FF, "R"), (0x07C0, 0x089F, "R"),
(0xFB1D, 0xFB4F, "R"), (0x10800, 0x10FFF, "R"),
(0x1E800, 0x1EDFF, "R"), (0x1EF00, 0x1EFFF, "R"),
(0x20A0, 0x20CF, "ET")]
(0x20A0, 0x20CF, "ET"),
]
for (start, end, default) in default_ranges:
for code in range(start, end+1):
if not code in udict:
bidi_class[default].append(code)
bidi_class = group_cats(bidi_class)
return bidi_class
return group_categories(bidi_class)
def group_cats(cats):
def group_categories(cats):
cats_out = []
for cat in cats:
cats_out.extend([(x, y, cat) for (x, y) in group_cat(cats[cat])])
@ -132,12 +149,18 @@ def format_table_content(f, content, indent):
def escape_char(c):
return "'\\u{%x}'" % c
def emit_table(f, name, t_data, t_type = "&'static [(char, char)]", is_pub=True,
pfun=lambda x: "(%s,%s)" % (escape_char(x[0]), escape_char(x[1]))):
pub_string = ""
def emit_table(
file_,
t_name,
t_data,
t_type = "&'static [(char, char)]",
is_pub=True,
pfun=lambda x: "(%s,%s)" % (escape_char(x[0]), escape_char(x[1]))
):
if is_pub:
pub_string = "pub "
f.write(" %sconst %s: %s = &[\n" % (pub_string, name, t_type))
file_.write("pub ")
file_.write("const %s: %s = &[\n" % (t_name, t_type))
data = ""
first = True
for dat in t_data:
@ -145,76 +168,61 @@ def emit_table(f, name, t_data, t_type = "&'static [(char, char)]", is_pub=True,
data += ","
first = False
data += pfun(dat)
format_table_content(f, data, 8)
f.write("\n ];\n\n")
format_table_content(file_, data, 4)
file_.write("\n];\n\n")
def emit_bidi_module(f, bidi_class, cats):
f.write("""pub use self::BidiClass::*;
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
/// Represents the Unicode character property **Bidi_Class**, also known as
/// the *bidirectional character type*.
///
/// Use the `bidi_class` function to look up the BidiClass of a code point.
///
/// http://www.unicode.org/reports/tr9/#Bidirectional_Character_Types
pub enum BidiClass {
def emit_bidi_module(file_, bidi_class_table, cats):
file_.write("""
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
/// Represents values of the Unicode character property
/// [Bidi_Class](http://www.unicode.org/reports/tr44/#Bidi_Class), also
/// known as the *bidirectional character type*.
///
/// * http://www.unicode.org/reports/tr9/#Bidirectional_Character_Types
/// * http://www.unicode.org/reports/tr44/#Bidi_Class_Values
pub enum BidiClass {
""")
for cat in cats:
f.write(" " + cat + ",\n")
f.write(""" }
fn bsearch_range_value_table(c: char, r: &'static [(char, char, BidiClass)]) -> BidiClass {
use ::std::cmp::Ordering::{Equal, Less, Greater};
match r.binary_search_by(|&(lo, hi, _)| {
if lo <= c && c <= hi { Equal }
else if hi < c { Less }
else { Greater }
}) {
Ok(idx) => {
let (_, _, cat) = r[idx];
cat
}
// UCD/extracted/DerivedBidiClass.txt: "All code points not explicitly listed
// for Bidi_Class have the value Left_To_Right (L)."
Err(_) => L
}
}
/// Find the BidiClass of a single char.
pub fn bidi_class(c: char) -> BidiClass {
bsearch_range_value_table(c, bidi_class_table)
}
file_.write(" " + cat + ",\n")
file_.write("""}
use self::BidiClass::*;
""")
emit_table(f, "bidi_class_table", bidi_class, "&'static [(char, char, BidiClass)]",
emit_table(
file_,
"bidi_class_table",
bidi_class_table,
"&'static [(char, char, BidiClass)]",
pfun=lambda x: "(%s,%s,%s)" % (escape_char(x[0]), escape_char(x[1]), x[2]),
is_pub=False)
)
def get_unicode_version():
fetch_data(README_NAME)
with open_data(README_NAME) as readme:
pattern = "for Version (\d+)\.(\d+)\.(\d+) of the Unicode"
return re.search(pattern, readme.read()).groups()
if __name__ == "__main__":
os.chdir("../src/") # changing download path to /unicode-bidi/src/
r = "tables.rs"
# downloading the test case files
# fetch("BidiTest.txt")
# fetch("BidiCharacterTest.txt")
# Find Unicode Version
if not os.path.exists(DATA_DIR):
os.mkdir(DATA_DIR)
unicode_version = get_unicode_version()
if os.path.exists(r):
os.remove(r)
with open(r, "w") as rf:
# write the file's preamble
rf.write(preamble)
# download and parse all the data
fetch("ReadMe.txt")
with open("ReadMe.txt") as readme:
pattern = "for Version (\d+)\.(\d+)\.(\d+) of the Unicode"
unicode_version = re.search(pattern, readme.read()).groups()
rf.write("""
/// The version of [Unicode](http://www.unicode.org/)
/// that the `bidi_class` function is based on.
# Build data tables
if os.path.exists(TABLES_PATH):
os.remove(TABLES_PATH)
with open(TABLES_PATH, "w") as file_:
file_.write(PREAMBLE)
file_.write("""
/// The [Unicode version](http://www.unicode.org/versions/) of data
pub const UNICODE_VERSION: (u64, u64, u64) = (%s, %s, %s);
""" % unicode_version)
(bidi_cats, bidi_class) = load_unicode_data("UnicodeData.txt")
emit_bidi_module(rf, bidi_class, bidi_cats)
(bidi_categories, bidi_class_table) = load_unicode_data()
emit_bidi_module(file_, bidi_class_table, bidi_categories)
# Fetch test data files
fetch_test_data("BidiTest.txt")
fetch_test_data("BidiCharacterTest.txt")

View File

@ -771,6 +771,11 @@ name = "serde"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_codegen_internals"
version = "0.14.1"
@ -789,6 +794,14 @@ dependencies = [
"syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_test"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "siphasher"
version = "0.2.1"
@ -840,6 +853,7 @@ dependencies = [
"style_traits 0.0.1",
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -997,6 +1011,17 @@ dependencies = [
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_test 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.4"
@ -1216,8 +1241,10 @@ dependencies = [
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "05a67b8a53f885f4b6e3ed183806035819f9862474e747fe4488a6d63bcbfcb7"
"checksum serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c0c3d79316a6051231925504f6ef893d45088e8823c77a8331a3dcf427ee9087"
"checksum serde_codegen_internals 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d52006899f910528a10631e5b727973fe668f3228109d1707ccf5bad5490b6e"
"checksum serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f15ea24bd037b2d64646b4d934fa99c649be66e3f7b29fb595a5543b212b1452"
"checksum serde_test 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "7d8c8022e0ec862cc1e0b73306bcd327c10de1873d1ab57794f344a7630ad46a"
"checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
"checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
@ -1236,6 +1263,7 @@ dependencies = [
"checksum time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "211b63c112206356ef1ff9b19355f43740fc3f85960c598a93d3a3d3ba7beade"
"checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4"
"checksum unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a078ebdd62c0e71a709c3d53d2af693fe09fe93fbff8344aebe289b78f9032"
"checksum unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c44d4e7ce691e2538b886bf33669fd6da1653a12d741b9390f351955c0949c03"
"checksum unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e28fa37426fceeb5cf8f41ee273faa7c82c47dc8fba5853402841e665fcd86ff"
"checksum unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18127285758f0e2c6cf325bb3f3d138a12fee27de4f23e146cd6a179f26c2cf3"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"

View File

@ -758,6 +758,11 @@ name = "serde"
version = "0.9.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde_codegen_internals"
version = "0.14.1"
@ -776,6 +781,14 @@ dependencies = [
"syn 0.11.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_test"
version = "1.0.7"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "siphasher"
version = "0.2.1"
@ -827,6 +840,7 @@ dependencies = [
"style_traits 0.0.1",
"time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)",
"toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)",
"unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)",
"walkdir 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
@ -984,6 +998,17 @@ dependencies = [
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-bidi"
version = "0.3.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"matches 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)",
"serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)",
"serde_test 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "unicode-normalization"
version = "0.1.4"
@ -1203,8 +1228,10 @@ dependencies = [
"checksum semver 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a3186ec9e65071a2095434b1f5bb24838d4e8e130f584c790f6033c79943537"
"checksum semver-parser 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "388a1df253eca08550bef6c72392cfe7c30914bf41df5269b68cbd6ff8f570a3"
"checksum serde 0.9.9 (registry+https://github.com/rust-lang/crates.io-index)" = "05a67b8a53f885f4b6e3ed183806035819f9862474e747fe4488a6d63bcbfcb7"
"checksum serde 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "c0c3d79316a6051231925504f6ef893d45088e8823c77a8331a3dcf427ee9087"
"checksum serde_codegen_internals 0.14.1 (registry+https://github.com/rust-lang/crates.io-index)" = "4d52006899f910528a10631e5b727973fe668f3228109d1707ccf5bad5490b6e"
"checksum serde_derive 0.9.11 (registry+https://github.com/rust-lang/crates.io-index)" = "f15ea24bd037b2d64646b4d934fa99c649be66e3f7b29fb595a5543b212b1452"
"checksum serde_test 1.0.7 (registry+https://github.com/rust-lang/crates.io-index)" = "7d8c8022e0ec862cc1e0b73306bcd327c10de1873d1ab57794f344a7630ad46a"
"checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
"checksum smallvec 0.3.3 (registry+https://github.com/rust-lang/crates.io-index)" = "4f8266519bc1d17d0b5b16f6c21295625d562841c708f6376f49028a43e9c11e"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
@ -1223,6 +1250,7 @@ dependencies = [
"checksum time 0.1.36 (registry+https://github.com/rust-lang/crates.io-index)" = "211b63c112206356ef1ff9b19355f43740fc3f85960c598a93d3a3d3ba7beade"
"checksum toml 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "736b60249cb25337bc196faa43ee12c705e426f3d55c214d73a4e7be06f92cb4"
"checksum unicode-bidi 0.2.5 (registry+https://github.com/rust-lang/crates.io-index)" = "d3a078ebdd62c0e71a709c3d53d2af693fe09fe93fbff8344aebe289b78f9032"
"checksum unicode-bidi 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c44d4e7ce691e2538b886bf33669fd6da1653a12d741b9390f351955c0949c03"
"checksum unicode-normalization 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "e28fa37426fceeb5cf8f41ee273faa7c82c47dc8fba5853402841e665fcd86ff"
"checksum unicode-segmentation 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18127285758f0e2c6cf325bb3f3d138a12fee27de4f23e146cd6a179f26c2cf3"
"checksum unicode-width 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "bf3a113775714a22dcb774d8ea3655c53a32debae63a063acc00a91cc586245f"