deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"6b96b2c6bfd7e1acef4b825a2813fc4277859eb9400a16800db8835c25e4087d","Cargo.toml":"41d47153a6043d3e4599f827888e1ac43c204e52ed5f6998b1e275fcae21a3cc","README.md":"9f048d969f9f8333cdcdb892744cd0816e4f2922c8817fa5e9e07f9472fe1050","src/app_unit.rs":"0f4fde2c0481b6dd021f48c8ef548090e7c577c02c429c41626c2b5e7a006949","src/lib.rs":"2df7d863c47d8b22f9af66caeafa87e6a206ee713a8aeaa55c5a80a42a92513b"},"package":"ed0a4de09a3b8449515e649f3bb84f72ea15fc2d10639beb0776a09b7d308074"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/.travis.yml
+++ /dev/null
@@ -1,8 +0,0 @@
-language: rust
-notifications:
- webhooks: http://build.servo.org:54856/travis
-
-rust:
- - stable
- - beta
- - nightly
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/Cargo.toml
+++ /dev/null
@@ -1,31 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "app_units"
-version = "0.5.6"
-authors = ["The Servo Project Developers"]
-description = "Servo app units type (Au)"
-documentation = "http://doc.servo.org/app_units/"
-license = "MPL-2.0"
-repository = "https://github.com/servo/app_units"
-[dependencies.rustc-serialize]
-version = "0.3"
-
-[dependencies.num-traits]
-version = "0.1.32"
-
-[dependencies.heapsize]
-version = ">=0.3, < 0.5"
-
-[dependencies.serde]
-version = "1.0"
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/README.md
+++ /dev/null
@@ -1,3 +0,0 @@
-# app-units
-
-[Documentation](http://doc.servo.org/app_units/index.html)
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/src/app_unit.rs
+++ /dev/null
@@ -1,388 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-use heapsize::HeapSizeOf;
-use num_traits::Zero;
-use rustc_serialize::{Encodable, Encoder};
-use serde::de::{Deserialize, Deserializer};
-use serde::ser::{Serialize, Serializer};
-use std::default::Default;
-use std::fmt;
-use std::i32;
-use std::ops::{Add, AddAssign, Div, DivAssign, Mul, MulAssign, Neg, Rem, Sub, SubAssign};
-
-/// The number of app units in a pixel.
-pub const AU_PER_PX: i32 = 60;
-
-#[derive(Clone, Copy, Hash, PartialEq, PartialOrd, Eq, Ord)]
-/// An App Unit, the fundamental unit of length in Servo. Usually
-/// 1/60th of a pixel (see AU_PER_PX)
-///
-/// Please ensure that the values are between MIN_AU and MAX_AU.
-/// It is safe to construct invalid Au values, but it may lead to
-/// panics and overflows.
-pub struct Au(pub i32);
-
-impl HeapSizeOf for Au {
- fn heap_size_of_children(&self) -> usize { 0 }
-}
-
-impl<'de> Deserialize<'de> for Au {
- fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Au, D::Error> {
- Ok(Au(try!(i32::deserialize(deserializer))).clamp())
- }
-}
-
-impl Serialize for Au {
- fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
- self.0.serialize(serializer)
- }
-}
-
-impl Default for Au {
- #[inline]
- fn default() -> Au {
- Au(0)
- }
-}
-
-impl Zero for Au {
- #[inline]
- fn zero() -> Au {
- Au(0)
- }
-
- #[inline]
- fn is_zero(&self) -> bool {
- self.0 == 0
- }
-}
-
-// (1 << 30) - 1 lets us add/subtract two Au and check for overflow
-// after the operation. Gecko uses the same min/max values
-pub const MAX_AU: Au = Au((1 << 30) - 1);
-pub const MIN_AU: Au = Au(- ((1 << 30) - 1));
-
-impl Encodable for Au {
- fn encode<S: Encoder>(&self, e: &mut S) -> Result<(), S::Error> {
- e.emit_f64(self.to_f64_px())
- }
-}
-
-impl fmt::Debug for Au {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{}px", self.to_f64_px())
- }
-}
-
-impl Add for Au {
- type Output = Au;
-
- #[inline]
- fn add(self, other: Au) -> Au {
- Au(self.0 + other.0).clamp()
- }
-}
-
-impl Sub for Au {
- type Output = Au;
-
- #[inline]
- fn sub(self, other: Au) -> Au {
- Au(self.0 - other.0).clamp()
- }
-
-}
-
-impl Mul<i32> for Au {
- type Output = Au;
-
- #[inline]
- fn mul(self, other: i32) -> Au {
- if let Some(new) = self.0.checked_mul(other) {
- Au(new).clamp()
- } else if (self.0 > 0) ^ (other > 0) {
- MIN_AU
- } else {
- MAX_AU
- }
- }
-}
-
-impl Div<i32> for Au {
- type Output = Au;
-
- #[inline]
- fn div(self, other: i32) -> Au {
- Au(self.0 / other)
- }
-}
-
-impl Rem<i32> for Au {
- type Output = Au;
-
- #[inline]
- fn rem(self, other: i32) -> Au {
- Au(self.0 % other)
- }
-}
-
-impl Neg for Au {
- type Output = Au;
-
- #[inline]
- fn neg(self) -> Au {
- Au(-self.0)
- }
-}
-
-impl AddAssign for Au {
- #[inline]
- fn add_assign(&mut self, other: Au) {
- *self = *self + other;
- self.clamp_self();
- }
-}
-
-impl SubAssign for Au {
- #[inline]
- fn sub_assign(&mut self, other: Au) {
- *self = *self - other;
- self.clamp_self();
- }
-}
-
-impl MulAssign<i32> for Au {
- #[inline]
- fn mul_assign(&mut self, other: i32) {
- *self = *self * other;
- self.clamp_self();
- }
-}
-
-impl DivAssign<i32> for Au {
- #[inline]
- fn div_assign(&mut self, other: i32) {
- *self = *self / other;
- self.clamp_self();
- }
-}
-
-impl Au {
- /// FIXME(pcwalton): Workaround for lack of cross crate inlining of newtype structs!
- #[inline]
- pub fn new(value: i32) -> Au {
- Au(value).clamp()
- }
-
- #[inline]
- fn clamp(self) -> Self {
- if self.0 > MAX_AU.0 {
- MAX_AU
- } else if self.0 < MIN_AU.0 {
- MIN_AU
- } else {
- self
- }
- }
-
- #[inline]
- fn clamp_self(&mut self) {
- *self = Au::clamp(*self)
- }
-
- #[inline]
- pub fn scale_by(self, factor: f32) -> Au {
- let new_float = ((self.0 as f64) * factor as f64).round();
- Au::from_f64_au(new_float)
- }
-
- #[inline]
- /// Scale, but truncate (useful for viewport-relative units)
- pub fn scale_by_trunc(self, factor: f32) -> Au {
- let new_float = ((self.0 as f64) * factor as f64).trunc();
- Au::from_f64_au(new_float)
- }
-
- #[inline]
- pub fn from_f64_au(float: f64) -> Self {
- // We *must* operate in f64. f32 isn't precise enough
- // to handle MAX_AU
- Au(float.min(MAX_AU.0 as f64)
- .max(MIN_AU.0 as f64)
- as i32)
- }
-
- #[inline]
- pub fn from_px(px: i32) -> Au {
- Au(px) * AU_PER_PX
- }
-
- /// Rounds this app unit down to the pixel towards zero and returns it.
- #[inline]
- pub fn to_px(self) -> i32 {
- self.0 / AU_PER_PX
- }
-
- /// Ceil this app unit to the appropriate pixel boundary and return it.
- #[inline]
- pub fn ceil_to_px(self) -> i32 {
- ((self.0 as f64) / (AU_PER_PX as f64)).ceil() as i32
- }
-
- #[inline]
- pub fn to_nearest_px(self) -> i32 {
- ((self.0 as f64) / (AU_PER_PX as f64)).round() as i32
- }
-
- #[inline]
- pub fn to_nearest_pixel(self, pixels_per_px: f32) -> f32 {
- ((self.0 as f32) / (AU_PER_PX as f32) * pixels_per_px).round() / pixels_per_px
- }
-
- #[inline]
- pub fn to_f32_px(self) -> f32 {
- (self.0 as f32) / (AU_PER_PX as f32)
- }
-
- #[inline]
- pub fn to_f64_px(self) -> f64 {
- (self.0 as f64) / (AU_PER_PX as f64)
- }
-
- #[inline]
- pub fn from_f32_px(px: f32) -> Au {
- let float = (px * AU_PER_PX as f32).round();
- Au::from_f64_au(float as f64)
- }
-
- #[inline]
- pub fn from_f64_px(px: f64) -> Au {
- let float = (px * AU_PER_PX as f64).round();
- Au::from_f64_au(float)
- }
-
- #[inline]
- pub fn abs(self) -> Self {
- Au(self.0.abs())
- }
-}
-
-#[test]
-fn create() {
- assert_eq!(Au::zero(), Au(0));
- assert_eq!(Au::default(), Au(0));
- assert_eq!(Au::new(7), Au(7));
-}
-
-#[test]
-fn operations() {
- assert_eq!(Au(7) + Au(5), Au(12));
- assert_eq!(MAX_AU + Au(1), MAX_AU);
-
- assert_eq!(Au(7) - Au(5), Au(2));
- assert_eq!(MIN_AU - Au(1), MIN_AU);
-
- assert_eq!(Au(7) * 5, Au(35));
- assert_eq!(MAX_AU * -1, MIN_AU);
- assert_eq!(MIN_AU * -1, MAX_AU);
-
- assert_eq!(Au(35) / 5, Au(7));
- assert_eq!(Au(35) % 6, Au(5));
-
- assert_eq!(-Au(7), Au(-7));
-}
-
-#[test]
-fn saturate() {
- let half = MAX_AU / 2;
- assert_eq!(half + half + half + half + half, MAX_AU);
- assert_eq!(-half - half - half - half - half, MIN_AU);
- assert_eq!(half * -10, MIN_AU);
- assert_eq!(-half * 10, MIN_AU);
- assert_eq!(half * 10, MAX_AU);
- assert_eq!(-half * -10, MAX_AU);
-}
-
-#[test]
-fn scale() {
- assert_eq!(Au(12).scale_by(1.5), Au(18));
- assert_eq!(Au(12).scale_by(1.7), Au(20));
- assert_eq!(Au(12).scale_by(1.8), Au(22));
- assert_eq!(Au(12).scale_by_trunc(1.8), Au(21));
-}
-
-#[test]
-fn abs() {
- assert_eq!(Au(-10).abs(), Au(10));
-}
-
-#[test]
-fn convert() {
- assert_eq!(Au::from_px(5), Au(300));
-
- assert_eq!(Au(300).to_px(), 5);
- assert_eq!(Au(330).to_px(), 5);
- assert_eq!(Au(350).to_px(), 5);
- assert_eq!(Au(360).to_px(), 6);
-
- assert_eq!(Au(300).ceil_to_px(), 5);
- assert_eq!(Au(310).ceil_to_px(), 6);
- assert_eq!(Au(330).ceil_to_px(), 6);
- assert_eq!(Au(350).ceil_to_px(), 6);
- assert_eq!(Au(360).ceil_to_px(), 6);
-
- assert_eq!(Au(300).to_nearest_px(), 5);
- assert_eq!(Au(310).to_nearest_px(), 5);
- assert_eq!(Au(330).to_nearest_px(), 6);
- assert_eq!(Au(350).to_nearest_px(), 6);
- assert_eq!(Au(360).to_nearest_px(), 6);
-
- assert_eq!(Au(60).to_nearest_pixel(2.), 1.);
- assert_eq!(Au(70).to_nearest_pixel(2.), 1.);
- assert_eq!(Au(80).to_nearest_pixel(2.), 1.5);
- assert_eq!(Au(90).to_nearest_pixel(2.), 1.5);
- assert_eq!(Au(100).to_nearest_pixel(2.), 1.5);
- assert_eq!(Au(110).to_nearest_pixel(2.), 2.);
- assert_eq!(Au(120).to_nearest_pixel(2.), 2.);
-
- assert_eq!(Au(300).to_f32_px(), 5.);
- assert_eq!(Au(312).to_f32_px(), 5.2);
- assert_eq!(Au(330).to_f32_px(), 5.5);
- assert_eq!(Au(348).to_f32_px(), 5.8);
- assert_eq!(Au(360).to_f32_px(), 6.);
- assert_eq!((Au(367).to_f32_px() * 1000.).round(), 6_117.);
- assert_eq!((Au(368).to_f32_px() * 1000.).round(), 6_133.);
-
- assert_eq!(Au(300).to_f64_px(), 5.);
- assert_eq!(Au(312).to_f64_px(), 5.2);
- assert_eq!(Au(330).to_f64_px(), 5.5);
- assert_eq!(Au(348).to_f64_px(), 5.8);
- assert_eq!(Au(360).to_f64_px(), 6.);
- assert_eq!((Au(367).to_f64_px() * 1000.).round(), 6_117.);
- assert_eq!((Au(368).to_f64_px() * 1000.).round(), 6_133.);
-
- assert_eq!(Au::from_f32_px(5.), Au(300));
- assert_eq!(Au::from_f32_px(5.2), Au(312));
- assert_eq!(Au::from_f32_px(5.5), Au(330));
- assert_eq!(Au::from_f32_px(5.8), Au(348));
- assert_eq!(Au::from_f32_px(6.), Au(360));
- assert_eq!(Au::from_f32_px(6.12), Au(367));
- assert_eq!(Au::from_f32_px(6.13), Au(368));
-
- assert_eq!(Au::from_f64_px(5.), Au(300));
- assert_eq!(Au::from_f64_px(5.2), Au(312));
- assert_eq!(Au::from_f64_px(5.5), Au(330));
- assert_eq!(Au::from_f64_px(5.8), Au(348));
- assert_eq!(Au::from_f64_px(6.), Au(360));
- assert_eq!(Au::from_f64_px(6.12), Au(367));
- assert_eq!(Au::from_f64_px(6.13), Au(368));
-}
-
-#[test]
-fn heapsize() {
- use heapsize::HeapSizeOf;
- fn f<T: HeapSizeOf>(_: T) {}
- f(Au::new(0));
-}
deleted file mode 100644
--- a/third_party/rust/app_units-0.5.6/src/lib.rs
+++ /dev/null
@@ -1,16 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//! An Au is an "App Unit" and represents 1/60th of a CSS pixel. It was
-//! originally proposed in 2002 as a standard unit of measure in Gecko.
-//! See https://bugzilla.mozilla.org/show_bug.cgi?id=177805 for more info.
-
-extern crate heapsize;
-extern crate num_traits;
-extern crate rustc_serialize;
-extern crate serde;
-
-mod app_unit;
-
-pub use app_unit::{Au, MIN_AU, MAX_AU, AU_PER_PX};
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"13574ca06216b94913348afb2beae9db9929f8964fbc45b3c00344ee281e1f52","COPYRIGHT":"ec82b96487e9e778ee610c7ab245162464782cfa1f555c2299333f8dbe5c036a","Cargo.toml":"1951103509b9ee4036df52e5f11c9d1e2ba18c09eab673de25c37ad1f6dabab4","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"62065228e42caebca7e7d7db1204cbb867033de5982ca4009928915e4095f3a3","README.md":"625bec69c76ce5423fdd05cfe46922b2680ec517f97c5854ce34798d1d8a9541","src/approxeq.rs":"6cf810ad389c73a27141a7a67454ed12d4b01c3c16605b9a7414b389bc0615dd","src/length.rs":"73b0aed12a0c9acfd77a6b9ac0cd3a7ec522c41ffafad4448753cb6bba47b6a4","src/lib.rs":"43b594eebf1cd2c8fb7a7f4616d872d9e09f5e0c7c0172a16d4e5841ab552328","src/macros.rs":"a3f4deaa4323da6398546720548dda20b0b39427603ccc35ab49d220a83467a8","src/num.rs":"749b201289fc6663199160a2f9204e17925fd3053f8ab7779e7bfb377ad06227","src/point.rs":"859e3da88bf45123b10d90642b807b9ef35751699594d85012cb32b45e9e970b","src/rect.rs":"761b3e1c841c03ec87e99ed9dd9c37d669bec6967c2dac2b6be2f056e9c8b7e0","src/rotation.rs":"0b0a299268a76fbc15c58aec788ad0bfc27f7f68bcfeade3dce71cd2585166f2","src/scale_factor.rs":"b093243256df3f2b8a2e2bf98236e6ec1032c3d358596f384313614dbefaca49","src/side_offsets.rs":"fd95ffc9a74e9e84314875c388e763d0780486eb7f9034423e3a22048361e379","src/size.rs":"5ecb66be6c42f07770662c925017a7ef6e1d0e332b3576e1884c488fbf9d4b59","src/transform2d.rs":"82b5a41881fc4ab947df0b337ad2ac2e1dce7d532df1a225eb5abf2d32776007","src/transform3d.rs":"3b944cae37968b3c4e98a25323ac57ba331d97638b0a747fff28f139fcb6043c","src/trig.rs":"ef290927af252ca90a29ba9f17158b591ed591604e66cb9df045dd47b9cfdca5","src/vector.rs":"7f076e77a9a6fbecf44c1802233e9c2d59015a94cccf94fd9d8832cfb037bdb8"},"package":"f5ed7d77e46f6600f490463ad7b6349c3ebb2d2319af56e679e279e4c66495d9"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/.travis.yml
+++ /dev/null
@@ -1,24 +0,0 @@
-language: rust
-rust:
- - 1.17.0
- - stable
- - beta
- - nightly
-
-notifications:
- webhooks: http://build.servo.org:54856/travis
-
-matrix:
- include:
- - rust: stable
- env: FEATURES=""
- - rust: beta
- env: FEATURES=""
- - rust: nightly
- env: FEATURES=""
- - rust: nightly
- env: FEATURES="unstable"
-
-script:
- - cargo build --verbose --features "$FEATURES"
- - cargo test --verbose --features "$FEATURES"
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/COPYRIGHT
+++ /dev/null
@@ -1,5 +0,0 @@
-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.
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/Cargo.toml
+++ /dev/null
@@ -1,42 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "euclid"
-version = "0.15.5"
-authors = ["The Servo Project Developers"]
-description = "Geometry primitives"
-documentation = "https://docs.rs/euclid/"
-keywords = ["matrix", "vector", "linear-algebra", "geometry"]
-categories = ["science"]
-license = "MIT / Apache-2.0"
-repository = "https://github.com/servo/euclid"
-[dependencies.heapsize]
-version = "0.4"
-
-[dependencies.num-traits]
-version = "0.1.32"
-default-features = false
-
-[dependencies.log]
-version = "0.3.1"
-
-[dependencies.serde]
-version = "1.0"
-[dev-dependencies.serde_test]
-version = "1.0"
-
-[dev-dependencies.rand]
-version = "0.3.7"
-
-[features]
-unstable = []
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/LICENSE-APACHE
+++ /dev/null
@@ -1,201 +0,0 @@
- 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.
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/LICENSE-MIT
+++ /dev/null
@@ -1,25 +0,0 @@
-Copyright (c) 2012-2013 Mozilla Foundation
-
-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.
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/README.md
+++ /dev/null
@@ -1,8 +0,0 @@
-# euclid
-
-This is a small library for geometric types with a focus on 2d graphics and
-layout.
-
-* [Documentation](https://docs.rs/euclid/)
-* [Release notes](https://github.com/servo/euclid/releases)
-* [crates.io](https://crates.io/crates/euclid)
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/approxeq.rs
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2013 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.
-
-
-/// Trait for testing approximate equality
-pub trait ApproxEq<Eps> {
- fn approx_epsilon() -> Eps;
- fn approx_eq(&self, other: &Self) -> bool;
- fn approx_eq_eps(&self, other: &Self, approx_epsilon: &Eps) -> bool;
-}
-
-macro_rules! approx_eq {
- ($ty:ty, $eps:expr) => (
- impl ApproxEq<$ty> for $ty {
- #[inline]
- fn approx_epsilon() -> $ty { $eps }
- #[inline]
- fn approx_eq(&self, other: &$ty) -> bool {
- self.approx_eq_eps(other, &$eps)
- }
- #[inline]
- fn approx_eq_eps(&self, other: &$ty, approx_epsilon: &$ty) -> bool {
- (*self - *other).abs() < *approx_epsilon
- }
- }
- )
-}
-
-approx_eq!(f32, 1.0e-6);
-approx_eq!(f64, 1.0e-6);
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/length.rs
+++ /dev/null
@@ -1,461 +0,0 @@
-// Copyright 2014 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.
-//! A one-dimensional length, tagged with its units.
-
-use scale_factor::ScaleFactor;
-use num::Zero;
-
-use heapsize::HeapSizeOf;
-use num_traits::{NumCast, Saturating};
-use num::One;
-use serde::{Deserialize, Deserializer, Serialize, Serializer};
-use std::cmp::Ordering;
-use std::ops::{Add, Sub, Mul, Div, Neg};
-use std::ops::{AddAssign, SubAssign};
-use std::marker::PhantomData;
-use std::fmt;
-
-/// A one-dimensional distance, with value represented by `T` and unit of measurement `Unit`.
-///
-/// `T` can be any numeric type, for example a primitive type like `u64` or `f32`.
-///
-/// `Unit` is not used in the representation of a `Length` value. It is used only at compile time
-/// to ensure that a `Length` stored with one unit is converted explicitly before being used in an
-/// expression that requires a different unit. It may be a type without values, such as an empty
-/// enum.
-///
-/// You can multiply a `Length` by a `scale_factor::ScaleFactor` to convert it from one unit to
-/// another. See the `ScaleFactor` docs for an example.
-// Uncomment the derive, and remove the macro call, once heapsize gets
-// PhantomData<T> support.
-#[repr(C)]
-pub struct Length<T, Unit>(pub T, PhantomData<Unit>);
-
-impl<T: Clone, Unit> Clone for Length<T, Unit> {
- fn clone(&self) -> Self {
- Length(self.0.clone(), PhantomData)
- }
-}
-
-impl<T: Copy, Unit> Copy for Length<T, Unit> {}
-
-impl<Unit, T: HeapSizeOf> HeapSizeOf for Length<T, Unit> {
- fn heap_size_of_children(&self) -> usize {
- self.0.heap_size_of_children()
- }
-}
-
-impl<'de, Unit, T> Deserialize<'de> for Length<T, Unit> where T: Deserialize<'de> {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where D: Deserializer<'de> {
- Ok(Length(try!(Deserialize::deserialize(deserializer)), PhantomData))
- }
-}
-
-impl<T, Unit> Serialize for Length<T, Unit> where T: Serialize {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
- self.0.serialize(serializer)
- }
-}
-
-impl<T, Unit> Length<T, Unit> {
- pub fn new(x: T) -> Self {
- Length(x, PhantomData)
- }
-}
-
-impl<Unit, T: Clone> Length<T, Unit> {
- pub fn get(&self) -> T {
- self.0.clone()
- }
-}
-
-impl<T: fmt::Debug + Clone, U> fmt::Debug for Length<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.get().fmt(f)
- }
-}
-
-impl<T: fmt::Display + Clone, U> fmt::Display for Length<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.get().fmt(f)
- }
-}
-
-// length + length
-impl<U, T: Clone + Add<T, Output=T>> Add for Length<T, U> {
- type Output = Length<T, U>;
- fn add(self, other: Length<T, U>) -> Length<T, U> {
- Length::new(self.get() + other.get())
- }
-}
-
-// length += length
-impl<U, T: Clone + AddAssign<T>> AddAssign for Length<T, U> {
- fn add_assign(&mut self, other: Length<T, U>) {
- self.0 += other.get();
- }
-}
-
-// length - length
-impl<U, T: Clone + Sub<T, Output=T>> Sub<Length<T, U>> for Length<T, U> {
- type Output = Length<T, U>;
- fn sub(self, other: Length<T, U>) -> <Self as Sub>::Output {
- Length::new(self.get() - other.get())
- }
-}
-
-// length -= length
-impl<U, T: Clone + SubAssign<T>> SubAssign for Length<T, U> {
- fn sub_assign(&mut self, other: Length<T, U>) {
- self.0 -= other.get();
- }
-}
-
-// Saturating length + length and length - length.
-impl<U, T: Clone + Saturating> Saturating for Length<T, U> {
- fn saturating_add(self, other: Length<T, U>) -> Length<T, U> {
- Length::new(self.get().saturating_add(other.get()))
- }
-
- fn saturating_sub(self, other: Length<T, U>) -> Length<T, U> {
- Length::new(self.get().saturating_sub(other.get()))
- }
-}
-
-// length / length
-impl<Src, Dst, T: Clone + Div<T, Output=T>> Div<Length<T, Src>> for Length<T, Dst> {
- type Output = ScaleFactor<T, Src, Dst>;
- #[inline]
- fn div(self, other: Length<T, Src>) -> ScaleFactor<T, Src, Dst> {
- ScaleFactor::new(self.get() / other.get())
- }
-}
-
-// length * scaleFactor
-impl<Src, Dst, T: Clone + Mul<T, Output=T>> Mul<ScaleFactor<T, Src, Dst>> for Length<T, Src> {
- type Output = Length<T, Dst>;
- #[inline]
- fn mul(self, scale: ScaleFactor<T, Src, Dst>) -> Length<T, Dst> {
- Length::new(self.get() * scale.get())
- }
-}
-
-// length / scaleFactor
-impl<Src, Dst, T: Clone + Div<T, Output=T>> Div<ScaleFactor<T, Src, Dst>> for Length<T, Dst> {
- type Output = Length<T, Src>;
- #[inline]
- fn div(self, scale: ScaleFactor<T, Src, Dst>) -> Length<T, Src> {
- Length::new(self.get() / scale.get())
- }
-}
-
-// -length
-impl <U, T:Clone + Neg<Output=T>> Neg for Length<T, U> {
- type Output = Length<T, U>;
- #[inline]
- fn neg(self) -> Length<T, U> {
- Length::new(-self.get())
- }
-}
-
-impl<Unit, T0: NumCast + Clone> Length<T0, Unit> {
- /// Cast from one numeric representation to another, preserving the units.
- pub fn cast<T1: NumCast + Clone>(&self) -> Option<Length<T1, Unit>> {
- NumCast::from(self.get()).map(Length::new)
- }
-}
-
-impl<Unit, T: Clone + PartialEq> PartialEq for Length<T, Unit> {
- fn eq(&self, other: &Self) -> bool { self.get().eq(&other.get()) }
-}
-
-impl<Unit, T: Clone + PartialOrd> PartialOrd for Length<T, Unit> {
- fn partial_cmp(&self, other: &Self) -> Option<Ordering> {
- self.get().partial_cmp(&other.get())
- }
-}
-
-impl<Unit, T: Clone + Eq> Eq for Length<T, Unit> {}
-
-impl<Unit, T: Clone + Ord> Ord for Length<T, Unit> {
- fn cmp(&self, other: &Self) -> Ordering { self.get().cmp(&other.get()) }
-}
-
-impl<Unit, T: Zero> Zero for Length<T, Unit> {
- fn zero() -> Self {
- Length::new(Zero::zero())
- }
-}
-
-impl<T, U> Length<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
- /// Linearly interpolate between this length and another length.
- ///
- /// `t` is expected to be between zero and one.
- #[inline]
- pub fn lerp(&self, other: Self, t: T) -> Self {
- let one_t = T::one() - t;
- Length::new(one_t * self.get() + t * other.get())
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::Length;
- use num::Zero;
-
- use heapsize::HeapSizeOf;
- use num_traits::Saturating;
- use scale_factor::ScaleFactor;
- use std::f32::INFINITY;
-
- extern crate serde_test;
- use self::serde_test::Token;
- use self::serde_test::assert_tokens;
-
- enum Inch {}
- enum Mm {}
- enum Cm {}
- enum Second {}
-
- #[test]
- fn test_clone() {
- // A cloned Length is a separate length with the state matching the
- // original Length at the point it was cloned.
- let mut variable_length: Length<f32, Inch> = Length::new(12.0);
-
- let one_foot = variable_length.clone();
- variable_length.0 = 24.0;
-
- assert_eq!(one_foot.get(), 12.0);
- assert_eq!(variable_length.get(), 24.0);
- }
-
- #[test]
- fn test_heapsizeof_builtins() {
- // Heap size of built-ins is zero by default.
- let one_foot: Length<f32, Inch> = Length::new(12.0);
-
- let heap_size_length_f32 = one_foot.heap_size_of_children();
-
- assert_eq!(heap_size_length_f32, 0);
- }
-
- #[test]
- fn test_heapsizeof_length_vector() {
- // Heap size of any Length is just the heap size of the length value.
- for n in 0..5 {
- let length: Length<Vec<f32>, Inch> = Length::new(Vec::with_capacity(n));
-
- assert_eq!(length.heap_size_of_children(), length.0.heap_size_of_children());
- }
- }
-
- #[test]
- fn test_length_serde() {
- let one_cm: Length<f32, Mm> = Length::new(10.0);
-
- assert_tokens(&one_cm, &[Token::F32(10.0)]);
- }
-
- #[test]
- fn test_get_clones_length_value() {
- // Calling get returns a clone of the Length's value.
- // To test this, we need something clone-able - hence a vector.
- let mut length: Length<Vec<i32>, Inch> = Length::new(vec![1, 2, 3]);
-
- let value = length.get();
- length.0.push(4);
-
- assert_eq!(value, vec![1, 2, 3]);
- assert_eq!(length.get(), vec![1, 2, 3, 4]);
- }
-
- #[test]
- fn test_fmt_debug() {
- // Debug and display format the value only.
- let one_cm: Length<f32, Mm> = Length::new(10.0);
-
- let result = format!("{:?}", one_cm);
-
- assert_eq!(result, "10");
- }
-
- #[test]
- fn test_fmt_display() {
- // Debug and display format the value only.
- let one_cm: Length<f32, Mm> = Length::new(10.0);
-
- let result = format!("{}", one_cm);
-
- assert_eq!(result, "10");
- }
-
- #[test]
- fn test_add() {
- let length1: Length<u8, Mm> = Length::new(250);
- let length2: Length<u8, Mm> = Length::new(5);
-
- let result = length1 + length2;
-
- assert_eq!(result.get(), 255);
- }
-
- #[test]
- fn test_addassign() {
- let one_cm: Length<f32, Mm> = Length::new(10.0);
- let mut measurement: Length<f32, Mm> = Length::new(5.0);
-
- measurement += one_cm;
-
- assert_eq!(measurement.get(), 15.0);
- }
-
- #[test]
- fn test_sub() {
- let length1: Length<u8, Mm> = Length::new(250);
- let length2: Length<u8, Mm> = Length::new(5);
-
- let result = length1 - length2;
-
- assert_eq!(result.get(), 245);
- }
-
- #[test]
- fn test_subassign() {
- let one_cm: Length<f32, Mm> = Length::new(10.0);
- let mut measurement: Length<f32, Mm> = Length::new(5.0);
-
- measurement -= one_cm;
-
- assert_eq!(measurement.get(), -5.0);
- }
-
- #[test]
- fn test_saturating_add() {
- let length1: Length<u8, Mm> = Length::new(250);
- let length2: Length<u8, Mm> = Length::new(6);
-
- let result = length1.saturating_add(length2);
-
- assert_eq!(result.get(), 255);
- }
-
- #[test]
- fn test_saturating_sub() {
- let length1: Length<u8, Mm> = Length::new(5);
- let length2: Length<u8, Mm> = Length::new(10);
-
- let result = length1.saturating_sub(length2);
-
- assert_eq!(result.get(), 0);
- }
-
- #[test]
- fn test_division_by_length() {
- // Division results in a ScaleFactor from denominator units
- // to numerator units.
- let length: Length<f32, Cm> = Length::new(5.0);
- let duration: Length<f32, Second> = Length::new(10.0);
-
- let result = length / duration;
-
- let expected: ScaleFactor<f32, Second, Cm> = ScaleFactor::new(0.5);
- assert_eq!(result, expected);
- }
-
- #[test]
- fn test_multiplication() {
- let length_mm: Length<f32, Mm> = Length::new(10.0);
- let cm_per_mm: ScaleFactor<f32, Mm, Cm> = ScaleFactor::new(0.1);
-
- let result = length_mm * cm_per_mm;
-
- let expected: Length<f32, Cm> = Length::new(1.0);
- assert_eq!(result, expected);
- }
-
- #[test]
- fn test_division_by_scalefactor() {
- let length: Length<f32, Cm> = Length::new(5.0);
- let cm_per_second: ScaleFactor<f32, Second, Cm> = ScaleFactor::new(10.0);
-
- let result = length / cm_per_second;
-
- let expected: Length<f32, Second> = Length::new(0.5);
- assert_eq!(result, expected);
- }
-
- #[test]
- fn test_negation() {
- let length: Length<f32, Cm> = Length::new(5.0);
-
- let result = -length;
-
- let expected: Length<f32, Cm> = Length::new(-5.0);
- assert_eq!(result, expected);
- }
-
- #[test]
- fn test_cast() {
- let length_as_i32: Length<i32, Cm> = Length::new(5);
-
- let result: Length<f32, Cm> = length_as_i32.cast().unwrap();
-
- let length_as_f32: Length<f32, Cm> = Length::new(5.0);
- assert_eq!(result, length_as_f32);
- }
-
- #[test]
- fn test_equality() {
- let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
- let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
- let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
-
- assert!(length_5_point_0 == length_5_point_1 - length_0_point_1);
- assert!(length_5_point_0 != length_5_point_1);
- }
-
- #[test]
- fn test_order() {
- let length_5_point_0: Length<f32, Cm> = Length::new(5.0);
- let length_5_point_1: Length<f32, Cm> = Length::new(5.1);
- let length_0_point_1: Length<f32, Cm> = Length::new(0.1);
-
- assert!(length_5_point_0 < length_5_point_1);
- assert!(length_5_point_0 <= length_5_point_1);
- assert!(length_5_point_0 <= length_5_point_1 - length_0_point_1);
- assert!(length_5_point_1 > length_5_point_0);
- assert!(length_5_point_1 >= length_5_point_0);
- assert!(length_5_point_0 >= length_5_point_1 - length_0_point_1);
- }
-
- #[test]
- fn test_zero_add() {
- type LengthCm = Length<f32, Cm>;
- let length: LengthCm = Length::new(5.0);
-
- let result = length - LengthCm::zero();
-
- assert_eq!(result, length);
- }
-
- #[test]
- fn test_zero_division() {
- type LengthCm = Length<f32, Cm>;
- let length: LengthCm = Length::new(5.0);
- let length_zero: LengthCm = Length::zero();
-
- let result = length / length_zero;
-
- let expected: ScaleFactor<f32, Cm, Cm> = ScaleFactor::new(INFINITY);
- assert_eq!(result, expected);
- }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/lib.rs
+++ /dev/null
@@ -1,136 +0,0 @@
-// Copyright 2013 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.
-
-#![cfg_attr(feature = "unstable", feature(asm, repr_simd, test, fn_must_use))]
-
-//! A collection of strongly typed math tools for computer graphics with an inclination
-//! towards 2d graphics and layout.
-//!
-//! All types are generic over the scalar type of their component (`f32`, `i32`, etc.),
-//! and tagged with a generic Unit parameter which is useful to prevent mixing
-//! values from different spaces. For example it should not be legal to translate
-//! a screen-space position by a world-space vector and this can be expressed using
-//! the generic Unit parameter.
-//!
-//! This unit system is not mandatory and all Typed* structures have an alias
-//! with the default unit: `UnknownUnit`.
-//! for example ```Point2D<T>``` is equivalent to ```TypedPoint2D<T, UnknownUnit>```.
-//! Client code typically creates a set of aliases for each type and doesn't need
-//! to deal with the specifics of typed units further. For example:
-//!
-//! ```rust
-//! use euclid::*;
-//! pub struct ScreenSpace;
-//! pub type ScreenPoint = TypedPoint2D<f32, ScreenSpace>;
-//! pub type ScreenSize = TypedSize2D<f32, ScreenSpace>;
-//! pub struct WorldSpace;
-//! pub type WorldPoint = TypedPoint3D<f32, WorldSpace>;
-//! pub type ProjectionMatrix = TypedTransform3D<f32, WorldSpace, ScreenSpace>;
-//! // etc...
-//! ```
-//!
-//! All euclid types are marked `#[repr(C)]` in order to facilitate exposing them to
-//! foreign function interfaces (provided the underlying scalar type is also `repr(C)`).
-//!
-//! Components are accessed in their scalar form by default for convenience, and most
-//! types additionally implement strongly typed accessors which return typed ```Length``` wrappers.
-//! For example:
-//!
-//! ```rust
-//! # use euclid::*;
-//! # pub struct WorldSpace;
-//! # pub type WorldPoint = TypedPoint3D<f32, WorldSpace>;
-//! let p = WorldPoint::new(0.0, 1.0, 1.0);
-//! // p.x is an f32.
-//! println!("p.x = {:?} ", p.x);
-//! // p.x is a Length<f32, WorldSpace>.
-//! println!("p.x_typed() = {:?} ", p.x_typed());
-//! // Length::get returns the scalar value (f32).
-//! assert_eq!(p.x, p.x_typed().get());
-//! ```
-
-extern crate heapsize;
-
-#[cfg_attr(test, macro_use)]
-extern crate log;
-extern crate serde;
-
-#[cfg(test)]
-extern crate rand;
-#[cfg(feature = "unstable")]
-extern crate test;
-extern crate num_traits;
-
-pub use length::Length;
-pub use scale_factor::ScaleFactor;
-pub use transform2d::{Transform2D, TypedTransform2D};
-pub use transform3d::{Transform3D, TypedTransform3D};
-pub use point::{
- Point2D, TypedPoint2D, point2,
- Point3D, TypedPoint3D, point3,
-};
-pub use vector::{
- Vector2D, TypedVector2D, vec2,
- Vector3D, TypedVector3D, vec3,
-};
-
-pub use rect::{Rect, TypedRect, rect};
-pub use rotation::{TypedRotation2D, Rotation2D, TypedRotation3D, Rotation3D};
-pub use side_offsets::{SideOffsets2D, TypedSideOffsets2D};
-#[cfg(feature = "unstable")] pub use side_offsets::SideOffsets2DSimdI32;
-pub use size::{Size2D, TypedSize2D, size2};
-pub use trig::Trig;
-
-pub mod approxeq;
-pub mod num;
-mod length;
-#[macro_use]
-mod macros;
-mod transform2d;
-mod transform3d;
-mod point;
-mod rect;
-mod rotation;
-mod scale_factor;
-mod side_offsets;
-mod size;
-mod trig;
-mod vector;
-
-/// The default unit.
-#[derive(Clone, Copy)]
-pub struct UnknownUnit;
-
-/// Unit for angles in radians.
-pub struct Rad;
-
-/// Unit for angles in degrees.
-pub struct Deg;
-
-/// A value in radians.
-pub type Radians<T> = Length<T, Rad>;
-
-/// A value in Degrees.
-pub type Degrees<T> = Length<T, Deg>;
-
-/// Temporary alias to facilitate the transition to the new naming scheme
-#[deprecated]
-pub type Matrix2D<T> = Transform2D<T>;
-
-/// Temporary alias to facilitate the transition to the new naming scheme
-#[deprecated]
-pub type TypedMatrix2D<T, Src, Dst> = TypedTransform2D<T, Src, Dst>;
-
-/// Temporary alias to facilitate the transition to the new naming scheme
-#[deprecated]
-pub type Matrix4D<T> = Transform3D<T>;
-
-/// Temporary alias to facilitate the transition to the new naming scheme
-#[deprecated]
-pub type TypedMatrix4D<T, Src, Dst> = TypedTransform3D<T, Src, Dst>;
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/macros.rs
+++ /dev/null
@@ -1,87 +0,0 @@
-// Copyright 2013 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.
-
-macro_rules! define_matrix {
- (
- $(#[$attr:meta])*
- pub struct $name:ident<T, $($phantom:ident),+> {
- $(pub $field:ident: T,)+
- }
- ) => (
- #[repr(C)]
- $(#[$attr])*
- pub struct $name<T, $($phantom),+> {
- $(pub $field: T,)+
- _unit: PhantomData<($($phantom),+)>
- }
-
- impl<T: Clone, $($phantom),+> Clone for $name<T, $($phantom),+> {
- fn clone(&self) -> Self {
- $name {
- $($field: self.$field.clone(),)+
- _unit: PhantomData,
- }
- }
- }
-
- impl<T: Copy, $($phantom),+> Copy for $name<T, $($phantom),+> {}
-
- impl<T, $($phantom),+> ::heapsize::HeapSizeOf for $name<T, $($phantom),+>
- where T: ::heapsize::HeapSizeOf
- {
- fn heap_size_of_children(&self) -> usize {
- $(self.$field.heap_size_of_children() +)+ 0
- }
- }
-
- impl<'de, T, $($phantom),+> ::serde::Deserialize<'de> for $name<T, $($phantom),+>
- where T: ::serde::Deserialize<'de>
- {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where D: ::serde::Deserializer<'de>
- {
- let ($($field,)+) =
- try!(::serde::Deserialize::deserialize(deserializer));
- Ok($name {
- $($field: $field,)+
- _unit: PhantomData,
- })
- }
- }
-
- impl<T, $($phantom),+> ::serde::Serialize for $name<T, $($phantom),+>
- where T: ::serde::Serialize
- {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where S: ::serde::Serializer
- {
- ($(&self.$field,)+).serialize(serializer)
- }
- }
-
- impl<T, $($phantom),+> ::std::cmp::Eq for $name<T, $($phantom),+>
- where T: ::std::cmp::Eq {}
-
- impl<T, $($phantom),+> ::std::cmp::PartialEq for $name<T, $($phantom),+>
- where T: ::std::cmp::PartialEq
- {
- fn eq(&self, other: &Self) -> bool {
- true $(&& self.$field == other.$field)+
- }
- }
-
- impl<T, $($phantom),+> ::std::hash::Hash for $name<T, $($phantom),+>
- where T: ::std::hash::Hash
- {
- fn hash<H: ::std::hash::Hasher>(&self, h: &mut H) {
- $(self.$field.hash(h);)+
- }
- }
- )
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/num.rs
+++ /dev/null
@@ -1,77 +0,0 @@
-// Copyright 2014 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.
-//! A one-dimensional length, tagged with its units.
-
-use num_traits;
-
-
-pub trait Zero {
- fn zero() -> Self;
-}
-
-impl<T: num_traits::Zero> Zero for T {
- fn zero() -> T { num_traits::Zero::zero() }
-}
-
-pub trait One {
- fn one() -> Self;
-}
-
-impl<T: num_traits::One> One for T {
- fn one() -> T { num_traits::One::one() }
-}
-
-
-pub trait Round : Copy { fn round(self) -> Self; }
-pub trait Floor : Copy { fn floor(self) -> Self; }
-pub trait Ceil : Copy { fn ceil(self) -> Self; }
-
-macro_rules! num_int {
- ($ty:ty) => (
- impl Round for $ty {
- #[inline]
- fn round(self) -> $ty { self }
- }
- impl Floor for $ty {
- #[inline]
- fn floor(self) -> $ty { self }
- }
- impl Ceil for $ty {
- #[inline]
- fn ceil(self) -> $ty { self }
- }
- )
-}
-macro_rules! num_float {
- ($ty:ty) => (
- impl Round for $ty {
- #[inline]
- fn round(self) -> $ty { self.round() }
- }
- impl Floor for $ty {
- #[inline]
- fn floor(self) -> $ty { self.floor() }
- }
- impl Ceil for $ty {
- #[inline]
- fn ceil(self) -> $ty { self.ceil() }
- }
- )
-}
-
-num_int!(i16);
-num_int!(u16);
-num_int!(i32);
-num_int!(u32);
-num_int!(i64);
-num_int!(u64);
-num_int!(isize);
-num_int!(usize);
-num_float!(f32);
-num_float!(f64);
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/point.rs
+++ /dev/null
@@ -1,834 +0,0 @@
-// Copyright 2013 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.
-
-use super::UnknownUnit;
-use approxeq::ApproxEq;
-use length::Length;
-use scale_factor::ScaleFactor;
-use size::TypedSize2D;
-use num::*;
-use num_traits::{Float, NumCast};
-use vector::{TypedVector2D, TypedVector3D, vec2, vec3};
-use std::fmt;
-use std::ops::{Add, Mul, Sub, Div, AddAssign, SubAssign, MulAssign, DivAssign};
-use std::marker::PhantomData;
-
-define_matrix! {
- /// A 2d Point tagged with a unit.
- pub struct TypedPoint2D<T, U> {
- pub x: T,
- pub y: T,
- }
-}
-
-/// Default 2d point type with no unit.
-///
-/// `Point2D` provides the same methods as `TypedPoint2D`.
-pub type Point2D<T> = TypedPoint2D<T, UnknownUnit>;
-
-impl<T: Copy + Zero, U> TypedPoint2D<T, U> {
- /// Constructor, setting all components to zero.
- #[inline]
- pub fn origin() -> Self {
- point2(Zero::zero(), Zero::zero())
- }
-
- #[inline]
- pub fn zero() -> Self {
- Self::origin()
- }
-
- /// Convert into a 3d point.
- #[inline]
- pub fn to_3d(&self) -> TypedPoint3D<T, U> {
- point3(self.x, self.y, Zero::zero())
- }
-}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedPoint2D<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "({:?},{:?})", self.x, self.y)
- }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedPoint2D<T, U> {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- write!(formatter, "({},{})", self.x, self.y)
- }
-}
-
-impl<T: Copy, U> TypedPoint2D<T, U> {
- /// Constructor taking scalar values directly.
- #[inline]
- pub fn new(x: T, y: T) -> Self {
- TypedPoint2D { x: x, y: y, _unit: PhantomData }
- }
-
- /// Constructor taking properly typed Lengths instead of scalar values.
- #[inline]
- pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
- point2(x.0, y.0)
- }
-
- /// Create a 3d point from this one, using the specified z value.
- #[inline]
- pub fn extend(&self, z: T) -> TypedPoint3D<T, U> {
- point3(self.x, self.y, z)
- }
-
- /// Cast this point into a vector.
- ///
- /// Equivalent to subtracting the origin from this point.
- #[inline]
- pub fn to_vector(&self) -> TypedVector2D<T, U> {
- vec2(self.x, self.y)
- }
-
- /// Swap x and y.
- #[inline]
- pub fn yx(&self) -> Self {
- point2(self.y, self.x)
- }
-
- /// Returns self.x as a Length carrying the unit.
- #[inline]
- pub fn x_typed(&self) -> Length<T, U> { Length::new(self.x) }
-
- /// Returns self.y as a Length carrying the unit.
- #[inline]
- pub fn y_typed(&self) -> Length<T, U> { Length::new(self.y) }
-
- /// Drop the units, preserving only the numeric value.
- #[inline]
- pub fn to_untyped(&self) -> Point2D<T> {
- point2(self.x, self.y)
- }
-
- /// Tag a unitless value with units.
- #[inline]
- pub fn from_untyped(p: &Point2D<T>) -> Self {
- point2(p.x, p.y)
- }
-
- #[inline]
- pub fn to_array(&self) -> [T; 2] {
- [self.x, self.y]
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> TypedPoint2D<T, U> {
- #[inline]
- pub fn add_size(&self, other: &TypedSize2D<T, U>) -> Self {
- point2(self.x + other.width, self.y + other.height)
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add<TypedSize2D<T, U>> for TypedPoint2D<T, U> {
- type Output = Self;
- #[inline]
- fn add(self, other: TypedSize2D<T, U>) -> Self {
- point2(self.x + other.width, self.y + other.height)
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> AddAssign<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
- #[inline]
- fn add_assign(&mut self, other: TypedVector2D<T, U>) {
- *self = *self + other
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> SubAssign<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
- #[inline]
- fn sub_assign(&mut self, other: TypedVector2D<T, U>) {
- *self = *self - other
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
- type Output = Self;
- #[inline]
- fn add(self, other: TypedVector2D<T, U>) -> Self {
- point2(self.x + other.x, self.y + other.y)
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub for TypedPoint2D<T, U> {
- type Output = TypedVector2D<T, U>;
- #[inline]
- fn sub(self, other: Self) -> TypedVector2D<T, U> {
- vec2(self.x - other.x, self.y - other.y)
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub<TypedVector2D<T, U>> for TypedPoint2D<T, U> {
- type Output = Self;
- #[inline]
- fn sub(self, other: TypedVector2D<T, U>) -> Self {
- point2(self.x - other.x, self.y - other.y)
- }
-}
-
-impl<T: Float, U> TypedPoint2D<T, U> {
- #[inline]
- pub fn min(self, other: Self) -> Self {
- point2(self.x.min(other.x), self.y.min(other.y))
- }
-
- #[inline]
- pub fn max(self, other: Self) -> Self {
- point2(self.x.max(other.x), self.y.max(other.y))
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedPoint2D<T, U> {
- type Output = Self;
- #[inline]
- fn mul(self, scale: T) -> Self {
- point2(self.x * scale, self.y * scale)
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> MulAssign<T> for TypedPoint2D<T, U> {
- #[inline]
- fn mul_assign(&mut self, scale: T) {
- *self = *self * scale
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedPoint2D<T, U> {
- type Output = Self;
- #[inline]
- fn div(self, scale: T) -> Self {
- point2(self.x / scale, self.y / scale)
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> DivAssign<T> for TypedPoint2D<T, U> {
- #[inline]
- fn div_assign(&mut self, scale: T) {
- *self = *self / scale
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U1, U2> Mul<ScaleFactor<T, U1, U2>> for TypedPoint2D<T, U1> {
- type Output = TypedPoint2D<T, U2>;
- #[inline]
- fn mul(self, scale: ScaleFactor<T, U1, U2>) -> TypedPoint2D<T, U2> {
- point2(self.x * scale.get(), self.y * scale.get())
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U1, U2> Div<ScaleFactor<T, U1, U2>> for TypedPoint2D<T, U2> {
- type Output = TypedPoint2D<T, U1>;
- #[inline]
- fn div(self, scale: ScaleFactor<T, U1, U2>) -> TypedPoint2D<T, U1> {
- point2(self.x / scale.get(), self.y / scale.get())
- }
-}
-
-impl<T: Round, U> TypedPoint2D<T, U> {
- /// Rounds each component to the nearest integer value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- /// For example `{ -0.1, -0.8 }.round() == { 0.0, -1.0 }`.
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn round(&self) -> Self {
- point2(self.x.round(), self.y.round())
- }
-}
-
-impl<T: Ceil, U> TypedPoint2D<T, U> {
- /// Rounds each component to the smallest integer equal or greater than the original value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- /// For example `{ -0.1, -0.8 }.ceil() == { 0.0, 0.0 }`.
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn ceil(&self) -> Self {
- point2(self.x.ceil(), self.y.ceil())
- }
-}
-
-impl<T: Floor, U> TypedPoint2D<T, U> {
- /// Rounds each component to the biggest integer equal or lower than the original value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- /// For example `{ -0.1, -0.8 }.floor() == { -1.0, -1.0 }`.
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn floor(&self) -> Self {
- point2(self.x.floor(), self.y.floor())
- }
-}
-
-impl<T: NumCast + Copy, U> TypedPoint2D<T, U> {
- /// Cast from one numeric representation to another, preserving the units.
- ///
- /// When casting from floating point to integer coordinates, the decimals are truncated
- /// as one would expect from a simple cast, but this behavior does not always make sense
- /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
- #[inline]
- pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedPoint2D<NewT, U>> {
- match (NumCast::from(self.x), NumCast::from(self.y)) {
- (Some(x), Some(y)) => Some(point2(x, y)),
- _ => None
- }
- }
-
- // Convenience functions for common casts
-
- /// Cast into an `f32` point.
- #[inline]
- pub fn to_f32(&self) -> TypedPoint2D<f32, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an `usize` point, truncating decimals if any.
- ///
- /// When casting from floating point points, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_usize(&self) -> TypedPoint2D<usize, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an i32 point, truncating decimals if any.
- ///
- /// When casting from floating point points, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_i32(&self) -> TypedPoint2D<i32, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an i64 point, truncating decimals if any.
- ///
- /// When casting from floating point points, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_i64(&self) -> TypedPoint2D<i64, U> {
- self.cast().unwrap()
- }
-}
-
-impl<T, U> TypedPoint2D<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
- /// Linearly interpolate between this point and another point.
- ///
- /// `t` is expected to be between zero and one.
- #[inline]
- pub fn lerp(&self, other: Self, t: T) -> Self {
- let one_t = T::one() - t;
- point2(
- one_t * self.x + t * other.x,
- one_t * self.y + t * other.y,
- )
- }
-}
-
-impl<T: Copy+ApproxEq<T>, U> ApproxEq<TypedPoint2D<T, U>> for TypedPoint2D<T, U> {
- #[inline]
- fn approx_epsilon() -> Self {
- point2(T::approx_epsilon(), T::approx_epsilon())
- }
-
- #[inline]
- fn approx_eq(&self, other: &Self) -> bool {
- self.x.approx_eq(&other.x) && self.y.approx_eq(&other.y)
- }
-
- #[inline]
- fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
- self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
- }
-}
-
-impl<T: Copy, U> Into<[T; 2]> for TypedPoint2D<T, U> {
- fn into(self) -> [T; 2] {
- self.to_array()
- }
-}
-
-impl<T: Copy, U> From<[T; 2]> for TypedPoint2D<T, U> {
- fn from(array: [T; 2]) -> Self {
- point2(array[0], array[1])
- }
-}
-
-
-define_matrix! {
- /// A 3d Point tagged with a unit.
- pub struct TypedPoint3D<T, U> {
- pub x: T,
- pub y: T,
- pub z: T,
- }
-}
-
-/// Default 3d point type with no unit.
-///
-/// `Point3D` provides the same methods as `TypedPoint3D`.
-pub type Point3D<T> = TypedPoint3D<T, UnknownUnit>;
-
-impl<T: Copy + Zero, U> TypedPoint3D<T, U> {
- /// Constructor, setting all copmonents to zero.
- #[inline]
- pub fn origin() -> Self {
- point3(Zero::zero(), Zero::zero(), Zero::zero())
- }
-}
-
-impl<T: Copy + One, U> TypedPoint3D<T, U> {
- #[inline]
- pub fn to_array_4d(&self) -> [T; 4] {
- [self.x, self.y, self.z, One::one()]
- }
-}
-
-impl<T, U> TypedPoint3D<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
- /// Linearly interpolate between this point and another point.
- ///
- /// `t` is expected to be between zero and one.
- #[inline]
- pub fn lerp(&self, other: Self, t: T) -> Self {
- let one_t = T::one() - t;
- point3(
- one_t * self.x + t * other.x,
- one_t * self.y + t * other.y,
- one_t * self.z + t * other.z,
- )
- }
-}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedPoint3D<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "({:?},{:?},{:?})", self.x, self.y, self.z)
- }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedPoint3D<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "({},{},{})", self.x, self.y, self.z)
- }
-}
-
-impl<T: Copy, U> TypedPoint3D<T, U> {
- /// Constructor taking scalar values directly.
- #[inline]
- pub fn new(x: T, y: T, z: T) -> Self {
- TypedPoint3D { x: x, y: y, z: z, _unit: PhantomData }
- }
-
- /// Constructor taking properly typed Lengths instead of scalar values.
- #[inline]
- pub fn from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> Self {
- point3(x.0, y.0, z.0)
- }
-
- /// Cast this point into a vector.
- ///
- /// Equivalent to substracting the origin to this point.
- #[inline]
- pub fn to_vector(&self) -> TypedVector3D<T, U> {
- vec3(self.x, self.y, self.z)
- }
-
- /// Returns a 2d point using this point's x and y coordinates
- #[inline]
- pub fn xy(&self) -> TypedPoint2D<T, U> {
- point2(self.x, self.y)
- }
-
- /// Returns a 2d point using this point's x and z coordinates
- #[inline]
- pub fn xz(&self) -> TypedPoint2D<T, U> {
- point2(self.x, self.z)
- }
-
- /// Returns a 2d point using this point's x and z coordinates
- #[inline]
- pub fn yz(&self) -> TypedPoint2D<T, U> {
- point2(self.y, self.z)
- }
-
- /// Returns self.x as a Length carrying the unit.
- #[inline]
- pub fn x_typed(&self) -> Length<T, U> { Length::new(self.x) }
-
- /// Returns self.y as a Length carrying the unit.
- #[inline]
- pub fn y_typed(&self) -> Length<T, U> { Length::new(self.y) }
-
- /// Returns self.z as a Length carrying the unit.
- #[inline]
- pub fn z_typed(&self) -> Length<T, U> { Length::new(self.z) }
-
- #[inline]
- pub fn to_array(&self) -> [T; 3] { [self.x, self.y, self.z] }
-
- /// Drop the units, preserving only the numeric value.
- #[inline]
- pub fn to_untyped(&self) -> Point3D<T> {
- point3(self.x, self.y, self.z)
- }
-
- /// Tag a unitless value with units.
- #[inline]
- pub fn from_untyped(p: &Point3D<T>) -> Self {
- point3(p.x, p.y, p.z)
- }
-
- /// Convert into a 2d point.
- #[inline]
- pub fn to_2d(&self) -> TypedPoint2D<T, U> {
- self.xy()
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> AddAssign<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
- #[inline]
- fn add_assign(&mut self, other: TypedVector3D<T, U>) {
- *self = *self + other
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> SubAssign<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
- #[inline]
- fn sub_assign(&mut self, other: TypedVector3D<T, U>) {
- *self = *self - other
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
- type Output = Self;
- #[inline]
- fn add(self, other: TypedVector3D<T, U>) -> Self {
- point3(self.x + other.x, self.y + other.y, self.z + other.z)
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub for TypedPoint3D<T, U> {
- type Output = TypedVector3D<T, U>;
- #[inline]
- fn sub(self, other: Self) -> TypedVector3D<T, U> {
- vec3(self.x - other.x, self.y - other.y, self.z - other.z)
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub<TypedVector3D<T, U>> for TypedPoint3D<T, U> {
- type Output = Self;
- #[inline]
- fn sub(self, other: TypedVector3D<T, U>) -> Self {
- point3(self.x - other.x, self.y - other.y, self.z - other.z)
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedPoint3D<T, U> {
- type Output = Self;
- #[inline]
- fn mul(self, scale: T) -> Self {
- point3(self.x * scale, self.y * scale, self.z * scale)
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedPoint3D<T, U> {
- type Output = Self;
- #[inline]
- fn div(self, scale: T) -> Self {
- point3(self.x / scale, self.y / scale, self.z / scale)
- }
-}
-
-impl<T: Float, U> TypedPoint3D<T, U> {
- #[inline]
- pub fn min(self, other: Self) -> Self {
- point3(self.x.min(other.x), self.y.min(other.y), self.z.min(other.z))
- }
-
- #[inline]
- pub fn max(self, other: Self) -> Self {
- point3(self.x.max(other.x), self.y.max(other.y), self.z.max(other.z))
- }
-}
-
-impl<T: Round, U> TypedPoint3D<T, U> {
- /// Rounds each component to the nearest integer value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn round(&self) -> Self {
- point3(self.x.round(), self.y.round(), self.z.round())
- }
-}
-
-impl<T: Ceil, U> TypedPoint3D<T, U> {
- /// Rounds each component to the smallest integer equal or greater than the original value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn ceil(&self) -> Self {
- point3(self.x.ceil(), self.y.ceil(), self.z.ceil())
- }
-}
-
-impl<T: Floor, U> TypedPoint3D<T, U> {
- /// Rounds each component to the biggest integer equal or lower than the original value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn floor(&self) -> Self {
- point3(self.x.floor(), self.y.floor(), self.z.floor())
- }
-}
-
-impl<T: NumCast + Copy, U> TypedPoint3D<T, U> {
- /// Cast from one numeric representation to another, preserving the units.
- ///
- /// When casting from floating point to integer coordinates, the decimals are truncated
- /// as one would expect from a simple cast, but this behavior does not always make sense
- /// geometrically. Consider using round(), ceil or floor() before casting.
- #[inline]
- pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedPoint3D<NewT, U>> {
- match (NumCast::from(self.x),
- NumCast::from(self.y),
- NumCast::from(self.z)) {
- (Some(x), Some(y), Some(z)) => Some(point3(x, y, z)),
- _ => None
- }
- }
-
- // Convenience functions for common casts
-
- /// Cast into an `f32` point.
- #[inline]
- pub fn to_f32(&self) -> TypedPoint3D<f32, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an `usize` point, truncating decimals if any.
- ///
- /// When casting from floating point points, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_usize(&self) -> TypedPoint3D<usize, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an `i32` point, truncating decimals if any.
- ///
- /// When casting from floating point points, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_i32(&self) -> TypedPoint3D<i32, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an `i64` point, truncating decimals if any.
- ///
- /// When casting from floating point points, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_i64(&self) -> TypedPoint3D<i64, U> {
- self.cast().unwrap()
- }
-}
-
-impl<T: Copy+ApproxEq<T>, U> ApproxEq<TypedPoint3D<T, U>> for TypedPoint3D<T, U> {
- #[inline]
- fn approx_epsilon() -> Self {
- point3(T::approx_epsilon(), T::approx_epsilon(), T::approx_epsilon())
- }
-
- #[inline]
- fn approx_eq(&self, other: &Self) -> bool {
- self.x.approx_eq(&other.x)
- && self.y.approx_eq(&other.y)
- && self.z.approx_eq(&other.z)
- }
-
- #[inline]
- fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
- self.x.approx_eq_eps(&other.x, &eps.x)
- && self.y.approx_eq_eps(&other.y, &eps.y)
- && self.z.approx_eq_eps(&other.z, &eps.z)
- }
-}
-
-impl<T: Copy, U> Into<[T; 3]> for TypedPoint3D<T, U> {
- fn into(self) -> [T; 3] {
- self.to_array()
- }
-}
-
-impl<T: Copy, U> From<[T; 3]> for TypedPoint3D<T, U> {
- fn from(array: [T; 3]) -> Self {
- point3(array[0], array[1], array[2])
- }
-}
-
-
-pub fn point2<T: Copy, U>(x: T, y: T) -> TypedPoint2D<T, U> {
- TypedPoint2D::new(x, y)
-}
-
-pub fn point3<T: Copy, U>(x: T, y: T, z: T) -> TypedPoint3D<T, U> {
- TypedPoint3D::new(x, y, z)
-}
-
-#[cfg(test)]
-mod point2d {
- use super::Point2D;
-
- #[test]
- pub fn test_scalar_mul() {
- let p1: Point2D<f32> = Point2D::new(3.0, 5.0);
-
- let result = p1 * 5.0;
-
- assert_eq!(result, Point2D::new(15.0, 25.0));
- }
-
- #[test]
- pub fn test_min() {
- let p1 = Point2D::new(1.0, 3.0);
- let p2 = Point2D::new(2.0, 2.0);
-
- let result = p1.min(p2);
-
- assert_eq!(result, Point2D::new(1.0, 2.0));
- }
-
- #[test]
- pub fn test_max() {
- let p1 = Point2D::new(1.0, 3.0);
- let p2 = Point2D::new(2.0, 2.0);
-
- let result = p1.max(p2);
-
- assert_eq!(result, Point2D::new(2.0, 3.0));
- }
-}
-
-#[cfg(test)]
-mod typedpoint2d {
- use super::{TypedPoint2D, Point2D, point2};
- use scale_factor::ScaleFactor;
- use vector::vec2;
-
- pub enum Mm {}
- pub enum Cm {}
-
- pub type Point2DMm<T> = TypedPoint2D<T, Mm>;
- pub type Point2DCm<T> = TypedPoint2D<T, Cm>;
-
- #[test]
- pub fn test_add() {
- let p1 = Point2DMm::new(1.0, 2.0);
- let p2 = vec2(3.0, 4.0);
-
- let result = p1 + p2;
-
- assert_eq!(result, Point2DMm::new(4.0, 6.0));
- }
-
- #[test]
- pub fn test_add_assign() {
- let mut p1 = Point2DMm::new(1.0, 2.0);
- p1 += vec2(3.0, 4.0);
-
- assert_eq!(p1, Point2DMm::new(4.0, 6.0));
- }
-
- #[test]
- pub fn test_scalar_mul() {
- let p1 = Point2DMm::new(1.0, 2.0);
- let cm_per_mm: ScaleFactor<f32, Mm, Cm> = ScaleFactor::new(0.1);
-
- let result = p1 * cm_per_mm;
-
- assert_eq!(result, Point2DCm::new(0.1, 0.2));
- }
-
- #[test]
- pub fn test_conv_vector() {
- use {Point2D, point2};
-
- for i in 0..100 {
- // We don't care about these values as long as they are not the same.
- let x = i as f32 *0.012345;
- let y = i as f32 *0.987654;
- let p: Point2D<f32> = point2(x, y);
- assert_eq!(p.to_vector().to_point(), p);
- }
- }
-
- #[test]
- pub fn test_swizzling() {
- let p: Point2D<i32> = point2(1, 2);
- assert_eq!(p.yx(), point2(2, 1));
- }
-}
-
-#[cfg(test)]
-mod point3d {
- use super::{Point3D, point2, point3};
-
- #[test]
- pub fn test_min() {
- let p1 = Point3D::new(1.0, 3.0, 5.0);
- let p2 = Point3D::new(2.0, 2.0, -1.0);
-
- let result = p1.min(p2);
-
- assert_eq!(result, Point3D::new(1.0, 2.0, -1.0));
- }
-
- #[test]
- pub fn test_max() {
- let p1 = Point3D::new(1.0, 3.0, 5.0);
- let p2 = Point3D::new(2.0, 2.0, -1.0);
-
- let result = p1.max(p2);
-
- assert_eq!(result, Point3D::new(2.0, 3.0, 5.0));
- }
-
- #[test]
- pub fn test_conv_vector() {
- use point3;
- for i in 0..100 {
- // We don't care about these values as long as they are not the same.
- let x = i as f32 *0.012345;
- let y = i as f32 *0.987654;
- let z = x * y;
- let p: Point3D<f32> = point3(x, y, z);
- assert_eq!(p.to_vector().to_point(), p);
- }
- }
-
- #[test]
- pub fn test_swizzling() {
- let p: Point3D<i32> = point3(1, 2, 3);
- assert_eq!(p.xy(), point2(1, 2));
- assert_eq!(p.xz(), point2(1, 3));
- assert_eq!(p.yz(), point2(2, 3));
- }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/rect.rs
+++ /dev/null
@@ -1,700 +0,0 @@
-// Copyright 2013 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.
-
-use super::UnknownUnit;
-use length::Length;
-use scale_factor::ScaleFactor;
-use num::*;
-use point::TypedPoint2D;
-use vector::TypedVector2D;
-use size::TypedSize2D;
-
-use heapsize::HeapSizeOf;
-use num_traits::NumCast;
-use serde::{Deserialize, Deserializer, Serialize, Serializer};
-use std::cmp::PartialOrd;
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::ops::{Add, Sub, Mul, Div};
-
-/// A 2d Rectangle optionally tagged with a unit.
-#[repr(C)]
-pub struct TypedRect<T, U = UnknownUnit> {
- pub origin: TypedPoint2D<T, U>,
- pub size: TypedSize2D<T, U>,
-}
-
-/// The default rectangle type with no unit.
-pub type Rect<T> = TypedRect<T, UnknownUnit>;
-
-impl<T: HeapSizeOf, U> HeapSizeOf for TypedRect<T, U> {
- fn heap_size_of_children(&self) -> usize {
- self.origin.heap_size_of_children() + self.size.heap_size_of_children()
- }
-}
-
-impl<'de, T: Copy + Deserialize<'de>, U> Deserialize<'de> for TypedRect<T, U> {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where D: Deserializer<'de>
- {
- let (origin, size) = try!(Deserialize::deserialize(deserializer));
- Ok(TypedRect::new(origin, size))
- }
-}
-
-impl<T: Serialize, U> Serialize for TypedRect<T, U> {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
- where S: Serializer
- {
- (&self.origin, &self.size).serialize(serializer)
- }
-}
-
-impl<T: Hash, U> Hash for TypedRect<T, U>
-{
- fn hash<H: Hasher>(&self, h: &mut H) {
- self.origin.hash(h);
- self.size.hash(h);
- }
-}
-
-impl<T: Copy, U> Copy for TypedRect<T, U> {}
-
-impl<T: Copy, U> Clone for TypedRect<T, U> {
- fn clone(&self) -> Self { *self }
-}
-
-impl<T: PartialEq, U> PartialEq<TypedRect<T, U>> for TypedRect<T, U> {
- fn eq(&self, other: &Self) -> bool {
- self.origin.eq(&other.origin) && self.size.eq(&other.size)
- }
-}
-
-impl<T: Eq, U> Eq for TypedRect<T, U> {}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedRect<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "TypedRect({:?} at {:?})", self.size, self.origin)
- }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedRect<T, U> {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- write!(formatter, "Rect({} at {})", self.size, self.origin)
- }
-}
-
-impl<T, U> TypedRect<T, U> {
- /// Constructor.
- pub fn new(origin: TypedPoint2D<T, U>, size: TypedSize2D<T, U>) -> Self {
- TypedRect {
- origin: origin,
- size: size,
- }
- }
-}
-
-impl<T, U> TypedRect<T, U>
-where T: Copy + Clone + Zero + PartialOrd + PartialEq + Add<T, Output=T> + Sub<T, Output=T> {
- #[inline]
- pub fn intersects(&self, other: &Self) -> bool {
- self.origin.x < other.origin.x + other.size.width &&
- other.origin.x < self.origin.x + self.size.width &&
- self.origin.y < other.origin.y + other.size.height &&
- other.origin.y < self.origin.y + self.size.height
- }
-
- #[inline]
- pub fn max_x(&self) -> T {
- self.origin.x + self.size.width
- }
-
- #[inline]
- pub fn min_x(&self) -> T {
- self.origin.x
- }
-
- #[inline]
- pub fn max_y(&self) -> T {
- self.origin.y + self.size.height
- }
-
- #[inline]
- pub fn min_y(&self) -> T {
- self.origin.y
- }
-
- #[inline]
- pub fn max_x_typed(&self) -> Length<T, U> {
- Length::new(self.max_x())
- }
-
- #[inline]
- pub fn min_x_typed(&self) -> Length<T, U> {
- Length::new(self.min_x())
- }
-
- #[inline]
- pub fn max_y_typed(&self) -> Length<T, U> {
- Length::new(self.max_y())
- }
-
- #[inline]
- pub fn min_y_typed(&self) -> Length<T, U> {
- Length::new(self.min_y())
- }
-
- #[inline]
- pub fn intersection(&self, other: &Self) -> Option<Self> {
- if !self.intersects(other) {
- return None;
- }
-
- let upper_left = TypedPoint2D::new(max(self.min_x(), other.min_x()),
- max(self.min_y(), other.min_y()));
- let lower_right_x = min(self.max_x(), other.max_x());
- let lower_right_y = min(self.max_y(), other.max_y());
-
- Some(TypedRect::new(upper_left, TypedSize2D::new(lower_right_x - upper_left.x,
- lower_right_y - upper_left.y)))
- }
-
- /// Returns the same rectangle, translated by a vector.
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn translate(&self, by: &TypedVector2D<T, U>) -> Self {
- Self::new(self.origin + *by, self.size)
- }
-
- /// Returns true if this rectangle contains the point. Points are considered
- /// in the rectangle if they are on the left or top edge, but outside if they
- /// are on the right or bottom edge.
- #[inline]
- pub fn contains(&self, other: &TypedPoint2D<T, U>) -> bool {
- self.origin.x <= other.x && other.x < self.origin.x + self.size.width &&
- self.origin.y <= other.y && other.y < self.origin.y + self.size.height
- }
-
- /// Returns true if this rectangle contains the interior of rect. Always
- /// returns true if rect is empty, and always returns false if rect is
- /// nonempty but this rectangle is empty.
- #[inline]
- pub fn contains_rect(&self, rect: &Self) -> bool {
- rect.is_empty() ||
- (self.min_x() <= rect.min_x() && rect.max_x() <= self.max_x() &&
- self.min_y() <= rect.min_y() && rect.max_y() <= self.max_y())
- }
-
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn inflate(&self, width: T, height: T) -> Self {
- TypedRect::new(
- TypedPoint2D::new(self.origin.x - width, self.origin.y - height),
- TypedSize2D::new(self.size.width + width + width, self.size.height + height + height),
- )
- }
-
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn inflate_typed(&self, width: Length<T, U>, height: Length<T, U>) -> Self {
- self.inflate(width.get(), height.get())
- }
-
- #[inline]
- pub fn top_right(&self) -> TypedPoint2D<T, U> {
- TypedPoint2D::new(self.max_x(), self.origin.y)
- }
-
- #[inline]
- pub fn bottom_left(&self) -> TypedPoint2D<T, U> {
- TypedPoint2D::new(self.origin.x, self.max_y())
- }
-
- #[inline]
- pub fn bottom_right(&self) -> TypedPoint2D<T, U> {
- TypedPoint2D::new(self.max_x(), self.max_y())
- }
-
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn translate_by_size(&self, size: &TypedSize2D<T, U>) -> Self {
- self.translate(&size.to_vector())
- }
-
- /// Returns the smallest rectangle containing the four points.
- pub fn from_points(points: &[TypedPoint2D<T, U>]) -> Self {
- if points.len() == 0 {
- return TypedRect::zero();
- }
- let (mut min_x, mut min_y) = (points[0].x, points[0].y);
- let (mut max_x, mut max_y) = (min_x, min_y);
- for point in &points[1..] {
- if point.x < min_x {
- min_x = point.x
- }
- if point.x > max_x {
- max_x = point.x
- }
- if point.y < min_y {
- min_y = point.y
- }
- if point.y > max_y {
- max_y = point.y
- }
- }
- TypedRect::new(TypedPoint2D::new(min_x, min_y),
- TypedSize2D::new(max_x - min_x, max_y - min_y))
- }
-}
-
-impl<T, U> TypedRect<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
- /// Linearly interpolate between this rectangle and another rectange.
- ///
- /// `t` is expected to be between zero and one.
- #[inline]
- pub fn lerp(&self, other: Self, t: T) -> Self {
- Self::new(
- self.origin.lerp(other.origin, t),
- self.size.lerp(other.size, t),
- )
- }
-}
-
-impl<T, U> TypedRect<T, U>
-where T: Copy + Clone + PartialOrd + Add<T, Output=T> + Sub<T, Output=T> + Zero {
- #[inline]
- pub fn union(&self, other: &Self) -> Self {
- if self.size == Zero::zero() {
- return *other;
- }
- if other.size == Zero::zero() {
- return *self;
- }
-
- let upper_left = TypedPoint2D::new(min(self.min_x(), other.min_x()),
- min(self.min_y(), other.min_y()));
-
- let lower_right_x = max(self.max_x(), other.max_x());
- let lower_right_y = max(self.max_y(), other.max_y());
-
- TypedRect::new(
- upper_left,
- TypedSize2D::new(lower_right_x - upper_left.x, lower_right_y - upper_left.y)
- )
- }
-}
-
-impl<T, U> TypedRect<T, U> {
- #[inline]
- pub fn scale<Scale: Copy>(&self, x: Scale, y: Scale) -> Self
- where T: Copy + Clone + Mul<Scale, Output=T> {
- TypedRect::new(
- TypedPoint2D::new(self.origin.x * x, self.origin.y * y),
- TypedSize2D::new(self.size.width * x, self.size.height * y)
- )
- }
-}
-
-impl<T: Copy + PartialEq + Zero, U> TypedRect<T, U> {
- /// Constructor, setting all sides to zero.
- pub fn zero() -> Self {
- TypedRect::new(
- TypedPoint2D::origin(),
- TypedSize2D::zero(),
- )
- }
-
- /// Returns true if the size is zero, regardless of the origin's value.
- pub fn is_empty(&self) -> bool {
- self.size.width == Zero::zero() || self.size.height == Zero::zero()
- }
-}
-
-
-pub fn min<T: Clone + PartialOrd>(x: T, y: T) -> T {
- if x <= y { x } else { y }
-}
-
-pub fn max<T: Clone + PartialOrd>(x: T, y: T) -> T {
- if x >= y { x } else { y }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedRect<T, U> {
- type Output = Self;
- #[inline]
- fn mul(self, scale: T) -> Self {
- TypedRect::new(self.origin * scale, self.size * scale)
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedRect<T, U> {
- type Output = Self;
- #[inline]
- fn div(self, scale: T) -> Self {
- TypedRect::new(self.origin / scale, self.size / scale)
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U1, U2> Mul<ScaleFactor<T, U1, U2>> for TypedRect<T, U1> {
- type Output = TypedRect<T, U2>;
- #[inline]
- fn mul(self, scale: ScaleFactor<T, U1, U2>) -> TypedRect<T, U2> {
- TypedRect::new(self.origin * scale, self.size * scale)
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U1, U2> Div<ScaleFactor<T, U1, U2>> for TypedRect<T, U2> {
- type Output = TypedRect<T, U1>;
- #[inline]
- fn div(self, scale: ScaleFactor<T, U1, U2>) -> TypedRect<T, U1> {
- TypedRect::new(self.origin / scale, self.size / scale)
- }
-}
-
-impl<T: Copy, Unit> TypedRect<T, Unit> {
- /// Drop the units, preserving only the numeric value.
- pub fn to_untyped(&self) -> Rect<T> {
- TypedRect::new(self.origin.to_untyped(), self.size.to_untyped())
- }
-
- /// Tag a unitless value with units.
- pub fn from_untyped(r: &Rect<T>) -> TypedRect<T, Unit> {
- TypedRect::new(TypedPoint2D::from_untyped(&r.origin), TypedSize2D::from_untyped(&r.size))
- }
-}
-
-impl<T0: NumCast + Copy, Unit> TypedRect<T0, Unit> {
- /// Cast from one numeric representation to another, preserving the units.
- ///
- /// When casting from floating point to integer coordinates, the decimals are truncated
- /// as one would expect from a simple cast, but this behavior does not always make sense
- /// geometrically. Consider using round(), round_in or round_out() before casting.
- pub fn cast<T1: NumCast + Copy>(&self) -> Option<TypedRect<T1, Unit>> {
- match (self.origin.cast(), self.size.cast()) {
- (Some(origin), Some(size)) => Some(TypedRect::new(origin, size)),
- _ => None
- }
- }
-}
-
-impl<T: Floor + Ceil + Round + Add<T, Output=T> + Sub<T, Output=T>, U> TypedRect<T, U> {
- /// Return a rectangle with edges rounded to integer coordinates, such that
- /// the returned rectangle has the same set of pixel centers as the original
- /// one.
- /// Edges at offset 0.5 round up.
- /// Suitable for most places where integral device coordinates
- /// are needed, but note that any translation should be applied first to
- /// avoid pixel rounding errors.
- /// Note that this is *not* rounding to nearest integer if the values are negative.
- /// They are always rounding as floor(n + 0.5).
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn round(&self) -> Self {
- let origin = self.origin.round();
- let size = self.origin.add_size(&self.size).round() - origin;
- TypedRect::new(origin, TypedSize2D::new(size.x, size.y))
- }
-
- /// Return a rectangle with edges rounded to integer coordinates, such that
- /// the original rectangle contains the resulting rectangle.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn round_in(&self) -> Self {
- let origin = self.origin.ceil();
- let size = self.origin.add_size(&self.size).floor() - origin;
- TypedRect::new(origin, TypedSize2D::new(size.x, size.y))
- }
-
- /// Return a rectangle with edges rounded to integer coordinates, such that
- /// the original rectangle is contained in the resulting rectangle.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn round_out(&self) -> Self {
- let origin = self.origin.floor();
- let size = self.origin.add_size(&self.size).ceil() - origin;
- TypedRect::new(origin, TypedSize2D::new(size.x, size.y))
- }
-}
-
-// Convenience functions for common casts
-impl<T: NumCast + Copy, Unit> TypedRect<T, Unit> {
- /// Cast into an `f32` rectangle.
- pub fn to_f32(&self) -> TypedRect<f32, Unit> {
- self.cast().unwrap()
- }
-
- /// Cast into an `usize` rectangle, truncating decimals if any.
- ///
- /// When casting from floating point rectangles, it is worth considering whether
- /// to `round()`, `round_in()` or `round_out()` before the cast in order to
- /// obtain the desired conversion behavior.
- pub fn to_usize(&self) -> TypedRect<usize, Unit> {
- self.cast().unwrap()
- }
-
- /// Cast into an `i32` rectangle, truncating decimals if any.
- ///
- /// When casting from floating point rectangles, it is worth considering whether
- /// to `round()`, `round_in()` or `round_out()` before the cast in order to
- /// obtain the desired conversion behavior.
- pub fn to_i32(&self) -> TypedRect<i32, Unit> {
- self.cast().unwrap()
- }
-
- /// Cast into an `i64` rectangle, truncating decimals if any.
- ///
- /// When casting from floating point rectangles, it is worth considering whether
- /// to `round()`, `round_in()` or `round_out()` before the cast in order to
- /// obtain the desired conversion behavior.
- pub fn to_i64(&self) -> TypedRect<i64, Unit> {
- self.cast().unwrap()
- }
-}
-
-/// Shorthand for `TypedRect::new(TypedPoint2D::new(x, y), TypedSize2D::new(w, h))`.
-pub fn rect<T: Copy, U>(x: T, y: T, w: T, h: T) -> TypedRect<T, U> {
- TypedRect::new(TypedPoint2D::new(x, y), TypedSize2D::new(w, h))
-}
-
-#[cfg(test)]
-mod tests {
- use point::Point2D;
- use vector::vec2;
- use size::Size2D;
- use super::*;
-
- #[test]
- fn test_min_max() {
- assert!(min(0u32, 1u32) == 0u32);
- assert!(min(-1.0f32, 0.0f32) == -1.0f32);
-
- assert!(max(0u32, 1u32) == 1u32);
- assert!(max(-1.0f32, 0.0f32) == 0.0f32);
- }
-
- #[test]
- fn test_translate() {
- let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));
- let pp = p.translate(&vec2(10,15));
-
- assert!(pp.size.width == 50);
- assert!(pp.size.height == 40);
- assert!(pp.origin.x == 10);
- assert!(pp.origin.y == 15);
-
-
- let r = Rect::new(Point2D::new(-10, -5), Size2D::new(50, 40));
- let rr = r.translate(&vec2(0,-10));
-
- assert!(rr.size.width == 50);
- assert!(rr.size.height == 40);
- assert!(rr.origin.x == -10);
- assert!(rr.origin.y == -15);
- }
-
- #[test]
- fn test_translate_by_size() {
- let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));
- let pp = p.translate_by_size(&Size2D::new(10,15));
-
- assert!(pp.size.width == 50);
- assert!(pp.size.height == 40);
- assert!(pp.origin.x == 10);
- assert!(pp.origin.y == 15);
-
-
- let r = Rect::new(Point2D::new(-10, -5), Size2D::new(50, 40));
- let rr = r.translate_by_size(&Size2D::new(0,-10));
-
- assert!(rr.size.width == 50);
- assert!(rr.size.height == 40);
- assert!(rr.origin.x == -10);
- assert!(rr.origin.y == -15);
- }
-
- #[test]
- fn test_union() {
- let p = Rect::new(Point2D::new(0, 0), Size2D::new(50, 40));
- let q = Rect::new(Point2D::new(20,20), Size2D::new(5, 5));
- let r = Rect::new(Point2D::new(-15, -30), Size2D::new(200, 15));
- let s = Rect::new(Point2D::new(20, -15), Size2D::new(250, 200));
-
- let pq = p.union(&q);
- assert!(pq.origin == Point2D::new(0, 0));
- assert!(pq.size == Size2D::new(50, 40));
-
- let pr = p.union(&r);
- assert!(pr.origin == Point2D::new(-15, -30));
- assert!(pr.size == Size2D::new(200, 70));
-
- let ps = p.union(&s);
- assert!(ps.origin == Point2D::new(0, -15));
- assert!(ps.size == Size2D::new(270, 200));
-
- }
-
- #[test]
- fn test_intersection() {
- let p = Rect::new(Point2D::new(0, 0), Size2D::new(10, 20));
- let q = Rect::new(Point2D::new(5, 15), Size2D::new(10, 10));
- let r = Rect::new(Point2D::new(-5, -5), Size2D::new(8, 8));
-
- let pq = p.intersection(&q);
- assert!(pq.is_some());
- let pq = pq.unwrap();
- assert!(pq.origin == Point2D::new(5, 15));
- assert!(pq.size == Size2D::new(5, 5));
-
- let pr = p.intersection(&r);
- assert!(pr.is_some());
- let pr = pr.unwrap();
- assert!(pr.origin == Point2D::new(0, 0));
- assert!(pr.size == Size2D::new(3, 3));
-
- let qr = q.intersection(&r);
- assert!(qr.is_none());
- }
-
- #[test]
- fn test_contains() {
- let r = Rect::new(Point2D::new(-20, 15), Size2D::new(100, 200));
-
- assert!(r.contains(&Point2D::new(0, 50)));
- assert!(r.contains(&Point2D::new(-10, 200)));
-
- // The `contains` method is inclusive of the top/left edges, but not the
- // bottom/right edges.
- assert!(r.contains(&Point2D::new(-20, 15)));
- assert!(!r.contains(&Point2D::new(80, 15)));
- assert!(!r.contains(&Point2D::new(80, 215)));
- assert!(!r.contains(&Point2D::new(-20, 215)));
-
- // Points beyond the top-left corner.
- assert!(!r.contains(&Point2D::new(-25, 15)));
- assert!(!r.contains(&Point2D::new(-15, 10)));
-
- // Points beyond the top-right corner.
- assert!(!r.contains(&Point2D::new(85, 20)));
- assert!(!r.contains(&Point2D::new(75, 10)));
-
- // Points beyond the bottom-right corner.
- assert!(!r.contains(&Point2D::new(85, 210)));
- assert!(!r.contains(&Point2D::new(75, 220)));
-
- // Points beyond the bottom-left corner.
- assert!(!r.contains(&Point2D::new(-25, 210)));
- assert!(!r.contains(&Point2D::new(-15, 220)));
-
- let r = Rect::new(Point2D::new(-20.0, 15.0), Size2D::new(100.0, 200.0));
- assert!(r.contains_rect(&r));
- assert!(!r.contains_rect(&r.translate(&vec2( 0.1, 0.0))));
- assert!(!r.contains_rect(&r.translate(&vec2(-0.1, 0.0))));
- assert!(!r.contains_rect(&r.translate(&vec2( 0.0, 0.1))));
- assert!(!r.contains_rect(&r.translate(&vec2( 0.0, -0.1))));
- // Empty rectangles are always considered as contained in other rectangles,
- // even if their origin is not.
- let p = Point2D::new(1.0, 1.0);
- assert!(!r.contains(&p));
- assert!(r.contains_rect(&Rect::new(p, Size2D::zero())));
- }
-
- #[test]
- fn test_scale() {
- let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));
- let pp = p.scale(10, 15);
-
- assert!(pp.size.width == 500);
- assert!(pp.size.height == 600);
- assert!(pp.origin.x == 0);
- assert!(pp.origin.y == 0);
-
- let r = Rect::new(Point2D::new(-10, -5), Size2D::new(50, 40));
- let rr = r.scale(1, 20);
-
- assert!(rr.size.width == 50);
- assert!(rr.size.height == 800);
- assert!(rr.origin.x == -10);
- assert!(rr.origin.y == -100);
- }
-
- #[test]
- fn test_inflate() {
- let p = Rect::new(Point2D::new(0, 0), Size2D::new(10, 10));
- let pp = p.inflate(10, 20);
-
- assert!(pp.size.width == 30);
- assert!(pp.size.height == 50);
- assert!(pp.origin.x == -10);
- assert!(pp.origin.y == -20);
-
- let r = Rect::new(Point2D::new(0, 0), Size2D::new(10, 20));
- let rr = r.inflate(-2, -5);
-
- assert!(rr.size.width == 6);
- assert!(rr.size.height == 10);
- assert!(rr.origin.x == 2);
- assert!(rr.origin.y == 5);
- }
-
- #[test]
- fn test_min_max_x_y() {
- let p = Rect::new(Point2D::new(0u32, 0u32), Size2D::new(50u32, 40u32));
- assert!(p.max_y() == 40);
- assert!(p.min_y() == 0);
- assert!(p.max_x() == 50);
- assert!(p.min_x() == 0);
-
- let r = Rect::new(Point2D::new(-10, -5), Size2D::new(50, 40));
- assert!(r.max_y() == 35);
- assert!(r.min_y() == -5);
- assert!(r.max_x() == 40);
- assert!(r.min_x() == -10);
- }
-
- #[test]
- fn test_is_empty() {
- assert!(Rect::new(Point2D::new(0u32, 0u32), Size2D::new(0u32, 0u32)).is_empty());
- assert!(Rect::new(Point2D::new(0u32, 0u32), Size2D::new(10u32, 0u32)).is_empty());
- assert!(Rect::new(Point2D::new(0u32, 0u32), Size2D::new(0u32, 10u32)).is_empty());
- assert!(!Rect::new(Point2D::new(0u32, 0u32), Size2D::new(1u32, 1u32)).is_empty());
- assert!(Rect::new(Point2D::new(10u32, 10u32), Size2D::new(0u32, 0u32)).is_empty());
- assert!(Rect::new(Point2D::new(10u32, 10u32), Size2D::new(10u32, 0u32)).is_empty());
- assert!(Rect::new(Point2D::new(10u32, 10u32), Size2D::new(0u32, 10u32)).is_empty());
- assert!(!Rect::new(Point2D::new(10u32, 10u32), Size2D::new(1u32, 1u32)).is_empty());
- }
-
- #[test]
- fn test_round() {
- let mut x = -2.0;
- let mut y = -2.0;
- let mut w = -2.0;
- let mut h = -2.0;
- while x < 2.0 {
- while y < 2.0 {
- while w < 2.0 {
- while h < 2.0 {
- let rect = Rect::new(Point2D::new(x, y), Size2D::new(w, h));
-
- assert!(rect.contains_rect(&rect.round_in()));
- assert!(rect.round_in().inflate(1.0, 1.0).contains_rect(&rect));
-
- assert!(rect.round_out().contains_rect(&rect));
- assert!(rect.inflate(1.0, 1.0).contains_rect(&rect.round_out()));
-
- assert!(rect.inflate(1.0, 1.0).contains_rect(&rect.round()));
- assert!(rect.round().inflate(1.0, 1.0).contains_rect(&rect));
-
- h += 0.1;
- }
- w += 0.1;
- }
- y += 0.1;
- }
- x += 0.1
- }
- }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/rotation.rs
+++ /dev/null
@@ -1,696 +0,0 @@
-// Copyright 2013 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.
-
-use approxeq::ApproxEq;
-use num_traits::{Float, One, Zero};
-use std::fmt;
-use std::ops::{Add, Neg, Mul, Sub, Div};
-use std::marker::PhantomData;
-use trig::Trig;
-use {TypedPoint2D, TypedPoint3D, TypedVector2D, TypedVector3D, Vector3D, point2, point3, vec3};
-use {TypedTransform3D, TypedTransform2D, UnknownUnit, Radians};
-
-
-define_matrix! {
- /// A transform that can represent rotations in 2d, represented as an angle in radians.
- pub struct TypedRotation2D<T, Src, Dst> {
- pub angle : T,
- }
-}
-
-/// The default 2d rotation type with no units.
-pub type Rotation2D<T> = TypedRotation2D<T, UnknownUnit, UnknownUnit>;
-
-impl<T, Src, Dst> TypedRotation2D<T, Src, Dst> {
- #[inline]
- /// Creates a rotation from an angle in radians.
- pub fn new(angle: Radians<T>) -> Self {
- TypedRotation2D {
- angle: angle.0,
- _unit: PhantomData,
- }
- }
-
- pub fn radians(angle: T) -> Self {
- Self::new(Radians::new(angle))
- }
-
- /// Creates the identity rotation.
- #[inline]
- pub fn identity() -> Self where T: Zero {
- Self::radians(T::zero())
- }
-}
-
-impl<T, Src, Dst> TypedRotation2D<T, Src, Dst> where T: Clone
-{
- /// Returns self.angle as a strongly typed `Radians<T>`.
- pub fn get_angle(&self) -> Radians<T> {
- Radians::new(self.angle.clone())
- }
-}
-
-
-impl<T, Src, Dst> TypedRotation2D<T, Src, Dst>
-where T: Copy + Clone +
- Add<T, Output=T> +
- Sub<T, Output=T> +
- Mul<T, Output=T> +
- Div<T, Output=T> +
- Neg<Output=T> +
- ApproxEq<T> +
- PartialOrd +
- Float +
- One + Zero
-{
- /// Creates a 3d rotation (around the z axis) from this 2d rotation.
- #[inline]
- pub fn to_3d(&self) -> TypedRotation3D<T, Src, Dst> {
- TypedRotation3D::around_z(self.get_angle())
- }
-
- /// Returns the inverse of this rotation.
- #[inline]
- pub fn inverse(&self) -> TypedRotation2D<T, Dst, Src> {
- TypedRotation2D::radians(-self.angle)
- }
-
- /// Returns a rotation representing the other rotation followed by this rotation.
- #[inline]
- pub fn pre_rotate<NewSrc>(&self, other: &TypedRotation2D<T, NewSrc, Src>) -> TypedRotation2D<T, NewSrc, Dst> {
- TypedRotation2D::radians(self.angle + other.angle)
- }
-
- /// Returns a rotation representing this rotation followed by the other rotation.
- #[inline]
- pub fn post_rotate<NewDst>(&self, other: &TypedRotation2D<T, Dst, NewDst>) -> TypedRotation2D<T, Src, NewDst> {
- other.pre_rotate(self)
- }
-
- /// Returns the given 2d point transformed by this rotation.
- ///
- /// The input point must be use the unit Src, and the returned point has the unit Dst.
- #[inline]
- pub fn transform_point(&self, point: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
- let (sin, cos) = Float::sin_cos(self.angle);
- point2(
- point.x * cos - point.y * sin,
- point.y * cos + point.x * sin,
- )
- }
-
- /// Returns the given 2d vector transformed by this rotation.
- ///
- /// The input point must be use the unit Src, and the returned point has the unit Dst.
- #[inline]
- pub fn transform_vector(&self, vector: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
- self.transform_point(&vector.to_point()).to_vector()
- }
-}
-
-impl<T, Src, Dst> TypedRotation2D<T, Src, Dst>
-where T: Copy + Clone +
- Add<T, Output=T> +
- Mul<T, Output=T> +
- Div<T, Output=T> +
- Sub<T, Output=T> +
- Trig +
- PartialOrd +
- One + Zero
-{
- /// Returns the matrix representation of this rotation.
- #[inline]
- pub fn to_transform(&self) -> TypedTransform2D<T, Src, Dst> {
- TypedTransform2D::create_rotation(self.get_angle())
- }
-}
-
-define_matrix! {
- /// A transform that can represent rotations in 3d, represented as a quaternion.
- ///
- /// Most methods expect the quaternion to be normalized.
- /// When in doubt, use `unit_quaternion` instead of `quaternion` to create
- /// a rotation as the former will ensure that its result is normalized.
- ///
- /// Some people use the `x, y, z, w` (or `w, x, y, z`) notations. The equivalence is
- /// as follows: `x -> i`, `y -> j`, `z -> k`, `w -> r`.
- /// The memory layout of this type corresponds to the `x, y, z, w` notation
- pub struct TypedRotation3D<T, Src, Dst> {
- // Component multiplied by the imaginary number `i`.
- pub i: T,
- // Component multiplied by the imaginary number `j`.
- pub j: T,
- // Component multiplied by the imaginary number `k`.
- pub k: T,
- // The real part.
- pub r: T,
- }
-}
-
-/// The default 3d rotation type with no units.
-pub type Rotation3D<T> = TypedRotation3D<T, UnknownUnit, UnknownUnit>;
-
-impl<T, Src, Dst> TypedRotation3D<T, Src, Dst> {
- /// Creates a rotation around from a quaternion representation.
- ///
- /// The parameters are a, b, c and r compose the quaternion `a*i + b*j + c*k + r`
- /// where `a`, `b` and `c` describe the vector part and the last parameter `r` is
- /// the real part.
- ///
- /// The resulting quaternion is not necessarily normalized. See `unit_quaternion`.
- #[inline]
- pub fn quaternion(a: T, b: T, c: T, r: T) -> Self {
- TypedRotation3D { i: a, j: b, k: c, r, _unit: PhantomData }
- }
-}
-
-
-impl<T, Src, Dst> TypedRotation3D<T, Src, Dst> where T: Copy {
- /// Returns the vector part (i, j, k) of this quaternion.
- #[inline]
- pub fn vector_part(&self) -> Vector3D<T> { vec3(self.i, self.j, self.k) }
-}
-
-impl<T, Src, Dst> TypedRotation3D<T, Src, Dst>
-where T: Copy + Clone +
- Add<T, Output=T> +
- Sub<T, Output=T> +
- Mul<T, Output=T> +
- Div<T, Output=T> +
- Neg<Output=T> +
- ApproxEq<T> +
- PartialOrd +
- Float +
- One + Zero
-{
- /// Creates the identity rotation.
- #[inline]
- pub fn identity() -> Self {
- let zero = T::zero();
- let one = T::one();
- Self::quaternion(zero, zero, zero, one)
- }
-
- /// Creates a rotation around from a quaternion representation and normalizes it.
- ///
- /// The parameters are a, b, c and r compose the quaternion `a*i + b*j + c*k + r`
- /// before normalization, where `a`, `b` and `c` describe the vector part and the
- /// last parameter `r` is the real part.
- #[inline]
- pub fn unit_quaternion(i: T, j: T, k: T, r: T) -> Self {
- Self::quaternion(i, j, k, r).normalize()
- }
-
- /// Creates a rotation around a given axis.
- pub fn around_axis(axis: TypedVector3D<T, Src>, angle: Radians<T>) -> Self {
- let axis = axis.normalize();
- let two = T::one() + T::one();
- let (sin, cos) = Float::sin_cos(angle.get() / two);
- Self::quaternion(axis.x * sin, axis.y * sin, axis.z * sin, cos)
- }
-
- /// Creates a rotation around the x axis.
- pub fn around_x(angle: Radians<T>) -> Self {
- let zero = Zero::zero();
- let two = T::one() + T::one();
- let (sin, cos) = Float::sin_cos(angle.get() / two);
- Self::quaternion(sin, zero, zero, cos)
- }
-
- /// Creates a rotation around the y axis.
- pub fn around_y(angle: Radians<T>) -> Self {
- let zero = Zero::zero();
- let two = T::one() + T::one();
- let (sin, cos) = Float::sin_cos(angle.get() / two);
- Self::quaternion(zero, sin, zero, cos)
- }
-
- /// Creates a rotation around the z axis.
- pub fn around_z(angle: Radians<T>) -> Self {
- let zero = Zero::zero();
- let two = T::one() + T::one();
- let (sin, cos) = Float::sin_cos(angle.get() / two);
- Self::quaternion(zero, zero, sin, cos)
- }
-
- /// Creates a rotation from euler angles.
- ///
- /// The rotations are applied in roll then pitch then yaw order.
- ///
- /// - Roll (also calld bank) is a rotation around the x axis.
- /// - Pitch (also calld bearing) is a rotation around the y axis.
- /// - Yaw (also calld heading) is a rotation around the z axis.
- pub fn euler(roll: Radians<T>, pitch: Radians<T>, yaw: Radians<T>) -> Self {
- let half = T::one() / (T::one() + T::one());
-
- let (sy, cy) = Float::sin_cos(half * yaw.get());
- let (sp, cp) = Float::sin_cos(half * pitch.get());
- let (sr, cr) = Float::sin_cos(half * roll.get());
-
- Self::quaternion(
- cy * sr * cp - sy * cr * sp,
- cy * cr * sp + sy * sr * cp,
- sy * cr * cp - cy * sr * sp,
- cy * cr * cp + sy * sr * sp,
- )
- }
-
- /// Returns the inverse of this rotation.
- #[inline]
- pub fn inverse(&self) -> TypedRotation3D<T, Dst, Src> {
- TypedRotation3D::quaternion(-self.i, -self.j, -self.k, self.r)
- }
-
- /// Computes the norm of this quaternion
- #[inline]
- pub fn norm(&self) -> T {
- self.square_norm().sqrt()
- }
-
- #[inline]
- pub fn square_norm(&self) -> T {
- (self.i * self.i + self.j * self.j + self.k * self.k + self.r *self.r)
- }
-
- /// Returns a unit quaternion from this one.
- #[inline]
- pub fn normalize(&self) -> Self {
- self.mul(T::one() / self.norm())
- }
-
- #[inline]
- pub fn is_normalized(&self) -> bool {
- // TODO: we might need to relax the threshold here, because of floating point imprecision.
- self.square_norm().approx_eq(&T::one())
- }
-
- /// Spherical linear interpolation between this rotation and another rotation.
- ///
- /// `t` is expected to be between zero and one.
- pub fn slerp(&self, other: &Self, t: T) -> Self {
- debug_assert!(self.is_normalized());
- debug_assert!(other.is_normalized());
-
- let r1 = *self;
- let mut r2 = *other;
-
- let mut dot = r1.i * r2.i + r1.j * r2.j + r1.k * r2.k + r1.r * r2.r;
-
- let one = T::one();
-
- if dot.approx_eq(&T::one()) {
- // If the inputs are too close, linearly interpolate to avoid precision issues.
- return r1.lerp(&r2, t);
- }
-
- // If the dot product is negative, the quaternions
- // have opposite handed-ness and slerp won't take
- // the shorter path. Fix by reversing one quaternion.
- if dot < T::zero() {
- r2 = r2.mul(-T::one());
- dot = -dot;
- }
-
- // For robustness, stay within the domain of acos.
- dot = Float::min(dot, one);
-
- // Angle between r1 and the result.
- let theta = Float::acos(dot) * t;
-
- // r1 and r3 form an orthonormal basis.
- let r3 = r2.sub(r1.mul(dot)).normalize();
- let (sin, cos) = Float::sin_cos(theta);
- r1.mul(cos).add(r3.mul(sin))
- }
-
- /// Basic Linear interpolation between this rotation and another rotation.
- ///
- /// `t` is expected to be between zero and one.
- #[inline]
- pub fn lerp(&self, other: &Self, t: T) -> Self {
- let one_t = T::one() - t;
- return self.mul(one_t).add(other.mul(t)).normalize();
- }
-
- /// Returns the given 3d point transformed by this rotation.
- ///
- /// The input point must be use the unit Src, and the returned point has the unit Dst.
- pub fn rotate_point3d(&self, point: &TypedPoint3D<T, Src>) -> TypedPoint3D<T, Dst> {
- debug_assert!(self.is_normalized());
-
- let two = T::one() + T::one();
- let cross = self.vector_part().cross(point.to_vector().to_untyped()) * two;
-
- point3(
- point.x + self.r * cross.x + self.j * cross.z - self.k * cross.y,
- point.y + self.r * cross.y + self.k * cross.x - self.i * cross.z,
- point.z + self.r * cross.z + self.i * cross.y - self.j * cross.x,
- )
- }
-
- /// Returns the given 2d point transformed by this rotation then projected on the xy plane.
- ///
- /// The input point must be use the unit Src, and the returned point has the unit Dst.
- #[inline]
- pub fn rotate_point2d(&self, point: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
- self.rotate_point3d(&point.to_3d()).xy()
- }
-
- /// Returns the given 3d vector transformed by this rotation then projected on the xy plane.
- ///
- /// The input vector must be use the unit Src, and the returned point has the unit Dst.
- #[inline]
- pub fn rotate_vector3d(&self, vector: &TypedVector3D<T, Src>) -> TypedVector3D<T, Dst> {
- self.rotate_point3d(&vector.to_point()).to_vector()
- }
-
- /// Returns the given 2d vector transformed by this rotation then projected on the xy plane.
- ///
- /// The input vector must be use the unit Src, and the returned point has the unit Dst.
- #[inline]
- pub fn rotate_vector2d(&self, vector: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
- self.rotate_vector3d(&vector.to_3d()).xy()
- }
-
- /// Returns the matrix representation of this rotation.
- #[inline]
- pub fn to_transform(&self) -> TypedTransform3D<T, Src, Dst> {
- debug_assert!(self.is_normalized());
-
- let i2 = self.i + self.i;
- let j2 = self.j + self.j;
- let k2 = self.k + self.k;
- let ii = self.i * i2;
- let ij = self.i * j2;
- let ik = self.i * k2;
- let jj = self.j * j2;
- let jk = self.j * k2;
- let kk = self.k * k2;
- let ri = self.r * i2;
- let rj = self.r * j2;
- let rk = self.r * k2;
-
- let one = T::one();
- let zero = T::zero();
-
- let m11 = one - (jj + kk);
- let m12 = ij + rk;
- let m13 = ik - rj;
-
- let m21 = ij - rk;
- let m22 = one - (ii + kk);
- let m23 = jk + ri;
-
- let m31 = ik + rj;
- let m32 = jk - ri;
- let m33 = one - (ii + jj);
-
- TypedTransform3D::row_major(
- m11, m12, m13, zero,
- m21, m22, m23, zero,
- m31, m32, m33, zero,
- zero, zero, zero, one,
- )
- }
-
- /// Returns a rotation representing the other rotation followed by this rotation.
- pub fn pre_rotate<NewSrc>(&self, other: &TypedRotation3D<T, NewSrc, Src>) -> TypedRotation3D<T, NewSrc, Dst> {
- debug_assert!(self.is_normalized());
- TypedRotation3D::quaternion(
- self.i * other.r + self.r * other.i + self.j * other.k - self.k * other.j,
- self.j * other.r + self.r * other.j + self.k * other.i - self.i * other.k,
- self.k * other.r + self.r * other.k + self.i * other.j - self.j * other.i,
- self.r * other.r - self.i * other.i - self.j * other.j - self.k * other.k,
- )
- }
-
- /// Returns a rotation representing this rotation followed by the other rotation.
- #[inline]
- pub fn post_rotate<NewDst>(&self, other: &TypedRotation3D<T, Dst, NewDst>) -> TypedRotation3D<T, Src, NewDst> {
- other.pre_rotate(self)
- }
-
- // add, sub and mul are used internally for intermediate computation but aren't public
- // because they don't carry real semantic meanings (I think?).
-
- #[inline]
- fn add(&self, other: Self) -> Self {
- Self::quaternion(
- self.i + other.i,
- self.j + other.j,
- self.k + other.k,
- self.r + other.r,
- )
- }
-
- #[inline]
- fn sub(&self, other: Self) -> Self {
- Self::quaternion(
- self.i - other.i,
- self.j - other.j,
- self.k - other.k,
- self.r - other.r,
- )
- }
-
- #[inline]
- fn mul(&self, factor: T) -> Self {
- Self::quaternion(
- self.i * factor,
- self.j * factor,
- self.k * factor,
- self.r * factor,
- )
- }
-}
-
-impl<T: fmt::Debug, Src, Dst> fmt::Debug for TypedRotation3D<T, Src, Dst> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "Quat({:?}*i + {:?}*j + {:?}*k + {:?})", self.i, self.j, self.k, self.r)
- }
-}
-
-impl<T: fmt::Display, Src, Dst> fmt::Display for TypedRotation3D<T, Src, Dst> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "Quat({}*i + {}*j + {}*k + {})", self.i, self.j, self.k, self.r)
- }
-}
-
-impl<T, Src, Dst> ApproxEq<T> for TypedRotation3D<T, Src, Dst>
-where
- T: Copy + Neg<Output=T> + ApproxEq<T>
-{
- fn approx_epsilon() -> T {
- T::approx_epsilon()
- }
-
- fn approx_eq(&self, other: &Self) -> bool {
- self.approx_eq_eps(other, &Self::approx_epsilon())
- }
-
- fn approx_eq_eps(&self, other: &Self, eps: &T) -> bool {
- (
- self.i.approx_eq_eps(&other.i, eps)
- && self.j.approx_eq_eps(&other.j, eps)
- && self.k.approx_eq_eps(&other.k, eps)
- && self.r.approx_eq_eps(&other.r, eps)
- ) || (
- self.i.approx_eq_eps(&-other.i, eps)
- && self.j.approx_eq_eps(&-other.j, eps)
- && self.k.approx_eq_eps(&-other.k, eps)
- && self.r.approx_eq_eps(&-other.r, eps)
- )
- }
-}
-
-#[test]
-fn simple_rotation_2d() {
- use std::f32::consts::{PI, FRAC_PI_2};
- let ri = Rotation2D::identity();
- let r90 = Rotation2D::radians(FRAC_PI_2);
- let rm90 = Rotation2D::radians(-FRAC_PI_2);
- let r180 = Rotation2D::radians(PI);
-
- assert!(ri.transform_point(&point2(1.0, 2.0)).approx_eq(&point2(1.0, 2.0)));
- assert!(r90.transform_point(&point2(1.0, 2.0)).approx_eq(&point2(-2.0, 1.0)));
- assert!(rm90.transform_point(&point2(1.0, 2.0)).approx_eq(&point2(2.0, -1.0)));
- assert!(r180.transform_point(&point2(1.0, 2.0)).approx_eq(&point2(-1.0, -2.0)));
-
- assert!(
- r90.inverse().inverse().transform_point(&point2(1.0, 2.0)).approx_eq(
- &r90.transform_point(&point2(1.0, 2.0))
- )
- );
-}
-
-#[test]
-fn simple_rotation_3d_in_2d() {
- use std::f32::consts::{PI, FRAC_PI_2};
- let ri = Rotation3D::identity();
- let r90 = Rotation3D::around_z(Radians::new(FRAC_PI_2));
- let rm90 = Rotation3D::around_z(Radians::new(-FRAC_PI_2));
- let r180 = Rotation3D::around_z(Radians::new(PI));
-
- assert!(ri.rotate_point2d(&point2(1.0, 2.0)).approx_eq(&point2(1.0, 2.0)));
- assert!(r90.rotate_point2d(&point2(1.0, 2.0)).approx_eq(&point2(-2.0, 1.0)));
- assert!(rm90.rotate_point2d(&point2(1.0, 2.0)).approx_eq(&point2(2.0, -1.0)));
- assert!(r180.rotate_point2d(&point2(1.0, 2.0)).approx_eq(&point2(-1.0, -2.0)));
-
- assert!(
- r90.inverse().inverse().rotate_point2d(&point2(1.0, 2.0)).approx_eq(
- &r90.rotate_point2d(&point2(1.0, 2.0))
- )
- );
-}
-
-#[test]
-fn pre_post() {
- use std::f32::consts::{FRAC_PI_2};
- let r1 = Rotation3D::around_x(Radians::new(FRAC_PI_2));
- let r2 = Rotation3D::around_y(Radians::new(FRAC_PI_2));
- let r3 = Rotation3D::around_z(Radians::new(FRAC_PI_2));
-
- let t1 = r1.to_transform();
- let t2 = r2.to_transform();
- let t3 = r3.to_transform();
-
- let p = point3(1.0, 2.0, 3.0);
-
- // Check that the order of transformations is correct (corresponds to what
- // we do in Transfor3D).
- let p1 = r1.post_rotate(&r2).post_rotate(&r3).rotate_point3d(&p);
- let p2 = t1.post_mul(&t2).post_mul(&t3).transform_point3d(&p);
-
- assert!(p1.approx_eq(&p2));
-
- // Check that changing the order indeed matters.
- let p3 = t3.post_mul(&t1).post_mul(&t2).transform_point3d(&p);
- assert!(!p1.approx_eq(&p3));
-}
-
-#[test]
-fn to_transform3d() {
- use std::f32::consts::{PI, FRAC_PI_2};
- let rotations = [
- Rotation3D::identity(),
- Rotation3D::around_x(Radians::new(FRAC_PI_2)),
- Rotation3D::around_x(Radians::new(-FRAC_PI_2)),
- Rotation3D::around_x(Radians::new(PI)),
- Rotation3D::around_y(Radians::new(FRAC_PI_2)),
- Rotation3D::around_y(Radians::new(-FRAC_PI_2)),
- Rotation3D::around_y(Radians::new(PI)),
- Rotation3D::around_z(Radians::new(FRAC_PI_2)),
- Rotation3D::around_z(Radians::new(-FRAC_PI_2)),
- Rotation3D::around_z(Radians::new(PI)),
- ];
-
- let points = [
- point3(0.0, 0.0, 0.0),
- point3(1.0, 2.0, 3.0),
- point3(-5.0, 3.0, -1.0),
- point3(-0.5, -1.0, 1.5),
- ];
-
- for rotation in &rotations {
- for point in &points {
- let p1 = rotation.rotate_point3d(point);
- let p2 = rotation.to_transform().transform_point3d(point);
- assert!(p1.approx_eq(&p2));
- }
- }
-}
-
-#[test]
-fn slerp() {
- let q1 = Rotation3D::quaternion(1.0, 0.0, 0.0, 0.0);
- let q2 = Rotation3D::quaternion(0.0, 1.0, 0.0, 0.0);
- let q3 = Rotation3D::quaternion(0.0, 0.0, -1.0, 0.0);
-
- // The values below can be obtained with a python program:
- // import numpy
- // import quaternion
- // q1 = numpy.quaternion(1, 0, 0, 0)
- // q2 = numpy.quaternion(0, 1, 0, 0)
- // quaternion.slerp_evaluate(q1, q2, 0.2)
-
- assert!(q1.slerp(&q2, 0.0).approx_eq(&q1));
- assert!(q1.slerp(&q2, 0.2).approx_eq(&Rotation3D::quaternion(0.951056516295154, 0.309016994374947, 0.0, 0.0)));
- assert!(q1.slerp(&q2, 0.4).approx_eq(&Rotation3D::quaternion(0.809016994374947, 0.587785252292473, 0.0, 0.0)));
- assert!(q1.slerp(&q2, 0.6).approx_eq(&Rotation3D::quaternion(0.587785252292473, 0.809016994374947, 0.0, 0.0)));
- assert!(q1.slerp(&q2, 0.8).approx_eq(&Rotation3D::quaternion(0.309016994374947, 0.951056516295154, 0.0, 0.0)));
- assert!(q1.slerp(&q2, 1.0).approx_eq(&q2));
-
- assert!(q1.slerp(&q3, 0.0).approx_eq(&q1));
- assert!(q1.slerp(&q3, 0.2).approx_eq(&Rotation3D::quaternion(0.951056516295154, 0.0, -0.309016994374947, 0.0)));
- assert!(q1.slerp(&q3, 0.4).approx_eq(&Rotation3D::quaternion(0.809016994374947, 0.0, -0.587785252292473, 0.0)));
- assert!(q1.slerp(&q3, 0.6).approx_eq(&Rotation3D::quaternion(0.587785252292473, 0.0, -0.809016994374947, 0.0)));
- assert!(q1.slerp(&q3, 0.8).approx_eq(&Rotation3D::quaternion(0.309016994374947, 0.0, -0.951056516295154, 0.0)));
- assert!(q1.slerp(&q3, 1.0).approx_eq(&q3));
-}
-
-#[test]
-fn around_axis() {
- use std::f32::consts::{PI, FRAC_PI_2};
-
- // Two sort of trivial cases:
- let r1 = Rotation3D::around_axis(vec3(1.0, 1.0, 0.0), Radians::new(PI));
- let r2 = Rotation3D::around_axis(vec3(1.0, 1.0, 0.0), Radians::new(FRAC_PI_2));
- assert!(r1.rotate_point3d(&point3(1.0, 2.0, 0.0)).approx_eq(&point3(2.0, 1.0, 0.0)));
- assert!(r2.rotate_point3d(&point3(1.0, 0.0, 0.0)).approx_eq(&point3(0.5, 0.5, -0.5.sqrt())));
-
- // A more arbitray test (made up with numpy):
- let r3 = Rotation3D::around_axis(vec3(0.5, 1.0, 2.0), Radians::new(2.291288));
- assert!(r3.rotate_point3d(&point3(1.0, 0.0, 0.0)).approx_eq(&point3(-0.58071821, 0.81401868, -0.01182979)));
-}
-
-#[test]
-fn from_euler() {
- use std::f32::consts::FRAC_PI_2;
-
- // First test simple separate yaw pitch and roll rotations, because it is easy to come
- // up with the corresponding quaternion.
- // Since several quaternions can represent the same transformation we compare the result
- // of transforming a point rather than the values of each qauetrnions.
- let p = point3(1.0, 2.0, 3.0);
-
- let angle = Radians::new(FRAC_PI_2);
- let zero = Radians::new(0.0);
-
- // roll
- let roll_re = Rotation3D::euler(angle, zero, zero);
- let roll_rq = Rotation3D::around_x(angle);
- let roll_pe = roll_re.rotate_point3d(&p);
- let roll_pq = roll_rq.rotate_point3d(&p);
-
- // pitch
- let pitch_re = Rotation3D::euler(zero, angle, zero);
- let pitch_rq = Rotation3D::around_y(angle);
- let pitch_pe = pitch_re.rotate_point3d(&p);
- let pitch_pq = pitch_rq.rotate_point3d(&p);
-
- // yaw
- let yaw_re = Rotation3D::euler(zero, zero, angle);
- let yaw_rq = Rotation3D::around_z(angle);
- let yaw_pe = yaw_re.rotate_point3d(&p);
- let yaw_pq = yaw_rq.rotate_point3d(&p);
-
- assert!(roll_pe.approx_eq(&roll_pq));
- assert!(pitch_pe.approx_eq(&pitch_pq));
- assert!(yaw_pe.approx_eq(&yaw_pq));
-
- // Now check that the yaw pitch and roll transformations when compined are applied in
- // the proper order: roll -> pitch -> yaw.
- let ypr_e = Rotation3D::euler(angle, angle, angle);
- let ypr_q = roll_rq.post_rotate(&pitch_rq).post_rotate(&yaw_rq);
- let ypr_pe = ypr_e.rotate_point3d(&p);
- let ypr_pq = ypr_q.rotate_point3d(&p);
-
- assert!(ypr_pe.approx_eq(&ypr_pq));
-}
-
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/scale_factor.rs
+++ /dev/null
@@ -1,171 +0,0 @@
-// Copyright 2014 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.
-//! A type-checked scaling factor between units.
-
-use num::One;
-
-use heapsize::HeapSizeOf;
-use num_traits::NumCast;
-use serde::{Deserialize, Deserializer, Serialize, Serializer};
-use std::fmt;
-use std::ops::{Add, Mul, Sub, Div};
-use std::marker::PhantomData;
-
-/// A scaling factor between two different units of measurement.
-///
-/// This is effectively a type-safe float, intended to be used in combination with other types like
-/// `length::Length` to enforce conversion between systems of measurement at compile time.
-///
-/// `Src` and `Dst` represent the units before and after multiplying a value by a `ScaleFactor`. They
-/// may be types without values, such as empty enums. For example:
-///
-/// ```rust
-/// use euclid::ScaleFactor;
-/// use euclid::Length;
-/// enum Mm {};
-/// enum Inch {};
-///
-/// let mm_per_inch: ScaleFactor<f32, Inch, Mm> = ScaleFactor::new(25.4);
-///
-/// let one_foot: Length<f32, Inch> = Length::new(12.0);
-/// let one_foot_in_mm: Length<f32, Mm> = one_foot * mm_per_inch;
-/// ```
-#[repr(C)]
-pub struct ScaleFactor<T, Src, Dst>(pub T, PhantomData<(Src, Dst)>);
-
-impl<T: HeapSizeOf, Src, Dst> HeapSizeOf for ScaleFactor<T, Src, Dst> {
- fn heap_size_of_children(&self) -> usize {
- self.0.heap_size_of_children()
- }
-}
-
-impl<'de, T, Src, Dst> Deserialize<'de> for ScaleFactor<T, Src, Dst> where T: Deserialize<'de> {
- fn deserialize<D>(deserializer: D) -> Result<ScaleFactor<T, Src, Dst>, D::Error>
- where D: Deserializer<'de> {
- Ok(ScaleFactor(try!(Deserialize::deserialize(deserializer)), PhantomData))
- }
-}
-
-impl<T, Src, Dst> Serialize for ScaleFactor<T, Src, Dst> where T: Serialize {
- fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error> where S: Serializer {
- self.0.serialize(serializer)
- }
-}
-
-impl<T, Src, Dst> ScaleFactor<T, Src, Dst> {
- pub fn new(x: T) -> ScaleFactor<T, Src, Dst> {
- ScaleFactor(x, PhantomData)
- }
-}
-
-impl<T: Clone, Src, Dst> ScaleFactor<T, Src, Dst> {
- pub fn get(&self) -> T {
- self.0.clone()
- }
-}
-
-impl<T: Clone + One + Div<T, Output=T>, Src, Dst> ScaleFactor<T, Src, Dst> {
- /// The inverse ScaleFactor (1.0 / self).
- pub fn inv(&self) -> ScaleFactor<T, Dst, Src> {
- let one: T = One::one();
- ScaleFactor::new(one / self.get())
- }
-}
-
-// scale0 * scale1
-impl<T: Clone + Mul<T, Output=T>, A, B, C>
-Mul<ScaleFactor<T, B, C>> for ScaleFactor<T, A, B> {
- type Output = ScaleFactor<T, A, C>;
- #[inline]
- fn mul(self, other: ScaleFactor<T, B, C>) -> ScaleFactor<T, A, C> {
- ScaleFactor::new(self.get() * other.get())
- }
-}
-
-// scale0 + scale1
-impl<T: Clone + Add<T, Output=T>, Src, Dst> Add for ScaleFactor<T, Src, Dst> {
- type Output = ScaleFactor<T, Src, Dst>;
- #[inline]
- fn add(self, other: ScaleFactor<T, Src, Dst>) -> ScaleFactor<T, Src, Dst> {
- ScaleFactor::new(self.get() + other.get())
- }
-}
-
-// scale0 - scale1
-impl<T: Clone + Sub<T, Output=T>, Src, Dst> Sub for ScaleFactor<T, Src, Dst> {
- type Output = ScaleFactor<T, Src, Dst>;
- #[inline]
- fn sub(self, other: ScaleFactor<T, Src, Dst>) -> ScaleFactor<T, Src, Dst> {
- ScaleFactor::new(self.get() - other.get())
- }
-}
-
-impl<T: NumCast + Clone, Src, Dst0> ScaleFactor<T, Src, Dst0> {
- /// Cast from one numeric representation to another, preserving the units.
- pub fn cast<T1: NumCast + Clone>(&self) -> Option<ScaleFactor<T1, Src, Dst0>> {
- NumCast::from(self.get()).map(ScaleFactor::new)
- }
-}
-
-// FIXME: Switch to `derive(PartialEq, Clone)` after this Rust issue is fixed:
-// https://github.com/mozilla/rust/issues/7671
-
-impl<T: PartialEq, Src, Dst> PartialEq for ScaleFactor<T, Src, Dst> {
- fn eq(&self, other: &ScaleFactor<T, Src, Dst>) -> bool {
- self.0 == other.0
- }
-}
-
-impl<T: Clone, Src, Dst> Clone for ScaleFactor<T, Src, Dst> {
- fn clone(&self) -> ScaleFactor<T, Src, Dst> {
- ScaleFactor::new(self.get())
- }
-}
-
-impl<T: Copy, Src, Dst> Copy for ScaleFactor<T, Src, Dst> {}
-
-impl<T: fmt::Debug, Src, Dst> fmt::Debug for ScaleFactor<T, Src, Dst> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-impl<T: fmt::Display, Src, Dst> fmt::Display for ScaleFactor<T, Src, Dst> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- self.0.fmt(f)
- }
-}
-
-#[cfg(test)]
-mod tests {
- use super::ScaleFactor;
-
- enum Inch {}
- enum Cm {}
- enum Mm {}
-
- #[test]
- fn test_scale_factor() {
- let mm_per_inch: ScaleFactor<f32, Inch, Mm> = ScaleFactor::new(25.4);
- let cm_per_mm: ScaleFactor<f32, Mm, Cm> = ScaleFactor::new(0.1);
-
- let mm_per_cm: ScaleFactor<f32, Cm, Mm> = cm_per_mm.inv();
- assert_eq!(mm_per_cm.get(), 10.0);
-
- let cm_per_inch: ScaleFactor<f32, Inch, Cm> = mm_per_inch * cm_per_mm;
- assert_eq!(cm_per_inch, ScaleFactor::new(2.54));
-
- let a: ScaleFactor<isize, Inch, Inch> = ScaleFactor::new(2);
- let b: ScaleFactor<isize, Inch, Inch> = ScaleFactor::new(3);
- assert!(a != b);
- assert_eq!(a, a.clone());
- assert_eq!(a.clone() + b.clone(), ScaleFactor::new(5));
- assert_eq!(a - b, ScaleFactor::new(-1));
- }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/side_offsets.rs
+++ /dev/null
@@ -1,283 +0,0 @@
-// Copyright 2013 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.
-
-//! A group of side offsets, which correspond to top/left/bottom/right for borders, padding,
-//! and margins in CSS.
-
-use super::UnknownUnit;
-use length::Length;
-use num::Zero;
-use std::fmt;
-use std::ops::Add;
-use std::marker::PhantomData;
-
-#[cfg(feature = "unstable")]
-use heapsize::HeapSizeOf;
-
-/// A group of side offsets, which correspond to top/left/bottom/right for borders, padding,
-/// and margins in CSS, optionally tagged with a unit.
-define_matrix! {
- pub struct TypedSideOffsets2D<T, U> {
- pub top: T,
- pub right: T,
- pub bottom: T,
- pub left: T,
- }
-}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedSideOffsets2D<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "({:?},{:?},{:?},{:?})",
- self.top, self.right, self.bottom, self.left)
- }
-}
-
-/// The default side offset type with no unit.
-pub type SideOffsets2D<T> = TypedSideOffsets2D<T, UnknownUnit>;
-
-impl<T: Copy, U> TypedSideOffsets2D<T, U> {
- /// Constructor taking a scalar for each side.
- pub fn new(top: T, right: T, bottom: T, left: T) -> Self {
- TypedSideOffsets2D {
- top: top,
- right: right,
- bottom: bottom,
- left: left,
- _unit: PhantomData,
- }
- }
-
- /// Constructor taking a typed Length for each side.
- pub fn from_lengths(top: Length<T, U>,
- right: Length<T, U>,
- bottom: Length<T, U>,
- left: Length<T, U>) -> Self {
- TypedSideOffsets2D::new(top.0, right.0, bottom.0, left.0)
- }
-
- /// Access self.top as a typed Length instead of a scalar value.
- pub fn top_typed(&self) -> Length<T, U> { Length::new(self.top) }
-
- /// Access self.right as a typed Length instead of a scalar value.
- pub fn right_typed(&self) -> Length<T, U> { Length::new(self.right) }
-
- /// Access self.bottom as a typed Length instead of a scalar value.
- pub fn bottom_typed(&self) -> Length<T, U> { Length::new(self.bottom) }
-
- /// Access self.left as a typed Length instead of a scalar value.
- pub fn left_typed(&self) -> Length<T, U> { Length::new(self.left) }
-
- /// Constructor setting the same value to all sides, taking a scalar value directly.
- pub fn new_all_same(all: T) -> Self {
- TypedSideOffsets2D::new(all, all, all, all)
- }
-
- /// Constructor setting the same value to all sides, taking a typed Length.
- pub fn from_length_all_same(all: Length<T, U>) -> Self {
- TypedSideOffsets2D::new_all_same(all.0)
- }
-}
-
-impl<T, U> TypedSideOffsets2D<T, U> where T: Add<T, Output=T> + Copy {
- pub fn horizontal(&self) -> T {
- self.left + self.right
- }
-
- pub fn vertical(&self) -> T {
- self.top + self.bottom
- }
-
- pub fn horizontal_typed(&self) -> Length<T, U> {
- Length::new(self.horizontal())
- }
-
- pub fn vertical_typed(&self) -> Length<T, U> {
- Length::new(self.vertical())
- }
-}
-
-impl<T, U> Add for TypedSideOffsets2D<T, U> where T : Copy + Add<T, Output=T> {
- type Output = Self;
- fn add(self, other: Self) -> Self {
- TypedSideOffsets2D::new(
- self.top + other.top,
- self.right + other.right,
- self.bottom + other.bottom,
- self.left + other.left,
- )
- }
-}
-
-impl<T: Copy + Zero, U> TypedSideOffsets2D<T, U> {
- /// Constructor, setting all sides to zero.
- pub fn zero() -> Self {
- TypedSideOffsets2D::new(
- Zero::zero(),
- Zero::zero(),
- Zero::zero(),
- Zero::zero(),
- )
- }
-}
-
-/// A SIMD enabled version of TypedSideOffsets2D specialized for i32.
-#[cfg(feature = "unstable")]
-#[derive(Clone, Copy, PartialEq)]
-#[repr(simd)]
-pub struct SideOffsets2DSimdI32 {
- pub top: i32,
- pub bottom: i32,
- pub right: i32,
- pub left: i32,
-}
-
-#[cfg(feature = "unstable")]
-impl HeapSizeOf for SideOffsets2DSimdI32 {
- fn heap_size_of_children(&self) -> usize { 0 }
-}
-
-#[cfg(feature = "unstable")]
-impl SideOffsets2DSimdI32 {
- #[inline]
- pub fn new(top: i32, right: i32, bottom: i32, left: i32) -> SideOffsets2DSimdI32 {
- SideOffsets2DSimdI32 {
- top: top,
- bottom: bottom,
- right: right,
- left: left,
- }
- }
-}
-
-#[cfg(feature = "unstable")]
-impl SideOffsets2DSimdI32 {
- #[inline]
- pub fn new_all_same(all: i32) -> SideOffsets2DSimdI32 {
- SideOffsets2DSimdI32::new(all.clone(), all.clone(), all.clone(), all.clone())
- }
-}
-
-#[cfg(feature = "unstable")]
-impl SideOffsets2DSimdI32 {
- #[inline]
- pub fn horizontal(&self) -> i32 {
- self.left + self.right
- }
-
- #[inline]
- pub fn vertical(&self) -> i32 {
- self.top + self.bottom
- }
-}
-
-/*impl Add for SideOffsets2DSimdI32 {
- type Output = SideOffsets2DSimdI32;
- #[inline]
- fn add(self, other: SideOffsets2DSimdI32) -> SideOffsets2DSimdI32 {
- self + other // Use SIMD addition
- }
-}*/
-
-#[cfg(feature = "unstable")]
-impl SideOffsets2DSimdI32 {
- #[inline]
- pub fn zero() -> SideOffsets2DSimdI32 {
- SideOffsets2DSimdI32 {
- top: 0,
- bottom: 0,
- right: 0,
- left: 0,
- }
- }
-
- #[cfg(not(target_arch = "x86_64"))]
- #[inline]
- pub fn is_zero(&self) -> bool {
- self.top == 0 && self.right == 0 && self.bottom == 0 && self.left == 0
- }
-
- #[cfg(target_arch = "x86_64")]
- #[inline]
- pub fn is_zero(&self) -> bool {
- let is_zero: bool;
- unsafe {
- asm! {
- "ptest $1, $1
- setz $0"
- : "=r"(is_zero)
- : "x"(*self)
- :
- : "intel"
- };
- }
- is_zero
- }
-}
-
-#[cfg(feature = "unstable")]
-#[cfg(test)]
-mod tests {
- use super::SideOffsets2DSimdI32;
-
- #[test]
- fn test_is_zero() {
- assert!(SideOffsets2DSimdI32::new_all_same(0).is_zero());
- assert!(!SideOffsets2DSimdI32::new_all_same(1).is_zero());
- assert!(!SideOffsets2DSimdI32::new(1, 0, 0, 0).is_zero());
- assert!(!SideOffsets2DSimdI32::new(0, 1, 0, 0).is_zero());
- assert!(!SideOffsets2DSimdI32::new(0, 0, 1, 0).is_zero());
- assert!(!SideOffsets2DSimdI32::new(0, 0, 0, 1).is_zero());
- }
-}
-
-#[cfg(feature = "unstable")]
-#[cfg(bench)]
-mod bench {
- use test::BenchHarness;
- use std::num::Zero;
- use rand::{XorShiftRng, Rng};
- use super::SideOffsets2DSimdI32;
-
- #[cfg(target_arch = "x86")]
- #[cfg(target_arch = "x86_64")]
- #[bench]
- fn bench_naive_is_zero(bh: &mut BenchHarness) {
- fn is_zero(x: &SideOffsets2DSimdI32) -> bool {
- x.top.is_zero() && x.right.is_zero() && x.bottom.is_zero() && x.left.is_zero()
- }
- let mut rng = XorShiftRng::new().unwrap();
- bh.iter(|| is_zero(&rng.gen::<SideOffsets2DSimdI32>()))
- }
-
- #[bench]
- fn bench_is_zero(bh: &mut BenchHarness) {
- let mut rng = XorShiftRng::new().unwrap();
- bh.iter(|| rng.gen::<SideOffsets2DSimdI32>().is_zero())
- }
-
- #[bench]
- fn bench_naive_add(bh: &mut BenchHarness) {
- fn add(x: &SideOffsets2DSimdI32, y: &SideOffsets2DSimdI32) -> SideOffsets2DSimdI32 {
- SideOffsets2DSimdI32 {
- top: x.top + y.top,
- right: x.right + y.right,
- bottom: x.bottom + y.bottom,
- left: x.left + y.left,
- }
- }
- let mut rng = XorShiftRng::new().unwrap();
- bh.iter(|| add(&rng.gen::<SideOffsets2DSimdI32>(), &rng.gen::<SideOffsets2DSimdI32>()))
- }
-
- #[bench]
- fn bench_add(bh: &mut BenchHarness) {
- let mut rng = XorShiftRng::new().unwrap();
- bh.iter(|| rng.gen::<SideOffsets2DSimdI32>() + rng.gen::<SideOffsets2DSimdI32>())
- }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/size.rs
+++ /dev/null
@@ -1,311 +0,0 @@
-// Copyright 2013 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.
-
-use super::UnknownUnit;
-use length::Length;
-use scale_factor::ScaleFactor;
-use vector::{TypedVector2D, vec2};
-use num::*;
-
-use num_traits::{NumCast, Signed};
-use std::fmt;
-use std::ops::{Add, Div, Mul, Sub};
-use std::marker::PhantomData;
-
-/// A 2d size tagged with a unit.
-define_matrix! {
- pub struct TypedSize2D<T, U> {
- pub width: T,
- pub height: T,
- }
-}
-
-/// Default 2d size type with no unit.
-///
-/// `Size2D` provides the same methods as `TypedSize2D`.
-pub type Size2D<T> = TypedSize2D<T, UnknownUnit>;
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedSize2D<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{:?}×{:?}", self.width, self.height)
- }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedSize2D<T, U> {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- write!(formatter, "({}x{})", self.width, self.height)
- }
-}
-
-impl<T, U> TypedSize2D<T, U> {
- /// Constructor taking scalar values.
- pub fn new(width: T, height: T) -> Self {
- TypedSize2D {
- width: width,
- height: height,
- _unit: PhantomData,
- }
- }
-}
-
-impl<T: Clone, U> TypedSize2D<T, U> {
- /// Constructor taking scalar strongly typed lengths.
- pub fn from_lengths(width: Length<T, U>, height: Length<T, U>) -> Self {
- TypedSize2D::new(width.get(), height.get())
- }
-}
-
-impl<T: Round, U> TypedSize2D<T, U> {
- /// Rounds each component to the nearest integer value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- pub fn round(&self) -> Self {
- TypedSize2D::new(self.width.round(), self.height.round())
- }
-}
-
-impl<T: Ceil, U> TypedSize2D<T, U> {
- /// Rounds each component to the smallest integer equal or greater than the original value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- pub fn ceil(&self) -> Self {
- TypedSize2D::new(self.width.ceil(), self.height.ceil())
- }
-}
-
-impl<T: Floor, U> TypedSize2D<T, U> {
- /// Rounds each component to the biggest integer equal or lower than the original value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- pub fn floor(&self) -> Self {
- TypedSize2D::new(self.width.floor(), self.height.floor())
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add for TypedSize2D<T, U> {
- type Output = Self;
- fn add(self, other: Self) -> Self {
- TypedSize2D::new(self.width + other.width, self.height + other.height)
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub for TypedSize2D<T, U> {
- type Output = Self;
- fn sub(self, other: Self) -> Self {
- TypedSize2D::new(self.width - other.width, self.height - other.height)
- }
-}
-
-impl<T: Copy + Clone + Mul<T>, U> TypedSize2D<T, U> {
- pub fn area(&self) -> T::Output { self.width * self.height }
-}
-
-impl<T, U> TypedSize2D<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
- /// Linearly interpolate between this size and another size.
- ///
- /// `t` is expected to be between zero and one.
- #[inline]
- pub fn lerp(&self, other: Self, t: T) -> Self {
- let one_t = T::one() - t;
- size2(
- one_t * self.width + t * other.width,
- one_t * self.height + t * other.height,
- )
- }
-}
-
-impl<T: Zero, U> TypedSize2D<T, U> {
- pub fn zero() -> Self {
- TypedSize2D::new(
- Zero::zero(),
- Zero::zero(),
- )
- }
-}
-
-impl<T: Zero, U> Zero for TypedSize2D<T, U> {
- fn zero() -> Self {
- TypedSize2D::new(
- Zero::zero(),
- Zero::zero(),
- )
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedSize2D<T, U> {
- type Output = Self;
- #[inline]
- fn mul(self, scale: T) -> Self {
- TypedSize2D::new(self.width * scale, self.height * scale)
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedSize2D<T, U> {
- type Output = Self;
- #[inline]
- fn div(self, scale: T) -> Self {
- TypedSize2D::new(self.width / scale, self.height / scale)
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U1, U2> Mul<ScaleFactor<T, U1, U2>> for TypedSize2D<T, U1> {
- type Output = TypedSize2D<T, U2>;
- #[inline]
- fn mul(self, scale: ScaleFactor<T, U1, U2>) -> TypedSize2D<T, U2> {
- TypedSize2D::new(self.width * scale.get(), self.height * scale.get())
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U1, U2> Div<ScaleFactor<T, U1, U2>> for TypedSize2D<T, U2> {
- type Output = TypedSize2D<T, U1>;
- #[inline]
- fn div(self, scale: ScaleFactor<T, U1, U2>) -> TypedSize2D<T, U1> {
- TypedSize2D::new(self.width / scale.get(), self.height / scale.get())
- }
-}
-
-impl<T: Copy, U> TypedSize2D<T, U> {
- /// Returns self.width as a Length carrying the unit.
- #[inline]
- pub fn width_typed(&self) -> Length<T, U> { Length::new(self.width) }
-
- /// Returns self.height as a Length carrying the unit.
- #[inline]
- pub fn height_typed(&self) -> Length<T, U> { Length::new(self.height) }
-
- #[inline]
- pub fn to_array(&self) -> [T; 2] { [self.width, self.height] }
-
- #[inline]
- pub fn to_vector(&self) -> TypedVector2D<T, U> { vec2(self.width, self.height) }
-
- /// Drop the units, preserving only the numeric value.
- pub fn to_untyped(&self) -> Size2D<T> {
- TypedSize2D::new(self.width, self.height)
- }
-
- /// Tag a unitless value with units.
- pub fn from_untyped(p: &Size2D<T>) -> Self {
- TypedSize2D::new(p.width, p.height)
- }
-}
-
-impl<T: NumCast + Copy, Unit> TypedSize2D<T, Unit> {
- /// Cast from one numeric representation to another, preserving the units.
- ///
- /// When casting from floating point to integer coordinates, the decimals are truncated
- /// as one would expect from a simple cast, but this behavior does not always make sense
- /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
- pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedSize2D<NewT, Unit>> {
- match (NumCast::from(self.width), NumCast::from(self.height)) {
- (Some(w), Some(h)) => Some(TypedSize2D::new(w, h)),
- _ => None
- }
- }
-
- // Convenience functions for common casts
-
- /// Cast into an `f32` size.
- pub fn to_f32(&self) -> TypedSize2D<f32, Unit> {
- self.cast().unwrap()
- }
-
- /// Cast into an `uint` size, truncating decimals if any.
- ///
- /// When casting from floating point sizes, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- pub fn to_usize(&self) -> TypedSize2D<usize, Unit> {
- self.cast().unwrap()
- }
-
- /// Cast into an `i32` size, truncating decimals if any.
- ///
- /// When casting from floating point sizes, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- pub fn to_i32(&self) -> TypedSize2D<i32, Unit> {
- self.cast().unwrap()
- }
-
- /// Cast into an `i64` size, truncating decimals if any.
- ///
- /// When casting from floating point sizes, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- pub fn to_i64(&self) -> TypedSize2D<i64, Unit> {
- self.cast().unwrap()
- }
-}
-
-impl<T, U> TypedSize2D<T, U>
-where T: Signed {
- pub fn abs(&self) -> Self {
- size2(self.width.abs(), self.height.abs())
- }
-
- pub fn is_positive(&self) -> bool {
- self.width.is_positive() && self.height.is_positive()
- }
-}
-
-/// Shorthand for `TypedSize2D::new(w, h)`.
-pub fn size2<T, U>(w: T, h: T) -> TypedSize2D<T, U> {
- TypedSize2D::new(w, h)
-}
-
-#[cfg(test)]
-mod size2d {
- use super::Size2D;
-
- #[test]
- pub fn test_add() {
- let p1 = Size2D::new(1.0, 2.0);
- let p2 = Size2D::new(3.0, 4.0);
- assert_eq!(p1 + p2, Size2D::new(4.0, 6.0));
-
- let p1 = Size2D::new(1.0, 2.0);
- let p2 = Size2D::new(0.0, 0.0);
- assert_eq!(p1 + p2, Size2D::new(1.0, 2.0));
-
- let p1 = Size2D::new(1.0, 2.0);
- let p2 = Size2D::new(-3.0, -4.0);
- assert_eq!(p1 + p2, Size2D::new(-2.0, -2.0));
-
- let p1 = Size2D::new(0.0, 0.0);
- let p2 = Size2D::new(0.0, 0.0);
- assert_eq!(p1 + p2, Size2D::new(0.0, 0.0));
- }
-
- #[test]
- pub fn test_sub() {
- let p1 = Size2D::new(1.0, 2.0);
- let p2 = Size2D::new(3.0, 4.0);
- assert_eq!(p1 - p2, Size2D::new(-2.0, -2.0));
-
- let p1 = Size2D::new(1.0, 2.0);
- let p2 = Size2D::new(0.0, 0.0);
- assert_eq!(p1 - p2, Size2D::new(1.0, 2.0));
-
- let p1 = Size2D::new(1.0, 2.0);
- let p2 = Size2D::new(-3.0, -4.0);
- assert_eq!(p1 - p2, Size2D::new(4.0, 6.0));
-
- let p1 = Size2D::new(0.0, 0.0);
- let p2 = Size2D::new(0.0, 0.0);
- assert_eq!(p1 - p2, Size2D::new(0.0, 0.0));
- }
-
- #[test]
- pub fn test_area() {
- let p = Size2D::new(1.5, 2.0);
- assert_eq!(p.area(), 3.0);
- }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/transform2d.rs
+++ /dev/null
@@ -1,526 +0,0 @@
-// Copyright 2013 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.
-
-use super::{UnknownUnit, Radians};
-use num::{One, Zero};
-use point::TypedPoint2D;
-use vector::{TypedVector2D, vec2};
-use rect::TypedRect;
-use transform3d::TypedTransform3D;
-use std::ops::{Add, Mul, Div, Sub, Neg};
-use std::marker::PhantomData;
-use approxeq::ApproxEq;
-use trig::Trig;
-use std::fmt;
-use num_traits::NumCast;
-
-define_matrix! {
- /// A 2d transform stored as a 2 by 3 matrix in row-major order in memory.
- ///
- /// Transforms can be parametrized over the source and destination units, to describe a
- /// transformation from a space to another.
- /// For example, `TypedTransform2D<f32, WordSpace, ScreenSpace>::transform_point4d`
- /// takes a `TypedPoint2D<f32, WordSpace>` and returns a `TypedPoint2D<f32, ScreenSpace>`.
- ///
- /// Transforms expose a set of convenience methods for pre- and post-transformations.
- /// A pre-transformation corresponds to adding an operation that is applied before
- /// the rest of the transformation, while a post-transformation adds an operation
- /// that is applied after.
- pub struct TypedTransform2D<T, Src, Dst> {
- pub m11: T, pub m12: T,
- pub m21: T, pub m22: T,
- pub m31: T, pub m32: T,
- }
-}
-
-/// The default 2d transform type with no units.
-pub type Transform2D<T> = TypedTransform2D<T, UnknownUnit, UnknownUnit>;
-
-impl<T: Copy, Src, Dst> TypedTransform2D<T, Src, Dst> {
- /// Create a transform specifying its matrix elements in row-major order.
- pub fn row_major(m11: T, m12: T, m21: T, m22: T, m31: T, m32: T) -> Self {
- TypedTransform2D {
- m11: m11, m12: m12,
- m21: m21, m22: m22,
- m31: m31, m32: m32,
- _unit: PhantomData,
- }
- }
-
- /// Create a transform specifying its matrix elements in column-major order.
- pub fn column_major(m11: T, m21: T, m31: T, m12: T, m22: T, m32: T) -> Self {
- TypedTransform2D {
- m11: m11, m12: m12,
- m21: m21, m22: m22,
- m31: m31, m32: m32,
- _unit: PhantomData,
- }
- }
-
- /// Returns an array containing this transform's terms in row-major order (the order
- /// in which the transform is actually laid out in memory).
- pub fn to_row_major_array(&self) -> [T; 6] {
- [
- self.m11, self.m12,
- self.m21, self.m22,
- self.m31, self.m32
- ]
- }
-
- /// Returns an array containing this transform's terms in column-major order.
- pub fn to_column_major_array(&self) -> [T; 6] {
- [
- self.m11, self.m21, self.m31,
- self.m12, self.m22, self.m32
- ]
- }
-
- /// Returns an array containing this transform's 3 rows in (in row-major order)
- /// as arrays.
- ///
- /// This is a convenience method to interface with other libraries like glium.
- pub fn to_row_arrays(&self) -> [[T; 2]; 3] {
- [
- [self.m11, self.m12],
- [self.m21, self.m22],
- [self.m31, self.m32],
- ]
- }
-
- /// Creates a transform from an array of 6 elements in row-major order.
- pub fn from_row_major_array(array: [T; 6]) -> Self {
- Self::row_major(
- array[0], array[1],
- array[2], array[3],
- array[4], array[5],
- )
- }
-
- /// Creates a transform from 3 rows of 2 elements (row-major order).
- pub fn from_row_arrays(array: [[T; 2]; 3]) -> Self {
- Self::row_major(
- array[0][0], array[0][1],
- array[1][0], array[1][1],
- array[2][0], array[2][1],
- )
- }
-
- /// Drop the units, preserving only the numeric value.
- pub fn to_untyped(&self) -> Transform2D<T> {
- Transform2D::row_major(
- self.m11, self.m12,
- self.m21, self.m22,
- self.m31, self.m32
- )
- }
-
- /// Tag a unitless value with units.
- pub fn from_untyped(p: &Transform2D<T>) -> Self {
- TypedTransform2D::row_major(
- p.m11, p.m12,
- p.m21, p.m22,
- p.m31, p.m32
- )
- }
-}
-
-impl<T0: NumCast + Copy, Src, Dst> TypedTransform2D<T0, Src, Dst> {
- /// Cast from one numeric representation to another, preserving the units.
- pub fn cast<T1: NumCast + Copy>(&self) -> Option<TypedTransform2D<T1, Src, Dst>> {
- match (NumCast::from(self.m11), NumCast::from(self.m12),
- NumCast::from(self.m21), NumCast::from(self.m22),
- NumCast::from(self.m31), NumCast::from(self.m32)) {
- (Some(m11), Some(m12),
- Some(m21), Some(m22),
- Some(m31), Some(m32)) => {
- Some(TypedTransform2D::row_major(m11, m12,
- m21, m22,
- m31, m32))
- },
- _ => None
- }
- }
-}
-
-impl<T, Src, Dst> TypedTransform2D<T, Src, Dst>
-where T: Copy +
- PartialEq +
- One + Zero {
- pub fn identity() -> Self {
- let (_0, _1) = (Zero::zero(), One::one());
- TypedTransform2D::row_major(
- _1, _0,
- _0, _1,
- _0, _0
- )
- }
-
- // Intentional not public, because it checks for exact equivalence
- // while most consumers will probably want some sort of approximate
- // equivalence to deal with floating-point errors.
- fn is_identity(&self) -> bool {
- *self == TypedTransform2D::identity()
- }
-}
-
-impl<T, Src, Dst> TypedTransform2D<T, Src, Dst>
-where T: Copy + Clone +
- Add<T, Output=T> +
- Mul<T, Output=T> +
- Div<T, Output=T> +
- Sub<T, Output=T> +
- Trig +
- PartialOrd +
- One + Zero {
-
- /// Returns the multiplication of the two matrices such that mat's transformation
- /// applies after self's transformation.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn post_mul<NewDst>(&self, mat: &TypedTransform2D<T, Dst, NewDst>) -> TypedTransform2D<T, Src, NewDst> {
- TypedTransform2D::row_major(
- self.m11 * mat.m11 + self.m12 * mat.m21,
- self.m11 * mat.m12 + self.m12 * mat.m22,
- self.m21 * mat.m11 + self.m22 * mat.m21,
- self.m21 * mat.m12 + self.m22 * mat.m22,
- self.m31 * mat.m11 + self.m32 * mat.m21 + mat.m31,
- self.m31 * mat.m12 + self.m32 * mat.m22 + mat.m32,
- )
- }
-
- /// Returns the multiplication of the two matrices such that mat's transformation
- /// applies before self's transformation.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn pre_mul<NewSrc>(&self, mat: &TypedTransform2D<T, NewSrc, Src>) -> TypedTransform2D<T, NewSrc, Dst> {
- mat.post_mul(self)
- }
-
- /// Returns a translation transform.
- pub fn create_translation(x: T, y: T) -> Self {
- let (_0, _1): (T, T) = (Zero::zero(), One::one());
- TypedTransform2D::row_major(
- _1, _0,
- _0, _1,
- x, y
- )
- }
-
- /// Applies a translation after self's transformation and returns the resulting transform.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn post_translate(&self, v: TypedVector2D<T, Dst>) -> Self {
- self.post_mul(&TypedTransform2D::create_translation(v.x, v.y))
- }
-
- /// Applies a translation before self's transformation and returns the resulting transform.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn pre_translate(&self, v: TypedVector2D<T, Src>) -> Self {
- self.pre_mul(&TypedTransform2D::create_translation(v.x, v.y))
- }
-
- /// Returns a scale transform.
- pub fn create_scale(x: T, y: T) -> Self {
- let _0 = Zero::zero();
- TypedTransform2D::row_major(
- x, _0,
- _0, y,
- _0, _0
- )
- }
-
- /// Applies a scale after self's transformation and returns the resulting transform.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn post_scale(&self, x: T, y: T) -> Self {
- self.post_mul(&TypedTransform2D::create_scale(x, y))
- }
-
- /// Applies a scale before self's transformation and returns the resulting transform.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn pre_scale(&self, x: T, y: T) -> Self {
- TypedTransform2D::row_major(
- self.m11 * x, self.m12,
- self.m21, self.m22 * y,
- self.m31, self.m32
- )
- }
-
- /// Returns a rotation transform.
- pub fn create_rotation(theta: Radians<T>) -> Self {
- let _0 = Zero::zero();
- let cos = theta.get().cos();
- let sin = theta.get().sin();
- TypedTransform2D::row_major(
- cos, _0 - sin,
- sin, cos,
- _0, _0
- )
- }
-
- /// Applies a rotation after self's transformation and returns the resulting transform.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn post_rotate(&self, theta: Radians<T>) -> Self {
- self.post_mul(&TypedTransform2D::create_rotation(theta))
- }
-
- /// Applies a rotation after self's transformation and returns the resulting transform.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn pre_rotate(&self, theta: Radians<T>) -> Self {
- self.pre_mul(&TypedTransform2D::create_rotation(theta))
- }
-
- /// Returns the given point transformed by this transform.
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn transform_point(&self, point: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
- TypedPoint2D::new(point.x * self.m11 + point.y * self.m21 + self.m31,
- point.x * self.m12 + point.y * self.m22 + self.m32)
- }
-
- /// Returns the given vector transformed by this matrix.
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn transform_vector(&self, vec: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
- vec2(vec.x * self.m11 + vec.y * self.m21,
- vec.x * self.m12 + vec.y * self.m22)
- }
-
- /// Returns a rectangle that encompasses the result of transforming the given rectangle by this
- /// transform.
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn transform_rect(&self, rect: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
- TypedRect::from_points(&[
- self.transform_point(&rect.origin),
- self.transform_point(&rect.top_right()),
- self.transform_point(&rect.bottom_left()),
- self.transform_point(&rect.bottom_right()),
- ])
- }
-
- /// Computes and returns the determinant of this transform.
- pub fn determinant(&self) -> T {
- self.m11 * self.m22 - self.m12 * self.m21
- }
-
- /// Returns the inverse transform if possible.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn inverse(&self) -> Option<TypedTransform2D<T, Dst, Src>> {
- let det = self.determinant();
-
- let _0: T = Zero::zero();
- let _1: T = One::one();
-
- if det == _0 {
- return None;
- }
-
- let inv_det = _1 / det;
- Some(TypedTransform2D::row_major(
- inv_det * self.m22,
- inv_det * (_0 - self.m12),
- inv_det * (_0 - self.m21),
- inv_det * self.m11,
- inv_det * (self.m21 * self.m32 - self.m22 * self.m31),
- inv_det * (self.m31 * self.m12 - self.m11 * self.m32),
- ))
- }
-
- /// Returns the same transform with a different destination unit.
- #[inline]
- pub fn with_destination<NewDst>(&self) -> TypedTransform2D<T, Src, NewDst> {
- TypedTransform2D::row_major(
- self.m11, self.m12,
- self.m21, self.m22,
- self.m31, self.m32,
- )
- }
-
- /// Returns the same transform with a different source unit.
- #[inline]
- pub fn with_source<NewSrc>(&self) -> TypedTransform2D<T, NewSrc, Dst> {
- TypedTransform2D::row_major(
- self.m11, self.m12,
- self.m21, self.m22,
- self.m31, self.m32,
- )
- }
-}
-
-impl <T, Src, Dst> TypedTransform2D<T, Src, Dst>
-where T: Copy + Clone +
- Add<T, Output=T> +
- Sub<T, Output=T> +
- Mul<T, Output=T> +
- Div<T, Output=T> +
- Neg<Output=T> +
- ApproxEq<T> +
- PartialOrd +
- Trig +
- One + Zero {
- /// Create a 3D transform from the current transform
- pub fn to_3d(&self) -> TypedTransform3D<T, Src, Dst> {
- TypedTransform3D::row_major_2d(self.m11, self.m12, self.m21, self.m22, self.m31, self.m32)
- }
-
-}
-
-impl<T: ApproxEq<T>, Src, Dst> TypedTransform2D<T, Src, Dst> {
- pub fn approx_eq(&self, other: &Self) -> bool {
- self.m11.approx_eq(&other.m11) && self.m12.approx_eq(&other.m12) &&
- self.m21.approx_eq(&other.m21) && self.m22.approx_eq(&other.m22) &&
- self.m31.approx_eq(&other.m31) && self.m32.approx_eq(&other.m32)
- }
-}
-
-impl<T: Copy + fmt::Debug, Src, Dst> fmt::Debug for TypedTransform2D<T, Src, Dst>
-where T: Copy + fmt::Debug +
- PartialEq +
- One + Zero {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- if self.is_identity() {
- write!(f, "[I]")
- } else {
- self.to_row_major_array().fmt(f)
- }
- }
-}
-
-#[cfg(test)]
-mod test {
- use super::*;
- use approxeq::ApproxEq;
- use point::Point2D;
- use Radians;
-
- use std::f32::consts::FRAC_PI_2;
-
- type Mat = Transform2D<f32>;
-
- fn rad(v: f32) -> Radians<f32> { Radians::new(v) }
-
- #[test]
- pub fn test_translation() {
- let t1 = Mat::create_translation(1.0, 2.0);
- let t2 = Mat::identity().pre_translate(vec2(1.0, 2.0));
- let t3 = Mat::identity().post_translate(vec2(1.0, 2.0));
- assert_eq!(t1, t2);
- assert_eq!(t1, t3);
-
- assert_eq!(t1.transform_point(&Point2D::new(1.0, 1.0)), Point2D::new(2.0, 3.0));
-
- assert_eq!(t1.post_mul(&t1), Mat::create_translation(2.0, 4.0));
- }
-
- #[test]
- pub fn test_rotation() {
- let r1 = Mat::create_rotation(rad(FRAC_PI_2));
- let r2 = Mat::identity().pre_rotate(rad(FRAC_PI_2));
- let r3 = Mat::identity().post_rotate(rad(FRAC_PI_2));
- assert_eq!(r1, r2);
- assert_eq!(r1, r3);
-
- assert!(r1.transform_point(&Point2D::new(1.0, 2.0)).approx_eq(&Point2D::new(2.0, -1.0)));
-
- assert!(r1.post_mul(&r1).approx_eq(&Mat::create_rotation(rad(FRAC_PI_2*2.0))));
- }
-
- #[test]
- pub fn test_scale() {
- let s1 = Mat::create_scale(2.0, 3.0);
- let s2 = Mat::identity().pre_scale(2.0, 3.0);
- let s3 = Mat::identity().post_scale(2.0, 3.0);
- assert_eq!(s1, s2);
- assert_eq!(s1, s3);
-
- assert!(s1.transform_point(&Point2D::new(2.0, 2.0)).approx_eq(&Point2D::new(4.0, 6.0)));
- }
-
- #[test]
- fn test_column_major() {
- assert_eq!(
- Mat::row_major(
- 1.0, 2.0,
- 3.0, 4.0,
- 5.0, 6.0
- ),
- Mat::column_major(
- 1.0, 3.0, 5.0,
- 2.0, 4.0, 6.0,
- )
- );
- }
-
- #[test]
- pub fn test_inverse_simple() {
- let m1 = Mat::identity();
- let m2 = m1.inverse().unwrap();
- assert!(m1.approx_eq(&m2));
- }
-
- #[test]
- pub fn test_inverse_scale() {
- let m1 = Mat::create_scale(1.5, 0.3);
- let m2 = m1.inverse().unwrap();
- assert!(m1.pre_mul(&m2).approx_eq(&Mat::identity()));
- }
-
- #[test]
- pub fn test_inverse_translate() {
- let m1 = Mat::create_translation(-132.0, 0.3);
- let m2 = m1.inverse().unwrap();
- assert!(m1.pre_mul(&m2).approx_eq(&Mat::identity()));
- }
-
- #[test]
- fn test_inverse_none() {
- assert!(Mat::create_scale(2.0, 0.0).inverse().is_none());
- assert!(Mat::create_scale(2.0, 2.0).inverse().is_some());
- }
-
- #[test]
- pub fn test_pre_post() {
- let m1 = Transform2D::identity().post_scale(1.0, 2.0).post_translate(vec2(1.0, 2.0));
- let m2 = Transform2D::identity().pre_translate(vec2(1.0, 2.0)).pre_scale(1.0, 2.0);
- assert!(m1.approx_eq(&m2));
-
- let r = Mat::create_rotation(rad(FRAC_PI_2));
- let t = Mat::create_translation(2.0, 3.0);
-
- let a = Point2D::new(1.0, 1.0);
-
- assert!(r.post_mul(&t).transform_point(&a).approx_eq(&Point2D::new(3.0, 2.0)));
- assert!(t.post_mul(&r).transform_point(&a).approx_eq(&Point2D::new(4.0, -3.0)));
- assert!(t.post_mul(&r).transform_point(&a).approx_eq(&r.transform_point(&t.transform_point(&a))));
-
- assert!(r.pre_mul(&t).transform_point(&a).approx_eq(&Point2D::new(4.0, -3.0)));
- assert!(t.pre_mul(&r).transform_point(&a).approx_eq(&Point2D::new(3.0, 2.0)));
- assert!(t.pre_mul(&r).transform_point(&a).approx_eq(&t.transform_point(&r.transform_point(&a))));
- }
-
- #[test]
- fn test_size_of() {
- use std::mem::size_of;
- assert_eq!(size_of::<Transform2D<f32>>(), 6*size_of::<f32>());
- assert_eq!(size_of::<Transform2D<f64>>(), 6*size_of::<f64>());
- }
-
- #[test]
- pub fn test_is_identity() {
- let m1 = Transform2D::identity();
- assert!(m1.is_identity());
- let m2 = m1.post_translate(vec2(0.1, 0.0));
- assert!(!m2.is_identity());
- }
-
- #[test]
- pub fn test_transform_vector() {
- // Translation does not apply to vectors.
- let m1 = Mat::create_translation(1.0, 1.0);
- let v1 = vec2(10.0, -10.0);
- assert_eq!(v1, m1.transform_vector(&v1));
- }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/transform3d.rs
+++ /dev/null
@@ -1,945 +0,0 @@
-// Copyright 2013 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.
-
-use super::{UnknownUnit, Radians};
-use approxeq::ApproxEq;
-use trig::Trig;
-use point::{TypedPoint2D, TypedPoint3D, point2, point3};
-use vector::{TypedVector2D, TypedVector3D, vec2, vec3};
-use rect::TypedRect;
-use transform2d::TypedTransform2D;
-use scale_factor::ScaleFactor;
-use num::{One, Zero};
-use std::ops::{Add, Mul, Sub, Div, Neg};
-use std::marker::PhantomData;
-use std::fmt;
-use num_traits::NumCast;
-
-define_matrix! {
- /// A 3d transform stored as a 4 by 4 matrix in row-major order in memory.
- ///
- /// Transforms can be parametrized over the source and destination units, to describe a
- /// transformation from a space to another.
- /// For example, `TypedTransform3D<f32, WordSpace, ScreenSpace>::transform_point3d`
- /// takes a `TypedPoint3D<f32, WordSpace>` and returns a `TypedPoint3D<f32, ScreenSpace>`.
- ///
- /// Transforms expose a set of convenience methods for pre- and post-transformations.
- /// A pre-transformation corresponds to adding an operation that is applied before
- /// the rest of the transformation, while a post-transformation adds an operation
- /// that is applied after.
- pub struct TypedTransform3D<T, Src, Dst> {
- pub m11: T, pub m12: T, pub m13: T, pub m14: T,
- pub m21: T, pub m22: T, pub m23: T, pub m24: T,
- pub m31: T, pub m32: T, pub m33: T, pub m34: T,
- pub m41: T, pub m42: T, pub m43: T, pub m44: T,
- }
-}
-
-/// The default 4d transform type with no units.
-pub type Transform3D<T> = TypedTransform3D<T, UnknownUnit, UnknownUnit>;
-
-impl<T, Src, Dst> TypedTransform3D<T, Src, Dst> {
- /// Create a transform specifying its components in row-major order.
- ///
- /// For example, the translation terms m41, m42, m43 on the last row with the
- /// row-major convention) are the 13rd, 14th and 15th parameters.
- #[inline]
- pub fn row_major(
- m11: T, m12: T, m13: T, m14: T,
- m21: T, m22: T, m23: T, m24: T,
- m31: T, m32: T, m33: T, m34: T,
- m41: T, m42: T, m43: T, m44: T)
- -> Self {
- TypedTransform3D {
- m11: m11, m12: m12, m13: m13, m14: m14,
- m21: m21, m22: m22, m23: m23, m24: m24,
- m31: m31, m32: m32, m33: m33, m34: m34,
- m41: m41, m42: m42, m43: m43, m44: m44,
- _unit: PhantomData,
- }
- }
-
- /// Create a transform specifying its components in column-major order.
- ///
- /// For example, the translation terms m41, m42, m43 on the last column with the
- /// column-major convention) are the 4th, 8th and 12nd parameters.
- #[inline]
- pub fn column_major(
- m11: T, m21: T, m31: T, m41: T,
- m12: T, m22: T, m32: T, m42: T,
- m13: T, m23: T, m33: T, m43: T,
- m14: T, m24: T, m34: T, m44: T)
- -> Self {
- TypedTransform3D {
- m11: m11, m12: m12, m13: m13, m14: m14,
- m21: m21, m22: m22, m23: m23, m24: m24,
- m31: m31, m32: m32, m33: m33, m34: m34,
- m41: m41, m42: m42, m43: m43, m44: m44,
- _unit: PhantomData,
- }
- }
-}
-
-impl <T, Src, Dst> TypedTransform3D<T, Src, Dst>
-where T: Copy + Clone +
- PartialEq +
- One + Zero {
- #[inline]
- pub fn identity() -> Self {
- let (_0, _1): (T, T) = (Zero::zero(), One::one());
- TypedTransform3D::row_major(
- _1, _0, _0, _0,
- _0, _1, _0, _0,
- _0, _0, _1, _0,
- _0, _0, _0, _1
- )
- }
-
- // Intentional not public, because it checks for exact equivalence
- // while most consumers will probably want some sort of approximate
- // equivalence to deal with floating-point errors.
- #[inline]
- fn is_identity(&self) -> bool {
- *self == TypedTransform3D::identity()
- }
-}
-
-impl <T, Src, Dst> TypedTransform3D<T, Src, Dst>
-where T: Copy + Clone +
- Add<T, Output=T> +
- Sub<T, Output=T> +
- Mul<T, Output=T> +
- Div<T, Output=T> +
- Neg<Output=T> +
- ApproxEq<T> +
- PartialOrd +
- Trig +
- One + Zero {
-
- /// Create a 4 by 4 transform representing a 2d transformation, specifying its components
- /// in row-major order.
- #[inline]
- pub fn row_major_2d(m11: T, m12: T, m21: T, m22: T, m41: T, m42: T) -> Self {
- let (_0, _1): (T, T) = (Zero::zero(), One::one());
- TypedTransform3D::row_major(
- m11, m12, _0, _0,
- m21, m22, _0, _0,
- _0, _0, _1, _0,
- m41, m42, _0, _1
- )
- }
-
- /// Create an orthogonal projection transform.
- pub fn ortho(left: T, right: T,
- bottom: T, top: T,
- near: T, far: T) -> Self {
- let tx = -((right + left) / (right - left));
- let ty = -((top + bottom) / (top - bottom));
- let tz = -((far + near) / (far - near));
-
- let (_0, _1): (T, T) = (Zero::zero(), One::one());
- let _2 = _1 + _1;
- TypedTransform3D::row_major(
- _2 / (right - left), _0 , _0 , _0,
- _0 , _2 / (top - bottom), _0 , _0,
- _0 , _0 , -_2 / (far - near), _0,
- tx , ty , tz , _1
- )
- }
-
- /// Returns true if this transform can be represented with a TypedTransform2D.
- ///
- /// See https://drafts.csswg.org/css-transforms/#2d-transform
- #[inline]
- pub fn is_2d(&self) -> bool {
- let (_0, _1): (T, T) = (Zero::zero(), One::one());
- self.m31 == _0 && self.m32 == _0 &&
- self.m13 == _0 && self.m23 == _0 &&
- self.m43 == _0 && self.m14 == _0 &&
- self.m24 == _0 && self.m34 == _0 &&
- self.m33 == _1 && self.m44 == _1
- }
-
- /// Create a 2D transform picking the relevent terms from this transform.
- ///
- /// This method assumes that self represents a 2d transformation, callers
- /// should check that self.is_2d() returns true beforehand.
- pub fn to_2d(&self) -> TypedTransform2D<T, Src, Dst> {
- TypedTransform2D::row_major(
- self.m11, self.m12,
- self.m21, self.m22,
- self.m41, self.m42
- )
- }
-
- /// Check whether shapes on the XY plane with Z pointing towards the
- /// screen transformed by this matrix would be facing back.
- pub fn is_backface_visible(&self) -> bool {
- // inverse().m33 < 0;
- let det = self.determinant();
- let m33 = self.m12 * self.m24 * self.m41 - self.m14 * self.m22 * self.m41 +
- self.m14 * self.m21 * self.m42 - self.m11 * self.m24 * self.m42 -
- self.m12 * self.m21 * self.m44 + self.m11 * self.m22 * self.m44;
- let _0: T = Zero::zero();
- (m33 * det) < _0
- }
-
- pub fn approx_eq(&self, other: &Self) -> bool {
- self.m11.approx_eq(&other.m11) && self.m12.approx_eq(&other.m12) &&
- self.m13.approx_eq(&other.m13) && self.m14.approx_eq(&other.m14) &&
- self.m21.approx_eq(&other.m21) && self.m22.approx_eq(&other.m22) &&
- self.m23.approx_eq(&other.m23) && self.m24.approx_eq(&other.m24) &&
- self.m31.approx_eq(&other.m31) && self.m32.approx_eq(&other.m32) &&
- self.m33.approx_eq(&other.m33) && self.m34.approx_eq(&other.m34) &&
- self.m41.approx_eq(&other.m41) && self.m42.approx_eq(&other.m42) &&
- self.m43.approx_eq(&other.m43) && self.m44.approx_eq(&other.m44)
- }
-
- /// Returns the same transform with a different destination unit.
- #[inline]
- pub fn with_destination<NewDst>(&self) -> TypedTransform3D<T, Src, NewDst> {
- TypedTransform3D::row_major(
- self.m11, self.m12, self.m13, self.m14,
- self.m21, self.m22, self.m23, self.m24,
- self.m31, self.m32, self.m33, self.m34,
- self.m41, self.m42, self.m43, self.m44,
- )
- }
-
- /// Returns the same transform with a different source unit.
- #[inline]
- pub fn with_source<NewSrc>(&self) -> TypedTransform3D<T, NewSrc, Dst> {
- TypedTransform3D::row_major(
- self.m11, self.m12, self.m13, self.m14,
- self.m21, self.m22, self.m23, self.m24,
- self.m31, self.m32, self.m33, self.m34,
- self.m41, self.m42, self.m43, self.m44,
- )
- }
-
- /// Drop the units, preserving only the numeric value.
- #[inline]
- pub fn to_untyped(&self) -> Transform3D<T> {
- Transform3D::row_major(
- self.m11, self.m12, self.m13, self.m14,
- self.m21, self.m22, self.m23, self.m24,
- self.m31, self.m32, self.m33, self.m34,
- self.m41, self.m42, self.m43, self.m44,
- )
- }
-
- /// Tag a unitless value with units.
- #[inline]
- pub fn from_untyped(m: &Transform3D<T>) -> Self {
- TypedTransform3D::row_major(
- m.m11, m.m12, m.m13, m.m14,
- m.m21, m.m22, m.m23, m.m24,
- m.m31, m.m32, m.m33, m.m34,
- m.m41, m.m42, m.m43, m.m44,
- )
- }
-
- /// Returns the multiplication of the two matrices such that mat's transformation
- /// applies after self's transformation.
- pub fn post_mul<NewDst>(&self, mat: &TypedTransform3D<T, Dst, NewDst>) -> TypedTransform3D<T, Src, NewDst> {
- TypedTransform3D::row_major(
- self.m11 * mat.m11 + self.m12 * mat.m21 + self.m13 * mat.m31 + self.m14 * mat.m41,
- self.m11 * mat.m12 + self.m12 * mat.m22 + self.m13 * mat.m32 + self.m14 * mat.m42,
- self.m11 * mat.m13 + self.m12 * mat.m23 + self.m13 * mat.m33 + self.m14 * mat.m43,
- self.m11 * mat.m14 + self.m12 * mat.m24 + self.m13 * mat.m34 + self.m14 * mat.m44,
- self.m21 * mat.m11 + self.m22 * mat.m21 + self.m23 * mat.m31 + self.m24 * mat.m41,
- self.m21 * mat.m12 + self.m22 * mat.m22 + self.m23 * mat.m32 + self.m24 * mat.m42,
- self.m21 * mat.m13 + self.m22 * mat.m23 + self.m23 * mat.m33 + self.m24 * mat.m43,
- self.m21 * mat.m14 + self.m22 * mat.m24 + self.m23 * mat.m34 + self.m24 * mat.m44,
- self.m31 * mat.m11 + self.m32 * mat.m21 + self.m33 * mat.m31 + self.m34 * mat.m41,
- self.m31 * mat.m12 + self.m32 * mat.m22 + self.m33 * mat.m32 + self.m34 * mat.m42,
- self.m31 * mat.m13 + self.m32 * mat.m23 + self.m33 * mat.m33 + self.m34 * mat.m43,
- self.m31 * mat.m14 + self.m32 * mat.m24 + self.m33 * mat.m34 + self.m34 * mat.m44,
- self.m41 * mat.m11 + self.m42 * mat.m21 + self.m43 * mat.m31 + self.m44 * mat.m41,
- self.m41 * mat.m12 + self.m42 * mat.m22 + self.m43 * mat.m32 + self.m44 * mat.m42,
- self.m41 * mat.m13 + self.m42 * mat.m23 + self.m43 * mat.m33 + self.m44 * mat.m43,
- self.m41 * mat.m14 + self.m42 * mat.m24 + self.m43 * mat.m34 + self.m44 * mat.m44,
- )
- }
-
- /// Returns the multiplication of the two matrices such that mat's transformation
- /// applies before self's transformation.
- pub fn pre_mul<NewSrc>(&self, mat: &TypedTransform3D<T, NewSrc, Src>) -> TypedTransform3D<T, NewSrc, Dst> {
- mat.post_mul(self)
- }
-
- /// Returns the inverse transform if possible.
- pub fn inverse(&self) -> Option<TypedTransform3D<T, Dst, Src>> {
- let det = self.determinant();
-
- if det == Zero::zero() {
- return None;
- }
-
- // todo(gw): this could be made faster by special casing
- // for simpler transform types.
- let m = TypedTransform3D::row_major(
- self.m23*self.m34*self.m42 - self.m24*self.m33*self.m42 +
- self.m24*self.m32*self.m43 - self.m22*self.m34*self.m43 -
- self.m23*self.m32*self.m44 + self.m22*self.m33*self.m44,
-
- self.m14*self.m33*self.m42 - self.m13*self.m34*self.m42 -
- self.m14*self.m32*self.m43 + self.m12*self.m34*self.m43 +
- self.m13*self.m32*self.m44 - self.m12*self.m33*self.m44,
-
- self.m13*self.m24*self.m42 - self.m14*self.m23*self.m42 +
- self.m14*self.m22*self.m43 - self.m12*self.m24*self.m43 -
- self.m13*self.m22*self.m44 + self.m12*self.m23*self.m44,
-
- self.m14*self.m23*self.m32 - self.m13*self.m24*self.m32 -
- self.m14*self.m22*self.m33 + self.m12*self.m24*self.m33 +
- self.m13*self.m22*self.m34 - self.m12*self.m23*self.m34,
-
- self.m24*self.m33*self.m41 - self.m23*self.m34*self.m41 -
- self.m24*self.m31*self.m43 + self.m21*self.m34*self.m43 +
- self.m23*self.m31*self.m44 - self.m21*self.m33*self.m44,
-
- self.m13*self.m34*self.m41 - self.m14*self.m33*self.m41 +
- self.m14*self.m31*self.m43 - self.m11*self.m34*self.m43 -
- self.m13*self.m31*self.m44 + self.m11*self.m33*self.m44,
-
- self.m14*self.m23*self.m41 - self.m13*self.m24*self.m41 -
- self.m14*self.m21*self.m43 + self.m11*self.m24*self.m43 +
- self.m13*self.m21*self.m44 - self.m11*self.m23*self.m44,
-
- self.m13*self.m24*self.m31 - self.m14*self.m23*self.m31 +
- self.m14*self.m21*self.m33 - self.m11*self.m24*self.m33 -
- self.m13*self.m21*self.m34 + self.m11*self.m23*self.m34,
-
- self.m22*self.m34*self.m41 - self.m24*self.m32*self.m41 +
- self.m24*self.m31*self.m42 - self.m21*self.m34*self.m42 -
- self.m22*self.m31*self.m44 + self.m21*self.m32*self.m44,
-
- self.m14*self.m32*self.m41 - self.m12*self.m34*self.m41 -
- self.m14*self.m31*self.m42 + self.m11*self.m34*self.m42 +
- self.m12*self.m31*self.m44 - self.m11*self.m32*self.m44,
-
- self.m12*self.m24*self.m41 - self.m14*self.m22*self.m41 +
- self.m14*self.m21*self.m42 - self.m11*self.m24*self.m42 -
- self.m12*self.m21*self.m44 + self.m11*self.m22*self.m44,
-
- self.m14*self.m22*self.m31 - self.m12*self.m24*self.m31 -
- self.m14*self.m21*self.m32 + self.m11*self.m24*self.m32 +
- self.m12*self.m21*self.m34 - self.m11*self.m22*self.m34,
-
- self.m23*self.m32*self.m41 - self.m22*self.m33*self.m41 -
- self.m23*self.m31*self.m42 + self.m21*self.m33*self.m42 +
- self.m22*self.m31*self.m43 - self.m21*self.m32*self.m43,
-
- self.m12*self.m33*self.m41 - self.m13*self.m32*self.m41 +
- self.m13*self.m31*self.m42 - self.m11*self.m33*self.m42 -
- self.m12*self.m31*self.m43 + self.m11*self.m32*self.m43,
-
- self.m13*self.m22*self.m41 - self.m12*self.m23*self.m41 -
- self.m13*self.m21*self.m42 + self.m11*self.m23*self.m42 +
- self.m12*self.m21*self.m43 - self.m11*self.m22*self.m43,
-
- self.m12*self.m23*self.m31 - self.m13*self.m22*self.m31 +
- self.m13*self.m21*self.m32 - self.m11*self.m23*self.m32 -
- self.m12*self.m21*self.m33 + self.m11*self.m22*self.m33
- );
-
- let _1: T = One::one();
- Some(m.mul_s(_1 / det))
- }
-
- /// Compute the determinant of the transform.
- pub fn determinant(&self) -> T {
- self.m14 * self.m23 * self.m32 * self.m41 -
- self.m13 * self.m24 * self.m32 * self.m41 -
- self.m14 * self.m22 * self.m33 * self.m41 +
- self.m12 * self.m24 * self.m33 * self.m41 +
- self.m13 * self.m22 * self.m34 * self.m41 -
- self.m12 * self.m23 * self.m34 * self.m41 -
- self.m14 * self.m23 * self.m31 * self.m42 +
- self.m13 * self.m24 * self.m31 * self.m42 +
- self.m14 * self.m21 * self.m33 * self.m42 -
- self.m11 * self.m24 * self.m33 * self.m42 -
- self.m13 * self.m21 * self.m34 * self.m42 +
- self.m11 * self.m23 * self.m34 * self.m42 +
- self.m14 * self.m22 * self.m31 * self.m43 -
- self.m12 * self.m24 * self.m31 * self.m43 -
- self.m14 * self.m21 * self.m32 * self.m43 +
- self.m11 * self.m24 * self.m32 * self.m43 +
- self.m12 * self.m21 * self.m34 * self.m43 -
- self.m11 * self.m22 * self.m34 * self.m43 -
- self.m13 * self.m22 * self.m31 * self.m44 +
- self.m12 * self.m23 * self.m31 * self.m44 +
- self.m13 * self.m21 * self.m32 * self.m44 -
- self.m11 * self.m23 * self.m32 * self.m44 -
- self.m12 * self.m21 * self.m33 * self.m44 +
- self.m11 * self.m22 * self.m33 * self.m44
- }
-
- /// Multiplies all of the transform's component by a scalar and returns the result.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn mul_s(&self, x: T) -> Self {
- TypedTransform3D::row_major(
- self.m11 * x, self.m12 * x, self.m13 * x, self.m14 * x,
- self.m21 * x, self.m22 * x, self.m23 * x, self.m24 * x,
- self.m31 * x, self.m32 * x, self.m33 * x, self.m34 * x,
- self.m41 * x, self.m42 * x, self.m43 * x, self.m44 * x
- )
- }
-
- /// Convenience function to create a scale transform from a ScaleFactor.
- pub fn from_scale_factor(scale: ScaleFactor<T, Src, Dst>) -> Self {
- TypedTransform3D::create_scale(scale.get(), scale.get(), scale.get())
- }
-
- /// Returns the given 2d point transformed by this transform.
- ///
- /// The input point must be use the unit Src, and the returned point has the unit Dst.
- #[inline]
- pub fn transform_point2d(&self, p: &TypedPoint2D<T, Src>) -> TypedPoint2D<T, Dst> {
- let x = p.x * self.m11 + p.y * self.m21 + self.m41;
- let y = p.x * self.m12 + p.y * self.m22 + self.m42;
-
- let w = p.x * self.m14 + p.y * self.m24 + self.m44;
-
- point2(x/w, y/w)
- }
-
- /// Returns the given 2d vector transformed by this matrix.
- ///
- /// The input point must be use the unit Src, and the returned point has the unit Dst.
- #[inline]
- pub fn transform_vector2d(&self, v: &TypedVector2D<T, Src>) -> TypedVector2D<T, Dst> {
- vec2(
- v.x * self.m11 + v.y * self.m21,
- v.x * self.m12 + v.y * self.m22,
- )
- }
-
- /// Returns the given 3d point transformed by this transform.
- ///
- /// The input point must be use the unit Src, and the returned point has the unit Dst.
- #[inline]
- pub fn transform_point3d(&self, p: &TypedPoint3D<T, Src>) -> TypedPoint3D<T, Dst> {
- let x = p.x * self.m11 + p.y * self.m21 + p.z * self.m31 + self.m41;
- let y = p.x * self.m12 + p.y * self.m22 + p.z * self.m32 + self.m42;
- let z = p.x * self.m13 + p.y * self.m23 + p.z * self.m33 + self.m43;
- let w = p.x * self.m14 + p.y * self.m24 + p.z * self.m34 + self.m44;
-
- point3(x/w, y/w, z/w)
- }
-
- /// Returns the given 3d vector transformed by this matrix.
- ///
- /// The input point must be use the unit Src, and the returned point has the unit Dst.
- #[inline]
- pub fn transform_vector3d(&self, v: &TypedVector3D<T, Src>) -> TypedVector3D<T, Dst> {
- vec3(
- v.x * self.m11 + v.y * self.m21 + v.z * self.m31,
- v.x * self.m12 + v.y * self.m22 + v.z * self.m32,
- v.x * self.m13 + v.y * self.m23 + v.z * self.m33,
- )
- }
-
- /// Returns a rectangle that encompasses the result of transforming the given rectangle by this
- /// transform.
- pub fn transform_rect(&self, rect: &TypedRect<T, Src>) -> TypedRect<T, Dst> {
- TypedRect::from_points(&[
- self.transform_point2d(&rect.origin),
- self.transform_point2d(&rect.top_right()),
- self.transform_point2d(&rect.bottom_left()),
- self.transform_point2d(&rect.bottom_right()),
- ])
- }
-
- /// Create a 3d translation transform
- pub fn create_translation(x: T, y: T, z: T) -> Self {
- let (_0, _1): (T, T) = (Zero::zero(), One::one());
- TypedTransform3D::row_major(
- _1, _0, _0, _0,
- _0, _1, _0, _0,
- _0, _0, _1, _0,
- x, y, z, _1
- )
- }
-
- /// Returns a transform with a translation applied before self's transformation.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn pre_translate(&self, v: TypedVector3D<T, Src>) -> Self {
- self.pre_mul(&TypedTransform3D::create_translation(v.x, v.y, v.z))
- }
-
- /// Returns a transform with a translation applied after self's transformation.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn post_translate(&self, v: TypedVector3D<T, Dst>) -> Self {
- self.post_mul(&TypedTransform3D::create_translation(v.x, v.y, v.z))
- }
-
- /// Create a 3d scale transform
- pub fn create_scale(x: T, y: T, z: T) -> Self {
- let (_0, _1): (T, T) = (Zero::zero(), One::one());
- TypedTransform3D::row_major(
- x, _0, _0, _0,
- _0, y, _0, _0,
- _0, _0, z, _0,
- _0, _0, _0, _1
- )
- }
-
- /// Returns a transform with a scale applied before self's transformation.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn pre_scale(&self, x: T, y: T, z: T) -> Self {
- TypedTransform3D::row_major(
- self.m11 * x, self.m12, self.m13, self.m14,
- self.m21 , self.m22 * y, self.m23, self.m24,
- self.m31 , self.m32, self.m33 * z, self.m34,
- self.m41 , self.m42, self.m43, self.m44
- )
- }
-
- /// Returns a transform with a scale applied after self's transformation.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn post_scale(&self, x: T, y: T, z: T) -> Self {
- self.post_mul(&TypedTransform3D::create_scale(x, y, z))
- }
-
- /// Create a 3d rotation transform from an angle / axis.
- /// The supplied axis must be normalized.
- pub fn create_rotation(x: T, y: T, z: T, theta: Radians<T>) -> Self {
- let (_0, _1): (T, T) = (Zero::zero(), One::one());
- let _2 = _1 + _1;
-
- let xx = x * x;
- let yy = y * y;
- let zz = z * z;
-
- let half_theta = theta.get() / _2;
- let sc = half_theta.sin() * half_theta.cos();
- let sq = half_theta.sin() * half_theta.sin();
-
- TypedTransform3D::row_major(
- _1 - _2 * (yy + zz) * sq,
- _2 * (x * y * sq - z * sc),
- _2 * (x * z * sq + y * sc),
- _0,
-
- _2 * (x * y * sq + z * sc),
- _1 - _2 * (xx + zz) * sq,
- _2 * (y * z * sq - x * sc),
- _0,
-
- _2 * (x * z * sq - y * sc),
- _2 * (y * z * sq + x * sc),
- _1 - _2 * (xx + yy) * sq,
- _0,
-
- _0,
- _0,
- _0,
- _1
- )
- }
-
- /// Returns a transform with a rotation applied after self's transformation.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn post_rotate(&self, x: T, y: T, z: T, theta: Radians<T>) -> Self {
- self.post_mul(&TypedTransform3D::create_rotation(x, y, z, theta))
- }
-
- /// Returns a transform with a rotation applied before self's transformation.
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn pre_rotate(&self, x: T, y: T, z: T, theta: Radians<T>) -> Self {
- self.pre_mul(&TypedTransform3D::create_rotation(x, y, z, theta))
- }
-
- /// Create a 2d skew transform.
- ///
- /// See https://drafts.csswg.org/css-transforms/#funcdef-skew
- pub fn create_skew(alpha: Radians<T>, beta: Radians<T>) -> Self {
- let (_0, _1): (T, T) = (Zero::zero(), One::one());
- let (sx, sy) = (beta.get().tan(), alpha.get().tan());
- TypedTransform3D::row_major(
- _1, sx, _0, _0,
- sy, _1, _0, _0,
- _0, _0, _1, _0,
- _0, _0, _0, _1
- )
- }
-
- /// Create a simple perspective projection transform
- pub fn create_perspective(d: T) -> Self {
- let (_0, _1): (T, T) = (Zero::zero(), One::one());
- TypedTransform3D::row_major(
- _1, _0, _0, _0,
- _0, _1, _0, _0,
- _0, _0, _1, -_1 / d,
- _0, _0, _0, _1
- )
- }
-}
-
-impl<T: Copy, Src, Dst> TypedTransform3D<T, Src, Dst> {
- /// Returns an array containing this transform's terms in row-major order (the order
- /// in which the transform is actually laid out in memory).
- pub fn to_row_major_array(&self) -> [T; 16] {
- [
- self.m11, self.m12, self.m13, self.m14,
- self.m21, self.m22, self.m23, self.m24,
- self.m31, self.m32, self.m33, self.m34,
- self.m41, self.m42, self.m43, self.m44
- ]
- }
-
- /// Returns an array containing this transform's terms in column-major order.
- pub fn to_column_major_array(&self) -> [T; 16] {
- [
- self.m11, self.m21, self.m31, self.m41,
- self.m12, self.m22, self.m32, self.m42,
- self.m13, self.m23, self.m33, self.m43,
- self.m14, self.m24, self.m34, self.m44
- ]
- }
-
- /// Returns an array containing this transform's 4 rows in (in row-major order)
- /// as arrays.
- ///
- /// This is a convenience method to interface with other libraries like glium.
- pub fn to_row_arrays(&self) -> [[T; 4]; 4] {
- [
- [self.m11, self.m12, self.m13, self.m14],
- [self.m21, self.m22, self.m23, self.m24],
- [self.m31, self.m32, self.m33, self.m34],
- [self.m41, self.m42, self.m43, self.m44]
- ]
- }
-
- /// Returns an array containing this transform's 4 columns in (in row-major order,
- /// or 4 rows in column-major order) as arrays.
- ///
- /// This is a convenience method to interface with other libraries like glium.
- pub fn to_column_arrays(&self) -> [[T; 4]; 4] {
- [
- [self.m11, self.m21, self.m31, self.m41],
- [self.m12, self.m22, self.m32, self.m42],
- [self.m13, self.m23, self.m33, self.m43],
- [self.m14, self.m24, self.m34, self.m44]
- ]
- }
-
- /// Creates a transform from an array of 16 elements in row-major order.
- pub fn from_array(array: [T; 16]) -> Self {
- Self::row_major(
- array[0], array[1], array[2], array[3],
- array[4], array[5], array[6], array[7],
- array[8], array[9], array[10], array[11],
- array[12], array[13], array[14], array[15],
- )
- }
-
- /// Creates a transform from 4 rows of 4 elements (row-major order).
- pub fn from_row_arrays(array: [[T; 4]; 4]) -> Self {
- Self::row_major(
- array[0][0], array[0][1], array[0][2], array[0][3],
- array[1][0], array[1][1], array[1][2], array[1][3],
- array[2][0], array[2][1], array[2][2], array[2][3],
- array[3][0], array[3][1], array[3][2], array[3][3],
- )
- }
-}
-
-impl<T0: NumCast + Copy, Src, Dst> TypedTransform3D<T0, Src, Dst> {
- /// Cast from one numeric representation to another, preserving the units.
- pub fn cast<T1: NumCast + Copy>(&self) -> Option<TypedTransform3D<T1, Src, Dst>> {
- match (NumCast::from(self.m11), NumCast::from(self.m12),
- NumCast::from(self.m13), NumCast::from(self.m14),
- NumCast::from(self.m21), NumCast::from(self.m22),
- NumCast::from(self.m23), NumCast::from(self.m24),
- NumCast::from(self.m31), NumCast::from(self.m32),
- NumCast::from(self.m33), NumCast::from(self.m34),
- NumCast::from(self.m41), NumCast::from(self.m42),
- NumCast::from(self.m43), NumCast::from(self.m44)) {
- (Some(m11), Some(m12), Some(m13), Some(m14),
- Some(m21), Some(m22), Some(m23), Some(m24),
- Some(m31), Some(m32), Some(m33), Some(m34),
- Some(m41), Some(m42), Some(m43), Some(m44)) => {
- Some(TypedTransform3D::row_major(m11, m12, m13, m14,
- m21, m22, m23, m24,
- m31, m32, m33, m34,
- m41, m42, m43, m44))
- },
- _ => None
- }
- }
-}
-
-impl<T, Src, Dst> fmt::Debug for TypedTransform3D<T, Src, Dst>
-where T: Copy + fmt::Debug +
- PartialEq +
- One + Zero {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- if self.is_identity() {
- write!(f, "[I]")
- } else {
- self.to_row_major_array().fmt(f)
- }
- }
-}
-
-#[cfg(test)]
-mod tests {
- use approxeq::ApproxEq;
- use transform2d::Transform2D;
- use point::{Point2D, Point3D};
- use Radians;
- use super::*;
-
- use std::f32::consts::{FRAC_PI_2, PI};
-
- type Mf32 = Transform3D<f32>;
-
- // For convenience.
- fn rad(v: f32) -> Radians<f32> { Radians::new(v) }
-
- #[test]
- pub fn test_translation() {
- let t1 = Mf32::create_translation(1.0, 2.0, 3.0);
- let t2 = Mf32::identity().pre_translate(vec3(1.0, 2.0, 3.0));
- let t3 = Mf32::identity().post_translate(vec3(1.0, 2.0, 3.0));
- assert_eq!(t1, t2);
- assert_eq!(t1, t3);
-
- assert_eq!(t1.transform_point3d(&Point3D::new(1.0, 1.0, 1.0)), Point3D::new(2.0, 3.0, 4.0));
- assert_eq!(t1.transform_point2d(&Point2D::new(1.0, 1.0)), Point2D::new(2.0, 3.0));
-
- assert_eq!(t1.post_mul(&t1), Mf32::create_translation(2.0, 4.0, 6.0));
-
- assert!(!t1.is_2d());
- assert_eq!(Mf32::create_translation(1.0, 2.0, 3.0).to_2d(), Transform2D::create_translation(1.0, 2.0));
- }
-
- #[test]
- pub fn test_rotation() {
- let r1 = Mf32::create_rotation(0.0, 0.0, 1.0, rad(FRAC_PI_2));
- let r2 = Mf32::identity().pre_rotate(0.0, 0.0, 1.0, rad(FRAC_PI_2));
- let r3 = Mf32::identity().post_rotate(0.0, 0.0, 1.0, rad(FRAC_PI_2));
- assert_eq!(r1, r2);
- assert_eq!(r1, r3);
-
- assert!(r1.transform_point3d(&Point3D::new(1.0, 2.0, 3.0)).approx_eq(&Point3D::new(2.0, -1.0, 3.0)));
- assert!(r1.transform_point2d(&Point2D::new(1.0, 2.0)).approx_eq(&Point2D::new(2.0, -1.0)));
-
- assert!(r1.post_mul(&r1).approx_eq(&Mf32::create_rotation(0.0, 0.0, 1.0, rad(FRAC_PI_2*2.0))));
-
- assert!(r1.is_2d());
- assert!(r1.to_2d().approx_eq(&Transform2D::create_rotation(rad(FRAC_PI_2))));
- }
-
- #[test]
- pub fn test_scale() {
- let s1 = Mf32::create_scale(2.0, 3.0, 4.0);
- let s2 = Mf32::identity().pre_scale(2.0, 3.0, 4.0);
- let s3 = Mf32::identity().post_scale(2.0, 3.0, 4.0);
- assert_eq!(s1, s2);
- assert_eq!(s1, s3);
-
- assert!(s1.transform_point3d(&Point3D::new(2.0, 2.0, 2.0)).approx_eq(&Point3D::new(4.0, 6.0, 8.0)));
- assert!(s1.transform_point2d(&Point2D::new(2.0, 2.0)).approx_eq(&Point2D::new(4.0, 6.0)));
-
- assert_eq!(s1.post_mul(&s1), Mf32::create_scale(4.0, 9.0, 16.0));
-
- assert!(!s1.is_2d());
- assert_eq!(Mf32::create_scale(2.0, 3.0, 0.0).to_2d(), Transform2D::create_scale(2.0, 3.0));
- }
-
- #[test]
- pub fn test_ortho() {
- let (left, right, bottom, top) = (0.0f32, 1.0f32, 0.1f32, 1.0f32);
- let (near, far) = (-1.0f32, 1.0f32);
- let result = Mf32::ortho(left, right, bottom, top, near, far);
- let expected = Mf32::row_major(
- 2.0, 0.0, 0.0, 0.0,
- 0.0, 2.22222222, 0.0, 0.0,
- 0.0, 0.0, -1.0, 0.0,
- -1.0, -1.22222222, -0.0, 1.0
- );
- debug!("result={:?} expected={:?}", result, expected);
- assert!(result.approx_eq(&expected));
- }
-
- #[test]
- pub fn test_is_2d() {
- assert!(Mf32::identity().is_2d());
- assert!(Mf32::create_rotation(0.0, 0.0, 1.0, rad(0.7854)).is_2d());
- assert!(!Mf32::create_rotation(0.0, 1.0, 0.0, rad(0.7854)).is_2d());
- }
-
- #[test]
- pub fn test_row_major_2d() {
- let m1 = Mf32::row_major_2d(1.0, 2.0, 3.0, 4.0, 5.0, 6.0);
- let m2 = Mf32::row_major(
- 1.0, 2.0, 0.0, 0.0,
- 3.0, 4.0, 0.0, 0.0,
- 0.0, 0.0, 1.0, 0.0,
- 5.0, 6.0, 0.0, 1.0
- );
- assert_eq!(m1, m2);
- }
-
- #[test]
- fn test_column_major() {
- assert_eq!(
- Mf32::row_major(
- 1.0, 2.0, 3.0, 4.0,
- 5.0, 6.0, 7.0, 8.0,
- 9.0, 10.0, 11.0, 12.0,
- 13.0, 14.0, 15.0, 16.0,
- ),
- Mf32::column_major(
- 1.0, 5.0, 9.0, 13.0,
- 2.0, 6.0, 10.0, 14.0,
- 3.0, 7.0, 11.0, 15.0,
- 4.0, 8.0, 12.0, 16.0,
- )
- );
- }
-
- #[test]
- pub fn test_inverse_simple() {
- let m1 = Mf32::identity();
- let m2 = m1.inverse().unwrap();
- assert!(m1.approx_eq(&m2));
- }
-
- #[test]
- pub fn test_inverse_scale() {
- let m1 = Mf32::create_scale(1.5, 0.3, 2.1);
- let m2 = m1.inverse().unwrap();
- assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
- }
-
- #[test]
- pub fn test_inverse_translate() {
- let m1 = Mf32::create_translation(-132.0, 0.3, 493.0);
- let m2 = m1.inverse().unwrap();
- assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
- }
-
- #[test]
- pub fn test_inverse_rotate() {
- let m1 = Mf32::create_rotation(0.0, 1.0, 0.0, rad(1.57));
- let m2 = m1.inverse().unwrap();
- assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
- }
-
- #[test]
- pub fn test_inverse_transform_point_2d() {
- let m1 = Mf32::create_translation(100.0, 200.0, 0.0);
- let m2 = m1.inverse().unwrap();
- assert!(m1.pre_mul(&m2).approx_eq(&Mf32::identity()));
-
- let p1 = Point2D::new(1000.0, 2000.0);
- let p2 = m1.transform_point2d(&p1);
- assert!(p2.eq(&Point2D::new(1100.0, 2200.0)));
-
- let p3 = m2.transform_point2d(&p2);
- assert!(p3.eq(&p1));
- }
-
- #[test]
- fn test_inverse_none() {
- assert!(Mf32::create_scale(2.0, 0.0, 2.0).inverse().is_none());
- assert!(Mf32::create_scale(2.0, 2.0, 2.0).inverse().is_some());
- }
-
- #[test]
- pub fn test_pre_post() {
- let m1 = Transform3D::identity().post_scale(1.0, 2.0, 3.0).post_translate(vec3(1.0, 2.0, 3.0));
- let m2 = Transform3D::identity().pre_translate(vec3(1.0, 2.0, 3.0)).pre_scale(1.0, 2.0, 3.0);
- assert!(m1.approx_eq(&m2));
-
- let r = Mf32::create_rotation(0.0, 0.0, 1.0, rad(FRAC_PI_2));
- let t = Mf32::create_translation(2.0, 3.0, 0.0);
-
- let a = Point3D::new(1.0, 1.0, 1.0);
-
- assert!(r.post_mul(&t).transform_point3d(&a).approx_eq(&Point3D::new(3.0, 2.0, 1.0)));
- assert!(t.post_mul(&r).transform_point3d(&a).approx_eq(&Point3D::new(4.0, -3.0, 1.0)));
- assert!(t.post_mul(&r).transform_point3d(&a).approx_eq(&r.transform_point3d(&t.transform_point3d(&a))));
-
- assert!(r.pre_mul(&t).transform_point3d(&a).approx_eq(&Point3D::new(4.0, -3.0, 1.0)));
- assert!(t.pre_mul(&r).transform_point3d(&a).approx_eq(&Point3D::new(3.0, 2.0, 1.0)));
- assert!(t.pre_mul(&r).transform_point3d(&a).approx_eq(&t.transform_point3d(&r.transform_point3d(&a))));
- }
-
- #[test]
- fn test_size_of() {
- use std::mem::size_of;
- assert_eq!(size_of::<Transform3D<f32>>(), 16*size_of::<f32>());
- assert_eq!(size_of::<Transform3D<f64>>(), 16*size_of::<f64>());
- }
-
- #[test]
- pub fn test_transform_associativity() {
- let m1 = Mf32::row_major(3.0, 2.0, 1.5, 1.0,
- 0.0, 4.5, -1.0, -4.0,
- 0.0, 3.5, 2.5, 40.0,
- 0.0, 3.0, 0.0, 1.0);
- let m2 = Mf32::row_major(1.0, -1.0, 3.0, 0.0,
- -1.0, 0.5, 0.0, 2.0,
- 1.5, -2.0, 6.0, 0.0,
- -2.5, 6.0, 1.0, 1.0);
-
- let p = Point3D::new(1.0, 3.0, 5.0);
- let p1 = m2.pre_mul(&m1).transform_point3d(&p);
- let p2 = m2.transform_point3d(&m1.transform_point3d(&p));
- assert!(p1.approx_eq(&p2));
- }
-
- #[test]
- pub fn test_is_identity() {
- let m1 = Transform3D::identity();
- assert!(m1.is_identity());
- let m2 = m1.post_translate(vec3(0.1, 0.0, 0.0));
- assert!(!m2.is_identity());
- }
-
- #[test]
- pub fn test_transform_vector() {
- // Translation does not apply to vectors.
- let m = Mf32::create_translation(1.0, 2.0, 3.0);
- let v1 = vec3(10.0, -10.0, 3.0);
- assert_eq!(v1, m.transform_vector3d(&v1));
- // While it does apply to points.
- assert!(v1.to_point() != m.transform_point3d(&v1.to_point()));
-
- // same thing with 2d vectors/points
- let v2 = vec2(10.0, -5.0);
- assert_eq!(v2, m.transform_vector2d(&v2));
- assert!(v2.to_point() != m.transform_point2d(&v2.to_point()));
- }
-
- #[test]
- pub fn test_is_backface_visible() {
- // backface is not visible for rotate-x 0 degree.
- let r1 = Mf32::create_rotation(1.0, 0.0, 0.0, rad(0.0));
- assert!(!r1.is_backface_visible());
- // backface is not visible for rotate-x 45 degree.
- let r1 = Mf32::create_rotation(1.0, 0.0, 0.0, rad(PI * 0.25));
- assert!(!r1.is_backface_visible());
- // backface is visible for rotate-x 180 degree.
- let r1 = Mf32::create_rotation(1.0, 0.0, 0.0, rad(PI));
- assert!(r1.is_backface_visible());
- // backface is visible for rotate-x 225 degree.
- let r1 = Mf32::create_rotation(1.0, 0.0, 0.0, rad(PI * 1.25));
- assert!(r1.is_backface_visible());
- // backface is not visible for non-inverseable matrix
- let r1 = Mf32::create_scale(2.0, 0.0, 2.0);
- assert!(!r1.is_backface_visible());
- }
-}
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/trig.rs
+++ /dev/null
@@ -1,32 +0,0 @@
-// Copyright 2013 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.
-
-
-/// Trait for basic trigonometry functions, so they can be used on generic numeric types
-pub trait Trig {
- fn sin(self) -> Self;
- fn cos(self) -> Self;
- fn tan(self) -> Self;
-}
-
-macro_rules! trig {
- ($ty:ty) => (
- impl Trig for $ty {
- #[inline]
- fn sin(self) -> $ty { self.sin() }
- #[inline]
- fn cos(self) -> $ty { self.cos() }
- #[inline]
- fn tan(self) -> $ty { self.tan() }
- }
- )
-}
-
-trig!(f32);
-trig!(f64);
deleted file mode 100644
--- a/third_party/rust/euclid-0.15.5/src/vector.rs
+++ /dev/null
@@ -1,949 +0,0 @@
-// Copyright 2013 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.
-
-use super::UnknownUnit;
-use approxeq::ApproxEq;
-use length::Length;
-use point::{TypedPoint2D, TypedPoint3D, point2, point3};
-use size::{TypedSize2D, size2};
-use scale_factor::ScaleFactor;
-use num::*;
-use num_traits::{Float, NumCast, Signed};
-use std::fmt;
-use std::ops::{Add, Neg, Mul, Sub, Div, AddAssign, SubAssign, MulAssign, DivAssign};
-use std::marker::PhantomData;
-
-define_matrix! {
- /// A 2d Vector tagged with a unit.
- pub struct TypedVector2D<T, U> {
- pub x: T,
- pub y: T,
- }
-}
-
-/// Default 2d vector type with no unit.
-///
-/// `Vector2D` provides the same methods as `TypedVector2D`.
-pub type Vector2D<T> = TypedVector2D<T, UnknownUnit>;
-
-impl<T: Copy + Zero, U> TypedVector2D<T, U> {
- /// Constructor, setting all components to zero.
- #[inline]
- pub fn zero() -> Self {
- TypedVector2D::new(Zero::zero(), Zero::zero())
- }
-
- /// Convert into a 3d vector.
- #[inline]
- pub fn to_3d(&self) -> TypedVector3D<T, U> {
- vec3(self.x, self.y, Zero::zero())
- }
-}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedVector2D<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "({:?},{:?})", self.x, self.y)
- }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedVector2D<T, U> {
- fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- write!(formatter, "({},{})", self.x, self.y)
- }
-}
-
-impl<T, U> TypedVector2D<T, U> {
- /// Constructor taking scalar values directly.
- #[inline]
- pub fn new(x: T, y: T) -> Self {
- TypedVector2D { x: x, y: y, _unit: PhantomData }
- }
-}
-
-impl<T: Copy, U> TypedVector2D<T, U> {
- /// Constructor taking properly typed Lengths instead of scalar values.
- #[inline]
- pub fn from_lengths(x: Length<T, U>, y: Length<T, U>) -> Self {
- vec2(x.0, y.0)
- }
-
- /// Create a 3d vector from this one, using the specified z value.
- #[inline]
- pub fn extend(&self, z: T) -> TypedVector3D<T, U> {
- vec3(self.x, self.y, z)
- }
-
- /// Cast this vector into a point.
- ///
- /// Equivalent to adding this vector to the origin.
- #[inline]
- pub fn to_point(&self) -> TypedPoint2D<T, U> {
- point2(self.x, self.y)
- }
-
- /// Swap x and y.
- #[inline]
- pub fn yx(&self) -> Self {
- vec2(self.y, self.x)
- }
-
- /// Cast this vector into a size.
- #[inline]
- pub fn to_size(&self) -> TypedSize2D<T, U> {
- size2(self.x, self.y)
- }
-
-
- /// Returns self.x as a Length carrying the unit.
- #[inline]
- pub fn x_typed(&self) -> Length<T, U> { Length::new(self.x) }
-
- /// Returns self.y as a Length carrying the unit.
- #[inline]
- pub fn y_typed(&self) -> Length<T, U> { Length::new(self.y) }
-
- /// Drop the units, preserving only the numeric value.
- #[inline]
- pub fn to_untyped(&self) -> Vector2D<T> {
- vec2(self.x, self.y)
- }
-
- /// Tag a unitless value with units.
- #[inline]
- pub fn from_untyped(p: &Vector2D<T>) -> Self {
- vec2(p.x, p.y)
- }
-
- #[inline]
- pub fn to_array(&self) -> [T; 2] {
- [self.x, self.y]
- }
-}
-
-impl<T, U> TypedVector2D<T, U>
-where T: Copy + Mul<T, Output=T> + Add<T, Output=T> + Sub<T, Output=T> {
- /// Dot product.
- #[inline]
- pub fn dot(self, other: Self) -> T {
- self.x * other.x + self.y * other.y
- }
-
- /// Returns the norm of the cross product [self.x, self.y, 0] x [other.x, other.y, 0]..
- #[inline]
- pub fn cross(self, other: Self) -> T {
- self.x * other.y - self.y * other.x
- }
-
- #[inline]
- pub fn normalize(self) -> Self where T: Float + ApproxEq<T> {
- let dot = self.dot(self);
- if dot.approx_eq(&T::zero()) {
- self
- } else {
- self / dot.sqrt()
- }
- }
-
- #[inline]
- pub fn square_length(&self) -> T {
- self.x * self.x + self.y * self.y
- }
-
- #[inline]
- pub fn length(&self) -> T where T: Float + ApproxEq<T> {
- self.square_length().sqrt()
- }
-}
-
-impl<T, U> TypedVector2D<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
- /// Linearly interpolate between this vector and another vector.
- ///
- /// `t` is expected to be between zero and one.
- #[inline]
- pub fn lerp(&self, other: Self, t: T) -> Self {
- let one_t = T::one() - t;
- (*self) * one_t + other * t
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add for TypedVector2D<T, U> {
- type Output = Self;
- fn add(self, other: Self) -> Self {
- TypedVector2D::new(self.x + other.x, self.y + other.y)
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> AddAssign for TypedVector2D<T, U> {
- #[inline]
- fn add_assign(&mut self, other: Self) {
- *self = *self + other
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> SubAssign<TypedVector2D<T, U>> for TypedVector2D<T, U> {
- #[inline]
- fn sub_assign(&mut self, other: Self) {
- *self = *self - other
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub for TypedVector2D<T, U> {
- type Output = Self;
- #[inline]
- fn sub(self, other: Self) -> Self {
- vec2(self.x - other.x, self.y - other.y)
- }
-}
-
-impl <T: Copy + Neg<Output=T>, U> Neg for TypedVector2D<T, U> {
- type Output = Self;
- #[inline]
- fn neg(self) -> Self {
- vec2(-self.x, -self.y)
- }
-}
-
-impl<T: Float, U> TypedVector2D<T, U> {
- #[inline]
- pub fn min(self, other: Self) -> Self {
- vec2(self.x.min(other.x), self.y.min(other.y))
- }
-
- #[inline]
- pub fn max(self, other: Self) -> Self {
- vec2(self.x.max(other.x), self.y.max(other.y))
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedVector2D<T, U> {
- type Output = Self;
- #[inline]
- fn mul(self, scale: T) -> Self {
- vec2(self.x * scale, self.y * scale)
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedVector2D<T, U> {
- type Output = Self;
- #[inline]
- fn div(self, scale: T) -> Self {
- vec2(self.x / scale, self.y / scale)
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> MulAssign<T> for TypedVector2D<T, U> {
- #[inline]
- fn mul_assign(&mut self, scale: T) {
- *self = *self * scale
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> DivAssign<T> for TypedVector2D<T, U> {
- #[inline]
- fn div_assign(&mut self, scale: T) {
- *self = *self / scale
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U1, U2> Mul<ScaleFactor<T, U1, U2>> for TypedVector2D<T, U1> {
- type Output = TypedVector2D<T, U2>;
- #[inline]
- fn mul(self, scale: ScaleFactor<T, U1, U2>) -> TypedVector2D<T, U2> {
- vec2(self.x * scale.get(), self.y * scale.get())
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U1, U2> Div<ScaleFactor<T, U1, U2>> for TypedVector2D<T, U2> {
- type Output = TypedVector2D<T, U1>;
- #[inline]
- fn div(self, scale: ScaleFactor<T, U1, U2>) -> TypedVector2D<T, U1> {
- vec2(self.x / scale.get(), self.y / scale.get())
- }
-}
-
-impl<T: Round, U> TypedVector2D<T, U> {
- /// Rounds each component to the nearest integer value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- /// For example `{ -0.1, -0.8 }.round() == { 0.0, -1.0 }`.
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn round(&self) -> Self {
- vec2(self.x.round(), self.y.round())
- }
-}
-
-impl<T: Ceil, U> TypedVector2D<T, U> {
- /// Rounds each component to the smallest integer equal or greater than the original value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- /// For example `{ -0.1, -0.8 }.ceil() == { 0.0, 0.0 }`.
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn ceil(&self) -> Self {
- vec2(self.x.ceil(), self.y.ceil())
- }
-}
-
-impl<T: Floor, U> TypedVector2D<T, U> {
- /// Rounds each component to the biggest integer equal or lower than the original value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- /// For example `{ -0.1, -0.8 }.floor() == { -1.0, -1.0 }`.
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn floor(&self) -> Self {
- vec2(self.x.floor(), self.y.floor())
- }
-}
-
-impl<T: NumCast + Copy, U> TypedVector2D<T, U> {
- /// Cast from one numeric representation to another, preserving the units.
- ///
- /// When casting from floating vector to integer coordinates, the decimals are truncated
- /// as one would expect from a simple cast, but this behavior does not always make sense
- /// geometrically. Consider using `round()`, `ceil()` or `floor()` before casting.
- #[inline]
- pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedVector2D<NewT, U>> {
- match (NumCast::from(self.x), NumCast::from(self.y)) {
- (Some(x), Some(y)) => Some(TypedVector2D::new(x, y)),
- _ => None
- }
- }
-
- // Convenience functions for common casts
-
- /// Cast into an `f32` vector.
- #[inline]
- pub fn to_f32(&self) -> TypedVector2D<f32, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an `usize` vector, truncating decimals if any.
- ///
- /// When casting from floating vector vectors, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_usize(&self) -> TypedVector2D<usize, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an i32 vector, truncating decimals if any.
- ///
- /// When casting from floating vector vectors, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_i32(&self) -> TypedVector2D<i32, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an i64 vector, truncating decimals if any.
- ///
- /// When casting from floating vector vectors, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_i64(&self) -> TypedVector2D<i64, U> {
- self.cast().unwrap()
- }
-}
-
-impl<T: Copy+ApproxEq<T>, U> ApproxEq<TypedVector2D<T, U>> for TypedVector2D<T, U> {
- #[inline]
- fn approx_epsilon() -> Self {
- vec2(T::approx_epsilon(), T::approx_epsilon())
- }
-
- #[inline]
- fn approx_eq(&self, other: &Self) -> bool {
- self.x.approx_eq(&other.x) && self.y.approx_eq(&other.y)
- }
-
- #[inline]
- fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
- self.x.approx_eq_eps(&other.x, &eps.x) && self.y.approx_eq_eps(&other.y, &eps.y)
- }
-}
-
-impl<T: Copy, U> Into<[T; 2]> for TypedVector2D<T, U> {
- fn into(self) -> [T; 2] {
- self.to_array()
- }
-}
-
-impl<T: Copy, U> From<[T; 2]> for TypedVector2D<T, U> {
- fn from(array: [T; 2]) -> Self {
- vec2(array[0], array[1])
- }
-}
-
-impl<T, U> TypedVector2D<T, U>
-where T: Signed {
- pub fn abs(&self) -> Self {
- vec2(self.x.abs(), self.y.abs())
- }
-}
-
-define_matrix! {
- /// A 3d Vector tagged with a unit.
- pub struct TypedVector3D<T, U> {
- pub x: T,
- pub y: T,
- pub z: T,
- }
-}
-
-/// Default 3d vector type with no unit.
-///
-/// `Vector3D` provides the same methods as `TypedVector3D`.
-pub type Vector3D<T> = TypedVector3D<T, UnknownUnit>;
-
-impl<T: Copy + Zero, U> TypedVector3D<T, U> {
- /// Constructor, setting all copmonents to zero.
- #[inline]
- pub fn zero() -> Self {
- vec3(Zero::zero(), Zero::zero(), Zero::zero())
- }
-
- #[inline]
- pub fn to_array_4d(&self) -> [T; 4] {
- [self.x, self.y, self.z, Zero::zero()]
- }
-}
-
-impl<T: fmt::Debug, U> fmt::Debug for TypedVector3D<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "({:?},{:?},{:?})", self.x, self.y, self.z)
- }
-}
-
-impl<T: fmt::Display, U> fmt::Display for TypedVector3D<T, U> {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "({},{},{})", self.x, self.y, self.z)
- }
-}
-
-impl<T, U> TypedVector3D<T, U> {
- /// Constructor taking scalar values directly.
- #[inline]
- pub fn new(x: T, y: T, z: T) -> Self {
- TypedVector3D { x: x, y: y, z: z, _unit: PhantomData }
- }
-}
-
-impl<T: Copy, U> TypedVector3D<T, U> {
- /// Constructor taking properly typed Lengths instead of scalar values.
- #[inline]
- pub fn from_lengths(x: Length<T, U>, y: Length<T, U>, z: Length<T, U>) -> TypedVector3D<T, U> {
- vec3(x.0, y.0, z.0)
- }
-
- /// Cast this vector into a point.
- ///
- /// Equivalent to adding this vector to the origin.
- #[inline]
- pub fn to_point(&self) -> TypedPoint3D<T, U> {
- point3(self.x, self.y, self.z)
- }
-
- /// Returns a 2d vector using this vector's x and y coordinates
- #[inline]
- pub fn xy(&self) -> TypedVector2D<T, U> {
- vec2(self.x, self.y)
- }
-
- /// Returns a 2d vector using this vector's x and z coordinates
- #[inline]
- pub fn xz(&self) -> TypedVector2D<T, U> {
- vec2(self.x, self.z)
- }
-
- /// Returns a 2d vector using this vector's x and z coordinates
- #[inline]
- pub fn yz(&self) -> TypedVector2D<T, U> {
- vec2(self.y, self.z)
- }
-
- /// Returns self.x as a Length carrying the unit.
- #[inline]
- pub fn x_typed(&self) -> Length<T, U> { Length::new(self.x) }
-
- /// Returns self.y as a Length carrying the unit.
- #[inline]
- pub fn y_typed(&self) -> Length<T, U> { Length::new(self.y) }
-
- /// Returns self.z as a Length carrying the unit.
- #[inline]
- pub fn z_typed(&self) -> Length<T, U> { Length::new(self.z) }
-
- #[inline]
- pub fn to_array(&self) -> [T; 3] { [self.x, self.y, self.z] }
-
- /// Drop the units, preserving only the numeric value.
- #[inline]
- pub fn to_untyped(&self) -> Vector3D<T> {
- vec3(self.x, self.y, self.z)
- }
-
- /// Tag a unitless value with units.
- #[inline]
- pub fn from_untyped(p: &Vector3D<T>) -> Self {
- vec3(p.x, p.y, p.z)
- }
-
- /// Convert into a 2d vector.
- #[inline]
- pub fn to_2d(&self) -> TypedVector2D<T, U> {
- self.xy()
- }
-}
-
-impl<T: Mul<T, Output=T> +
- Add<T, Output=T> +
- Sub<T, Output=T> +
- Copy, U> TypedVector3D<T, U> {
-
- // Dot product.
- #[inline]
- pub fn dot(self, other: Self) -> T {
- self.x * other.x +
- self.y * other.y +
- self.z * other.z
- }
-
- // Cross product.
- #[inline]
- pub fn cross(self, other: Self) -> Self {
- vec3(
- self.y * other.z - self.z * other.y,
- self.z * other.x - self.x * other.z,
- self.x * other.y - self.y * other.x
- )
- }
-
- #[inline]
- pub fn normalize(self) -> Self where T: Float + ApproxEq<T> {
- let dot = self.dot(self);
- if dot.approx_eq(&T::zero()) {
- self
- } else {
- self / dot.sqrt()
- }
- }
-
- #[inline]
- pub fn square_length(&self) -> T {
- self.x * self.x + self.y * self.y + self.z * self.z
- }
-
- #[inline]
- pub fn length(&self) -> T where T: Float + ApproxEq<T> {
- self.square_length().sqrt()
- }
-}
-
-impl<T, U> TypedVector3D<T, U>
-where T: Copy + One + Add<Output=T> + Sub<Output=T> + Mul<Output=T> {
- /// Linearly interpolate between this vector and another vector.
- ///
- /// `t` is expected to be between zero and one.
- #[inline]
- pub fn lerp(&self, other: Self, t: T) -> Self {
- let one_t = T::one() - t;
- (*self) * one_t + other * t
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> Add for TypedVector3D<T, U> {
- type Output = Self;
- #[inline]
- fn add(self, other: Self) -> Self {
- vec3(self.x + other.x, self.y + other.y, self.z + other.z)
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> Sub for TypedVector3D<T, U> {
- type Output = Self;
- #[inline]
- fn sub(self, other: Self) -> Self {
- vec3(self.x - other.x, self.y - other.y, self.z - other.z)
- }
-}
-
-impl<T: Copy + Add<T, Output=T>, U> AddAssign for TypedVector3D<T, U> {
- #[inline]
- fn add_assign(&mut self, other: Self) {
- *self = *self + other
- }
-}
-
-impl<T: Copy + Sub<T, Output=T>, U> SubAssign<TypedVector3D<T, U>> for TypedVector3D<T, U> {
- #[inline]
- fn sub_assign(&mut self, other: Self) {
- *self = *self - other
- }
-}
-
-impl <T: Copy + Neg<Output=T>, U> Neg for TypedVector3D<T, U> {
- type Output = Self;
- #[inline]
- fn neg(self) -> Self {
- vec3(-self.x, -self.y, -self.z)
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> Mul<T> for TypedVector3D<T, U> {
- type Output = Self;
- #[inline]
- fn mul(self, scale: T) -> Self {
- Self::new(self.x * scale, self.y * scale, self.z * scale)
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> Div<T> for TypedVector3D<T, U> {
- type Output = Self;
- #[inline]
- fn div(self, scale: T) -> Self {
- Self::new(self.x / scale, self.y / scale, self.z / scale)
- }
-}
-
-impl<T: Copy + Mul<T, Output=T>, U> MulAssign<T> for TypedVector3D<T, U> {
- #[inline]
- fn mul_assign(&mut self, scale: T) {
- *self = *self * scale
- }
-}
-
-impl<T: Copy + Div<T, Output=T>, U> DivAssign<T> for TypedVector3D<T, U> {
- #[inline]
- fn div_assign(&mut self, scale: T) {
- *self = *self / scale
- }
-}
-
-impl<T: Float, U> TypedVector3D<T, U> {
- #[inline]
- pub fn min(self, other: Self) -> Self {
- vec3(self.x.min(other.x), self.y.min(other.y), self.z.min(other.z))
- }
-
- #[inline]
- pub fn max(self, other: Self) -> Self {
- vec3(self.x.max(other.x), self.y.max(other.y), self.z.max(other.z))
- }
-}
-
-impl<T: Round, U> TypedVector3D<T, U> {
- /// Rounds each component to the nearest integer value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn round(&self) -> Self {
- vec3(self.x.round(), self.y.round(), self.z.round())
- }
-}
-
-impl<T: Ceil, U> TypedVector3D<T, U> {
- /// Rounds each component to the smallest integer equal or greater than the original value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn ceil(&self) -> Self {
- vec3(self.x.ceil(), self.y.ceil(), self.z.ceil())
- }
-}
-
-impl<T: Floor, U> TypedVector3D<T, U> {
- /// Rounds each component to the biggest integer equal or lower than the original value.
- ///
- /// This behavior is preserved for negative values (unlike the basic cast).
- #[inline]
- #[cfg_attr(feature = "unstable", must_use)]
- pub fn floor(&self) -> Self {
- vec3(self.x.floor(), self.y.floor(), self.z.floor())
- }
-}
-
-impl<T: NumCast + Copy, U> TypedVector3D<T, U> {
- /// Cast from one numeric representation to another, preserving the units.
- ///
- /// When casting from floating vector to integer coordinates, the decimals are truncated
- /// as one would expect from a simple cast, but this behavior does not always make sense
- /// geometrically. Consider using round(), ceil or floor() before casting.
- #[inline]
- pub fn cast<NewT: NumCast + Copy>(&self) -> Option<TypedVector3D<NewT, U>> {
- match (NumCast::from(self.x),
- NumCast::from(self.y),
- NumCast::from(self.z)) {
- (Some(x), Some(y), Some(z)) => Some(vec3(x, y, z)),
- _ => None
- }
- }
-
- // Convenience functions for common casts
-
- /// Cast into an `f32` vector.
- #[inline]
- pub fn to_f32(&self) -> TypedVector3D<f32, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an `usize` vector, truncating decimals if any.
- ///
- /// When casting from floating vector vectors, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_usize(&self) -> TypedVector3D<usize, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an `i32` vector, truncating decimals if any.
- ///
- /// When casting from floating vector vectors, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_i32(&self) -> TypedVector3D<i32, U> {
- self.cast().unwrap()
- }
-
- /// Cast into an `i64` vector, truncating decimals if any.
- ///
- /// When casting from floating vector vectors, it is worth considering whether
- /// to `round()`, `ceil()` or `floor()` before the cast in order to obtain
- /// the desired conversion behavior.
- #[inline]
- pub fn to_i64(&self) -> TypedVector3D<i64, U> {
- self.cast().unwrap()
- }
-}
-
-impl<T: Copy+ApproxEq<T>, U> ApproxEq<TypedVector3D<T, U>> for TypedVector3D<T, U> {
- #[inline]
- fn approx_epsilon() -> Self {
- vec3(T::approx_epsilon(), T::approx_epsilon(), T::approx_epsilon())
- }
-
- #[inline]
- fn approx_eq(&self, other: &Self) -> bool {
- self.x.approx_eq(&other.x)
- && self.y.approx_eq(&other.y)
- && self.z.approx_eq(&other.z)
- }
-
- #[inline]
- fn approx_eq_eps(&self, other: &Self, eps: &Self) -> bool {
- self.x.approx_eq_eps(&other.x, &eps.x)
- && self.y.approx_eq_eps(&other.y, &eps.y)
- && self.z.approx_eq_eps(&other.z, &eps.z)
- }
-}
-
-impl<T: Copy, U> Into<[T; 3]> for TypedVector3D<T, U> {
- fn into(self) -> [T; 3] {
- self.to_array()
- }
-}
-
-impl<T: Copy, U> From<[T; 3]> for TypedVector3D<T, U> {
- fn from(array: [T; 3]) -> Self {
- vec3(array[0], array[1], array[2])
- }
-}
-
-impl<T, U> TypedVector3D<T, U>
-where T: Signed {
- pub fn abs(&self) -> Self {
- vec3(self.x.abs(), self.y.abs(), self.z.abs())
- }
-}
-
-/// Convenience constructor.
-#[inline]
-pub fn vec2<T, U>(x: T, y: T) -> TypedVector2D<T, U> {
- TypedVector2D::new(x, y)
-}
-
-/// Convenience constructor.
-#[inline]
-pub fn vec3<T, U>(x: T, y: T, z: T) -> TypedVector3D<T, U> {
- TypedVector3D::new(x, y, z)
-}
-
-#[cfg(test)]
-mod vector2d {
- use super::{Vector2D, vec2};
- type Vec2 = Vector2D<f32>;
-
- #[test]
- pub fn test_scalar_mul() {
- let p1: Vec2 = vec2(3.0, 5.0);
-
- let result = p1 * 5.0;
-
- assert_eq!(result, Vector2D::new(15.0, 25.0));
- }
-
- #[test]
- pub fn test_dot() {
- let p1: Vec2 = vec2(2.0, 7.0);
- let p2: Vec2 = vec2(13.0, 11.0);
- assert_eq!(p1.dot(p2), 103.0);
- }
-
- #[test]
- pub fn test_cross() {
- let p1: Vec2 = vec2(4.0, 7.0);
- let p2: Vec2 = vec2(13.0, 8.0);
- let r = p1.cross(p2);
- assert_eq!(r, -59.0);
- }
-
- #[test]
- pub fn test_normalize() {
- let p0: Vec2 = Vec2::zero();
- let p1: Vec2 = vec2(4.0, 0.0);
- let p2: Vec2 = vec2(3.0, -4.0);
- assert_eq!(p0.normalize(), p0);
- assert_eq!(p1.normalize(), vec2(1.0, 0.0));
- assert_eq!(p2.normalize(), vec2(0.6, -0.8));
- }
-
- #[test]
- pub fn test_min() {
- let p1: Vec2 = vec2(1.0, 3.0);
- let p2: Vec2 = vec2(2.0, 2.0);
-
- let result = p1.min(p2);
-
- assert_eq!(result, vec2(1.0, 2.0));
- }
-
- #[test]
- pub fn test_max() {
- let p1: Vec2 = vec2(1.0, 3.0);
- let p2: Vec2 = vec2(2.0, 2.0);
-
- let result = p1.max(p2);
-
- assert_eq!(result, vec2(2.0, 3.0));
- }
-}
-
-#[cfg(test)]
-mod typedvector2d {
- use super::{TypedVector2D, Vector2D, vec2};
- use scale_factor::ScaleFactor;
-
- pub enum Mm {}
- pub enum Cm {}
-
- pub type Vector2DMm<T> = TypedVector2D<T, Mm>;
- pub type Vector2DCm<T> = TypedVector2D<T, Cm>;
-
- #[test]
- pub fn test_add() {
- let p1 = Vector2DMm::new(1.0, 2.0);
- let p2 = Vector2DMm::new(3.0, 4.0);
-
- let result = p1 + p2;
-
- assert_eq!(result, vec2(4.0, 6.0));
- }
-
- #[test]
- pub fn test_add_assign() {
- let mut p1 = Vector2DMm::new(1.0, 2.0);
- p1 += vec2(3.0, 4.0);
-
- assert_eq!(p1, vec2(4.0, 6.0));
- }
-
- #[test]
- pub fn test_scalar_mul() {
- let p1 = Vector2DMm::new(1.0, 2.0);
- let cm_per_mm: ScaleFactor<f32, Mm, Cm> = ScaleFactor::new(0.1);
-
- let result: Vector2DCm<f32> = p1 * cm_per_mm;
-
- assert_eq!(result, vec2(0.1, 0.2));
- }
-
- #[test]
- pub fn test_swizzling() {
- let p: Vector2D<i32> = vec2(1, 2);
- assert_eq!(p.yx(), vec2(2, 1));
- }
-}
-
-#[cfg(test)]
-mod vector3d {
- use super::{Vector3D, vec2, vec3};
- type Vec3 = Vector3D<f32>;
-
- #[test]
- pub fn test_dot() {
- let p1: Vec3 = vec3(7.0, 21.0, 32.0);
- let p2: Vec3 = vec3(43.0, 5.0, 16.0);
- assert_eq!(p1.dot(p2), 918.0);
- }
-
- #[test]
- pub fn test_cross() {
- let p1: Vec3 = vec3(4.0, 7.0, 9.0);
- let p2: Vec3 = vec3(13.0, 8.0, 3.0);
- let p3 = p1.cross(p2);
- assert_eq!(p3, vec3(-51.0, 105.0, -59.0));
- }
-
- #[test]
- pub fn test_normalize() {
- let p0: Vec3 = Vec3::zero();
- let p1: Vec3 = vec3(0.0, -6.0, 0.0);
- let p2: Vec3 = vec3(1.0, 2.0, -2.0);
- assert_eq!(p0.normalize(), p0);
- assert_eq!(p1.normalize(), vec3(0.0, -1.0, 0.0));
- assert_eq!(p2.normalize(), vec3(1.0/3.0, 2.0/3.0, -2.0/3.0));
- }
-
- #[test]
- pub fn test_min() {
- let p1: Vec3 = vec3(1.0, 3.0, 5.0);
- let p2: Vec3 = vec3(2.0, 2.0, -1.0);
-
- let result = p1.min(p2);
-
- assert_eq!(result, vec3(1.0, 2.0, -1.0));
- }
-
- #[test]
- pub fn test_max() {
- let p1: Vec3 = vec3(1.0, 3.0, 5.0);
- let p2: Vec3 = vec3(2.0, 2.0, -1.0);
-
- let result = p1.max(p2);
-
- assert_eq!(result, vec3(2.0, 3.0, 5.0));
- }
-
- #[test]
- pub fn test_swizzling() {
- let p: Vector3D<i32> = vec3(1, 2, 3);
- assert_eq!(p.xy(), vec2(1, 2));
- assert_eq!(p.xz(), vec2(1, 3));
- assert_eq!(p.yz(), vec2(2, 3));
- }
-}
--- a/third_party/rust/plane-split/.cargo-checksum.json
+++ b/third_party/rust/plane-split/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{".travis.yml":"b76d49f66f842c652d40825c67791352364a6b6bbb7d8d1009f2ac79eb413e66","Cargo.toml":"dafb727ecf8ce1c097737e0fc3c82a047591ac34c1c04362cd489c1e1fb1f91e","LICENSE":"b946744aeda89b467929585fe8eeb5461847695220c1b168fb375d8abd4ea3d0","README.md":"62f99334c17b451342fcea70eb1cc27b26612616b7c1a58fab50dd493f766f32","benches/split.rs":"dfe01759652e2098f20547e0ddcc1b2937e88c6d6ddb025353c037a46b7ef85d","src/bsp.rs":"66e1690aa8540f744ee013ac0e550ecdee84633727cb3a2d8239db3597ad25d6","src/lib.rs":"21d6135c10dd820c2b9ac484cc018e1149f2bf44c315d27134edd3ecb8a7f3d2","src/naive.rs":"444d3298224009209ae329458fe8df953193b15a04da29cdd6f498572a6471bf","tests/main.rs":"d65d7fe01ff3091a9b470a2f26b28108968ca5d32a5a14defba4336df31c7d7f","tests/split.rs":"19d5bfaaf93115ddecdac0f720893c61b2ed73a0bcb4711534ac7e4500cc06ae"},"package":"e57800a97ca52c556db6b6184a3201f05366ad5e11876f7d17e234589ca2fa26"}
\ No newline at end of file
+{"files":{".travis.yml":"b76d49f66f842c652d40825c67791352364a6b6bbb7d8d1009f2ac79eb413e66","Cargo.toml":"74145a361386c636f61349e165ef59dd1631a4a5f7e1c16c96b0163184e6ccaa","LICENSE":"b946744aeda89b467929585fe8eeb5461847695220c1b168fb375d8abd4ea3d0","README.md":"62f99334c17b451342fcea70eb1cc27b26612616b7c1a58fab50dd493f766f32","benches/split.rs":"dfe01759652e2098f20547e0ddcc1b2937e88c6d6ddb025353c037a46b7ef85d","src/bsp.rs":"66e1690aa8540f744ee013ac0e550ecdee84633727cb3a2d8239db3597ad25d6","src/lib.rs":"21d6135c10dd820c2b9ac484cc018e1149f2bf44c315d27134edd3ecb8a7f3d2","src/naive.rs":"444d3298224009209ae329458fe8df953193b15a04da29cdd6f498572a6471bf","tests/main.rs":"54104b672128ae623e1ef6000c30110c2b713482b81bc5f18ac1f86088813cb1","tests/split.rs":"67259be206c2e9eb77b0ff285dc5c5d912f7e539c15fc9e278e5ec9959bc24af"},"package":"d2adb8d1523b2ddcd98275613e9bc04eef75b47a39e252e63733a3218ae3c1b7"}
\ No newline at end of file
--- a/third_party/rust/plane-split/Cargo.toml
+++ b/third_party/rust/plane-split/Cargo.toml
@@ -1,15 +1,33 @@
+# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+#
+# When uploading crates to the registry Cargo will automatically
+# "normalize" Cargo.toml files for maximal compatibility
+# with all versions of Cargo and also rewrite `path` dependencies
+# to registry (e.g. crates.io) dependencies
+#
+# If you believe there's an error in this file please file an
+# issue against the rust-lang/cargo repository. If you're
+# editing this file be aware that the upstream Cargo.toml
+# will likely look very different (and much more reasonable)
+
[package]
name = "plane-split"
-version = "0.6.0"
+version = "0.7.0"
+authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
description = "Plane splitting"
-authors = ["Dzmitry Malyshau <kvark@mozilla.com>"]
+documentation = "https://docs.rs/plane-split"
+keywords = ["geometry", "math"]
license = "MPL-2.0"
repository = "https://github.com/kvark/plane-split"
-keywords = ["geometry", "math"]
-documentation = "https://docs.rs/plane-split"
+[dependencies.binary-space-partition]
+version = "0.1.2"
+
+[dependencies.euclid]
+version = "0.16"
-[dependencies]
-binary-space-partition = "0.1.2"
-euclid = "0.15"
-log = "0.3"
-num-traits = {version = "0.1.37", default-features = false}
+[dependencies.log]
+version = "0.3"
+
+[dependencies.num-traits]
+version = "0.1.37"
+default-features = false
--- a/third_party/rust/plane-split/tests/main.rs
+++ b/third_party/rust/plane-split/tests/main.rs
@@ -1,12 +1,12 @@
extern crate euclid;
extern crate plane_split;
-use euclid::{Radians, TypedRect, TypedSize2D, TypedTransform3D, point2, point3, vec3};
+use euclid::{Angle, TypedRect, TypedSize2D, TypedTransform3D, point2, point3, vec3};
use euclid::approxeq::ApproxEq;
use plane_split::{Intersection, Line, LineProjection, Polygon};
#[test]
fn line_proj_bounds() {
assert_eq!((-5i8, 4), LineProjection { markers: [-5i8, 1, 4, 2] }.get_bounds());
assert_eq!((1f32, 4.0), LineProjection { markers: [4f32, 3.0, 2.0, 1.0] }.get_bounds());
@@ -51,17 +51,17 @@ fn valid() {
};
assert!(poly_c.is_valid());
}
#[test]
fn from_transformed_rect() {
let rect: TypedRect<f32, ()> = TypedRect::new(point2(10.0, 10.0), TypedSize2D::new(20.0, 30.0));
let transform: TypedTransform3D<f32, (), ()> =
- TypedTransform3D::create_rotation(0.5f32.sqrt(), 0.0, 0.5f32.sqrt(), Radians::new(5.0))
+ TypedTransform3D::create_rotation(0.5f32.sqrt(), 0.0, 0.5f32.sqrt(), Angle::radians(5.0))
.pre_translate(vec3(0.0, 0.0, 10.0));
let poly = Polygon::from_transformed_rect(rect, transform, 0);
assert!(poly.is_valid());
}
#[test]
fn untransform_point() {
let poly: Polygon<f32, ()> = Polygon {
--- a/third_party/rust/plane-split/tests/split.rs
+++ b/third_party/rust/plane-split/tests/split.rs
@@ -1,13 +1,13 @@
extern crate euclid;
extern crate plane_split;
use std::f32::consts::FRAC_PI_4;
-use euclid::{Radians, TypedTransform3D, TypedRect, vec3};
+use euclid::{Angle, TypedTransform3D, TypedRect, vec3};
use plane_split::{BspSplitter, NaiveSplitter, Polygon, Splitter, _make_grid};
fn grid_impl(count: usize, splitter: &mut Splitter<f32, ()>) {
let polys = _make_grid(count);
let result = splitter.solve(&polys, vec3(0.0, 0.0, 1.0));
assert_eq!(result.len(), count + count*count + count*count*count);
}
@@ -20,21 +20,21 @@ fn grid_naive() {
#[test]
fn grid_bsp() {
grid_impl(2, &mut BspSplitter::new());
}
fn sort_rotation(splitter: &mut Splitter<f32, ()>) {
let transform0: TypedTransform3D<f32, (), ()> =
- TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Radians::new(-FRAC_PI_4));
+ TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Angle::radians(-FRAC_PI_4));
let transform1: TypedTransform3D<f32, (), ()> =
- TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Radians::new(0.0));
+ TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Angle::radians(0.0));
let transform2: TypedTransform3D<f32, (), ()> =
- TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Radians::new(FRAC_PI_4));
+ TypedTransform3D::create_rotation(0.0, 1.0, 0.0, Angle::radians(FRAC_PI_4));
let rect: TypedRect<f32, ()> = euclid::rect(-10.0, -10.0, 20.0, 20.0);
let polys = [
Polygon::from_transformed_rect(rect, transform0, 0),
Polygon::from_transformed_rect(rect, transform1, 1),
Polygon::from_transformed_rect(rect, transform2, 2),
];
--- a/third_party/rust/serde/.cargo-checksum.json
+++ b/third_party/rust/serde/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"0537077146c955003ccbb274e748e727b66447fc4f07b585935a407e9ecee73a","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":"7659af7266821d1aca648ae48146216dfed0415f134f3989fa25a00ed6f265e2","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":"c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4"}
\ No newline at end of file
+{"files":{"Cargo.toml":"f98dcc6eedbfb307be98a2d8ca49d3cc10a76a08e7d7dfa2f6ec69987f0c679d","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/de/from_primitive.rs":"28ec3ab1c430cf27d632b642ccfccb6d055eeb9fb576e7e446ba24c66f507fb4","src/de/ignored_any.rs":"1b5ee592f5ae58d69e321144d4397f149c047e327529d0b880e1a5285e781a35","src/de/impls.rs":"d220ded8bebc3367c3a0ac1360b59be1b435df40be65a5b688a6ba8108e96bea","src/de/mod.rs":"b8fd19e4a2d40369cb85e3ed6bc5197800c06b2271a846ed6e9b0cb7af41c5f0","src/de/utf8.rs":"956b124b7ce98353cb781b56e43a6fed2e67f1389d35b7a468d5be75b1485853","src/de/value.rs":"fe31174cc41035a1b53d4657b6cae6f3bcb660be39eccaae281a6e3705655578","src/export.rs":"7477f5bd345ca9e0b8d56bccdc62484e42a92fc6cd909bf17fb6e05cd1eb7946","src/lib.rs":"f549fbbd92b2e5e946a327eadf18216b9fe076f569bd623a32872797dc9eb4bc","src/macros.rs":"e1d542b1dac2c1d1f9d5ada7cc5b6639767fc67851421cc3adfb942a7cf750b6","src/private/de.rs":"15b82edcadaa60e748bf6ee0e0e14464cf945f39cb7493d3c1684cc34f6594b6","src/private/macros.rs":"6861a4f332ea24d0ed5db1c28fe3105d2716523902f045c0bbbd439ebf9e44de","src/private/mod.rs":"bcd7c54838e139475c23a323678e20eccbe88c0be93f7977f7675cead4d3b6ed","src/private/ser.rs":"eec5aecf077cebf4dc3fdbe83780f716bf33d311806ee59ce42a0c53c2f92211","src/ser/impls.rs":"dc5219e898d67c9422fef81d1f36d25ea92341c5ad3d976c0017886f371a8d51","src/ser/impossible.rs":"35bd09bb517b28eda0048b0622eb5a0313d5aebf37c03b5a44dbca200d0a9ac8","src/ser/mod.rs":"3d92794f13c8d90c2ebc33716bd6e4d4dde552c6f7de42dfaf9967d8a9ab7d10"},"package":null}
\ No newline at end of file
--- a/third_party/rust/serde/Cargo.toml
+++ b/third_party/rust/serde/Cargo.toml
@@ -1,45 +1,68 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
[package]
name = "serde"
-version = "1.0.8"
+version = "1.0.23" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
-include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+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/"
-readme = "README.md"
keywords = ["serde", "serialization", "no_std"]
categories = ["encoding"]
-license = "MIT/Apache-2.0"
-repository = "https://github.com/serde-rs/serde"
-[dependencies.serde_derive]
-version = "1.0"
-optional = true
-[dev-dependencies.serde_derive]
-version = "1.0"
+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]
-playground = ["serde_derive"]
+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 in the Rust core allocation and collections library
+# including String, Box<T>, Vec<T>, 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 core allocation library:
+#
+# https://doc.rust-lang.org/alloc/
alloc = ["unstable"]
-unstable = []
-std = []
-collections = ["alloc"]
+
+# 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 = []
-default = ["std"]
-[badges.appveyor]
-repository = "serde-rs/serde"
-[badges.travis-ci]
-repository = "serde-rs/serde"
+# Get serde_derive picked up by the Integer 32 playground. Not public API.
+#
+# http://play.integer32.com/
+playground = ["serde_derive"]
--- a/third_party/rust/serde/README.md
+++ b/third_party/rust/serde/README.md
@@ -15,19 +15,40 @@ You may be looking for:
- [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>
+<details>
+<summary>
+Click to show Cargo.toml.
+<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
+</summary>
+
+```toml
+[dependencies]
+
+# The core APIs, including the Serialize and Deserialize traits. Always
+# required when using Serde.
+serde = "1.0"
+
+# Support for #[derive(Serialize, Deserialize)]. Required if you want Serde
+# to work for structs and enums defined in your crate.
+serde_derive = "1.0"
+
+# Each data format lives in its own crate; the sample code below uses JSON
+# but you may be using a different one.
+serde_json = "1.0"
+```
+
+</details>
+<p></p>
```rust
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
--- a/third_party/rust/serde/src/de/impls.rs
+++ b/third_party/rust/serde/src/de/impls.rs
@@ -6,22 +6,23 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use lib::*;
use de::{Deserialize, Deserializer, EnumAccess, Error, SeqAccess, Unexpected, VariantAccess,
Visitor};
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
use de::MapAccess;
use de::from_primitive::FromPrimitive;
+use private::de::DeserializeFromSeed;
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
use private::de::size_hint;
////////////////////////////////////////////////////////////////////////////////
struct UnitVisitor;
impl<'de> Visitor<'de> for UnitVisitor {
type Value = ();
@@ -46,16 +47,17 @@ impl<'de> Deserialize<'de> for () {
deserializer.deserialize_unit(UnitVisitor)
}
}
////////////////////////////////////////////////////////////////////////////////
struct BoolVisitor;
+
impl<'de> Visitor<'de> for BoolVisitor {
type Value = bool;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a boolean")
}
fn visit_bool<E>(self, v: bool) -> Result<bool, E>
@@ -203,20 +205,22 @@ impl<'de> Deserialize<'de> for char {
D: Deserializer<'de>,
{
deserializer.deserialize_char(CharVisitor)
}
}
////////////////////////////////////////////////////////////////////////////////
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
struct StringVisitor;
+#[cfg(any(feature = "std", feature = "alloc"))]
+struct StringFromVisitor<'a>(&'a mut String);
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Visitor<'de> for StringVisitor {
type Value = String;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
formatter.write_str("a string")
}
fn visit_str<E>(self, v: &str) -> Result<String, E>
@@ -249,24 +253,84 @@ impl<'de> Visitor<'de> for StringVisitor
{
match String::from_utf8(v) {
Ok(s) => Ok(s),
Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),),
}
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
+impl<'a, 'de> Visitor<'de> for StringFromVisitor<'a> {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a string")
+ }
+
+ fn visit_str<E>(self, v: &str) -> Result<(), E>
+ where
+ E: Error,
+ {
+ self.0.clear();
+ self.0.push_str(v);
+ Ok(())
+ }
+
+ fn visit_string<E>(self, v: String) -> Result<(), E>
+ where
+ E: Error,
+ {
+ *self.0 = v;
+ Ok(())
+ }
+
+ fn visit_bytes<E>(self, v: &[u8]) -> Result<(), E>
+ where
+ E: Error,
+ {
+ match str::from_utf8(v) {
+ Ok(s) => {
+ self.0.clear();
+ self.0.push_str(s);
+ Ok(())
+ }
+ Err(_) => Err(Error::invalid_value(Unexpected::Bytes(v), &self)),
+ }
+ }
+
+ fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<(), E>
+ where
+ E: Error,
+ {
+ match String::from_utf8(v) {
+ Ok(s) => {
+ *self.0 = s;
+ Ok(())
+ }
+ Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),),
+ }
+ }
+}
+
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de> Deserialize<'de> for String {
fn deserialize<D>(deserializer: D) -> Result<String, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_string(StringVisitor)
}
+
+ fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_string(StringFromVisitor(self))
+ }
}
////////////////////////////////////////////////////////////////////////////////
struct StrVisitor;
impl<'a> Visitor<'a> for StrVisitor {
type Value = &'a str;
@@ -395,31 +459,38 @@ impl<'de> Deserialize<'de> for CString {
fn deserialize<D>(deserializer: D) -> Result<CString, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_byte_buf(CStringVisitor)
}
}
-#[cfg(all(feature = "std", feature = "unstable"))]
-impl<'de> Deserialize<'de> for Box<CStr> {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- CString::deserialize(deserializer).map(CString::into_boxed_c_str)
+macro_rules! forwarded_impl {
+ (( $($id: ident),* ), $ty: ty, $func: expr) => {
+ impl<'de $(, $id : Deserialize<'de>,)*> Deserialize<'de> for $ty {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer).map($func)
+ }
+ }
}
}
+#[cfg(all(feature = "std", feature = "unstable"))]
+forwarded_impl!((), Box<CStr>, CString::into_boxed_c_str);
+
////////////////////////////////////////////////////////////////////////////////
struct OptionVisitor<T> {
marker: PhantomData<T>,
}
+struct OptionFromVisitor<'a, T: 'a>(&'a mut Option<T>);
impl<'de, T> Visitor<'de> for OptionVisitor<T>
where
T: Deserialize<'de>,
{
type Value = Option<T>;
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
@@ -446,26 +517,76 @@ where
fn visit_some<D>(self, deserializer: D) -> Result<Option<T>, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(Some)
}
}
+impl<'a, 'de, T> Visitor<'de> for OptionFromVisitor<'a, T>
+where
+ T: Deserialize<'de>,
+{
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("option")
+ }
+
+ #[inline]
+ fn visit_unit<E>(self) -> Result<(), E>
+ where
+ E: Error,
+ {
+ *self.0 = None;
+ Ok(())
+ }
+
+ #[inline]
+ fn visit_none<E>(self) -> Result<(), E>
+ where
+ E: Error,
+ {
+ *self.0 = None;
+ Ok(())
+ }
+
+ #[inline]
+ fn visit_some<D>(self, deserializer: D) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // The some enum's repr is opaque, so we can't play cute tricks with
+ // its tag to build this in place unconditionally.
+ //
+ // FIXME: investigate whether branching on the old value being Some to
+ // deserialize_from the value is profitable (probably data-dependent?)
+ *self.0 = try!(T::deserialize(deserializer).map(Some));
+ Ok(())
+ }
+}
+
impl<'de, T> Deserialize<'de> for Option<T>
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<Option<T>, D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_option(OptionVisitor { marker: PhantomData })
}
+
+ fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_option(OptionFromVisitor(self))
+ }
}
////////////////////////////////////////////////////////////////////////////////
struct PhantomDataVisitor<T> {
marker: PhantomData<T>,
}
@@ -492,23 +613,25 @@ impl<'de, T> Deserialize<'de> for Phanto
{
let visitor = PhantomDataVisitor { marker: PhantomData };
deserializer.deserialize_unit_struct("PhantomData", visitor)
}
}
////////////////////////////////////////////////////////////////////////////////
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! seq_impl {
(
$ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
$access:ident,
$ctor:expr,
+ $clear:expr,
$with_capacity:expr,
+ $reserve:expr,
$insert:expr
) => {
impl<'de, T $(, $typaram)*> Deserialize<'de> for $ty<T $(, $typaram)*>
where
T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*,
$($typaram: $bound1 $(+ $bound2)*,)*
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
@@ -543,73 +666,127 @@ macro_rules! seq_impl {
Ok(values)
}
}
let visitor = SeqVisitor { marker: PhantomData };
deserializer.deserialize_seq(visitor)
}
+
+ fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct SeqVisitor<'a, T: 'a $(, $typaram: 'a)*>(&'a mut $ty<T $(, $typaram)*>);
+
+ impl<'a, 'de, T $(, $typaram)*> Visitor<'de> for SeqVisitor<'a, T $(, $typaram)*>
+ where
+ T: Deserialize<'de> $(+ $tbound1 $(+ $tbound2)*)*,
+ $($typaram: $bound1 $(+ $bound2)*,)*
+ {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("a sequence")
+ }
+
+ #[inline]
+ fn visit_seq<A>(mut self, mut $access: A) -> Result<(), A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ $clear(&mut self.0);
+ $reserve(&mut self.0, size_hint::cautious($access.size_hint()));
+
+ // FIXME: try to overwrite old values here? (Vec, VecDeque, LinkedList)
+ while let Some(value) = try!($access.next_element()) {
+ $insert(&mut self.0, value);
+ }
+
+ Ok(())
+ }
+ }
+
+ deserializer.deserialize_seq(SeqVisitor(self))
+ }
}
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+// Dummy impl of reserve
+#[cfg(any(feature = "std", feature = "alloc"))]
+fn nop_reserve<T, U>(_x: T, _y: U) { }
+
+#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
BinaryHeap<T: Ord>,
seq,
BinaryHeap::new(),
+ BinaryHeap::clear,
BinaryHeap::with_capacity(size_hint::cautious(seq.size_hint())),
+ BinaryHeap::reserve,
BinaryHeap::push);
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
BTreeSet<T: Eq + Ord>,
seq,
BTreeSet::new(),
+ BTreeSet::clear,
BTreeSet::new(),
+ nop_reserve,
BTreeSet::insert);
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
LinkedList<T>,
seq,
LinkedList::new(),
+ LinkedList::clear,
LinkedList::new(),
+ nop_reserve,
LinkedList::push_back);
#[cfg(feature = "std")]
seq_impl!(
HashSet<T: Eq + Hash, S: BuildHasher + Default>,
seq,
HashSet::with_hasher(S::default()),
+ HashSet::clear,
HashSet::with_capacity_and_hasher(size_hint::cautious(seq.size_hint()), S::default()),
+ HashSet::reserve,
HashSet::insert);
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
Vec<T>,
seq,
Vec::new(),
+ Vec::clear,
Vec::with_capacity(size_hint::cautious(seq.size_hint())),
+ Vec::reserve,
Vec::push);
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(
VecDeque<T>,
seq,
VecDeque::new(),
+ VecDeque::clear,
VecDeque::with_capacity(size_hint::cautious(seq.size_hint())),
+ VecDeque::reserve,
VecDeque::push_back);
////////////////////////////////////////////////////////////////////////////////
struct ArrayVisitor<A> {
marker: PhantomData<A>,
}
+struct ArrayFromVisitor<'a, A: 'a>(&'a mut A);
impl<A> ArrayVisitor<A> {
fn new() -> Self {
ArrayVisitor { marker: PhantomData }
}
}
impl<'de, T> Visitor<'de> for ArrayVisitor<[T; 0]> {
@@ -662,26 +839,62 @@ macro_rules! array_impls {
None => return Err(Error::invalid_length($n, &self)),
};
)+
Ok([$($name),+])
}
}
+ impl<'a, 'de, T> Visitor<'de> for ArrayFromVisitor<'a, [T; $len]>
+ where
+ T: Deserialize<'de>,
+ {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(concat!("an array of length ", $len))
+ }
+
+ #[inline]
+ fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let mut fail_idx = None;
+ for (idx, dest) in self.0[..].iter_mut().enumerate() {
+ if try!(seq.next_element_seed(DeserializeFromSeed(dest))).is_none() {
+ fail_idx = Some(idx);
+ break;
+ }
+ }
+ if let Some(idx) = fail_idx {
+ return Err(Error::invalid_length(idx, &self));
+ }
+ Ok(())
+ }
+ }
+
impl<'de, T> Deserialize<'de> for [T; $len]
where
T: Deserialize<'de>,
{
fn deserialize<D>(deserializer: D) -> Result<[T; $len], D::Error>
where
D: Deserializer<'de>,
{
deserializer.deserialize_tuple($len, ArrayVisitor::<[T; $len]>::new())
}
+
+ fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ deserializer.deserialize_tuple($len, ArrayFromVisitor(self))
+ }
}
)+
}
}
array_impls! {
1 => (0 a)
2 => (0 a 1 b)
@@ -715,87 +928,114 @@ array_impls! {
30 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad)
31 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad 30 ae)
32 => (0 a 1 b 2 c 3 d 4 e 5 f 6 g 7 h 8 i 9 j 10 k 11 l 12 m 13 n 14 o 15 p 16 q 17 r 18 s 19 t 20 u 21 v 22 w 23 x 24 y 25 z 26 aa 27 ab 28 ac 29 ad 30 ae 31 af)
}
////////////////////////////////////////////////////////////////////////////////
macro_rules! tuple_impls {
- ($($len:tt $visitor:ident => ($($n:tt $name:ident)+))+) => {
+ ($($len:tt => ($($n:tt $name:ident)+))+) => {
$(
- struct $visitor<$($name,)+> {
- marker: PhantomData<($($name,)+)>,
- }
-
- impl<$($name,)+> $visitor<$($name,)+> {
- fn new() -> Self {
- $visitor { marker: PhantomData }
- }
- }
-
- impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for $visitor<$($name,)+> {
- type Value = ($($name,)+);
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str(concat!("a tuple of size ", $len))
- }
-
- #[inline]
- #[allow(non_snake_case)]
- fn visit_seq<A>(self, mut seq: A) -> Result<($($name,)+), A::Error>
- where
- A: SeqAccess<'de>,
- {
- $(
- let $name = match try!(seq.next_element()) {
- Some(value) => value,
- None => return Err(Error::invalid_length($n, &self)),
- };
- )+
-
- Ok(($($name,)+))
- }
- }
-
impl<'de, $($name: Deserialize<'de>),+> Deserialize<'de> for ($($name,)+) {
#[inline]
fn deserialize<D>(deserializer: D) -> Result<($($name,)+), D::Error>
where
D: Deserializer<'de>,
{
- deserializer.deserialize_tuple($len, $visitor::new())
+ struct TupleVisitor<$($name,)+> {
+ marker: PhantomData<($($name,)+)>,
+ }
+
+ impl<'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<$($name,)+> {
+ type Value = ($($name,)+);
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(concat!("a tuple of size ", $len))
+ }
+
+ #[inline]
+ #[allow(non_snake_case)]
+ fn visit_seq<A>(self, mut seq: A) -> Result<($($name,)+), A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ $(
+ let $name = match try!(seq.next_element()) {
+ Some(value) => value,
+ None => return Err(Error::invalid_length($n, &self)),
+ };
+ )+
+
+ Ok(($($name,)+))
+ }
+ }
+
+ deserializer.deserialize_tuple($len, TupleVisitor { marker: PhantomData })
+ }
+
+ #[inline]
+ fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct TupleVisitor<'a, $($name: 'a,)+>(&'a mut ($($name,)+));
+
+ impl<'a, 'de, $($name: Deserialize<'de>),+> Visitor<'de> for TupleVisitor<'a, $($name,)+> {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(concat!("a tuple of size ", $len))
+ }
+
+ #[inline]
+ #[allow(non_snake_case)]
+ fn visit_seq<A>(self, mut seq: A) -> Result<(), A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ $(
+ if try!(seq.next_element_seed(DeserializeFromSeed(&mut (self.0).$n))).is_none() {
+ return Err(Error::invalid_length($n, &self));
+ }
+ )+
+
+ Ok(())
+ }
+ }
+
+ deserializer.deserialize_tuple($len, TupleVisitor(self))
}
}
)+
}
}
tuple_impls! {
- 1 TupleVisitor1 => (0 T0)
- 2 TupleVisitor2 => (0 T0 1 T1)
- 3 TupleVisitor3 => (0 T0 1 T1 2 T2)
- 4 TupleVisitor4 => (0 T0 1 T1 2 T2 3 T3)
- 5 TupleVisitor5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
- 6 TupleVisitor6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
- 7 TupleVisitor7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
- 8 TupleVisitor8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
- 9 TupleVisitor9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
- 10 TupleVisitor10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
- 11 TupleVisitor11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
- 12 TupleVisitor12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
- 13 TupleVisitor13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
- 14 TupleVisitor14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
- 15 TupleVisitor15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
- 16 TupleVisitor16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
+ 1 => (0 T0)
+ 2 => (0 T0 1 T1)
+ 3 => (0 T0 1 T1 2 T2)
+ 4 => (0 T0 1 T1 2 T2 3 T3)
+ 5 => (0 T0 1 T1 2 T2 3 T3 4 T4)
+ 6 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5)
+ 7 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6)
+ 8 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7)
+ 9 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8)
+ 10 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9)
+ 11 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10)
+ 12 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11)
+ 13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
+ 14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
+ 15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
+ 16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
}
////////////////////////////////////////////////////////////////////////////////
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! map_impl {
(
$ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound1:ident $(+ $bound2:ident)*)* >,
$access:ident,
$ctor:expr,
$with_capacity:expr
) => {
impl<'de, K, V $(, $typaram)*> Deserialize<'de> for $ty<K, V $(, $typaram)*>
@@ -841,64 +1081,233 @@ macro_rules! map_impl {
let visitor = MapVisitor { marker: PhantomData };
deserializer.deserialize_map(visitor)
}
}
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
map_impl!(
BTreeMap<K: Ord, V>,
map,
BTreeMap::new(),
BTreeMap::new());
#[cfg(feature = "std")]
map_impl!(
HashMap<K: Eq + Hash, V, S: BuildHasher + Default>,
map,
HashMap::with_hasher(S::default()),
HashMap::with_capacity_and_hasher(size_hint::cautious(map.size_hint()), S::default()));
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
-macro_rules! parse_impl {
- ($ty:ty) => {
+macro_rules! parse_ip_impl {
+ ($ty:ty; $size: expr) => {
impl<'de> Deserialize<'de> for $ty {
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>,
{
- let s = try!(String::deserialize(deserializer));
- s.parse().map_err(Error::custom)
+ if deserializer.is_human_readable() {
+ let s = try!(String::deserialize(deserializer));
+ s.parse().map_err(Error::custom)
+ } else {
+ <[u8; $size]>::deserialize(deserializer).map(<$ty>::from)
+ }
+ }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+macro_rules! variant_identifier {
+ (
+ $name_kind: ident ( $($variant: ident; $bytes: expr; $index: expr),* )
+ $expecting_message: expr,
+ $variants_name: ident
+ ) => {
+ enum $name_kind {
+ $( $variant ),*
+ }
+
+ static $variants_name: &'static [&'static str] = &[ $( stringify!($variant) ),*];
+
+ impl<'de> Deserialize<'de> for $name_kind {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct KindVisitor;
+
+ impl<'de> Visitor<'de> for KindVisitor {
+ type Value = $name_kind;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str($expecting_message)
+ }
+
+ fn visit_u32<E>(self, value: u32) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ $(
+ $index => Ok($name_kind :: $variant),
+ )*
+ _ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self),),
+ }
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ $(
+ stringify!($variant) => Ok($name_kind :: $variant),
+ )*
+ _ => Err(Error::unknown_variant(value, $variants_name)),
+ }
+ }
+
+ fn visit_bytes<E>(self, value: &[u8]) -> Result<Self::Value, E>
+ where
+ E: Error,
+ {
+ match value {
+ $(
+ $bytes => Ok($name_kind :: $variant),
+ )*
+ _ => {
+ match str::from_utf8(value) {
+ Ok(value) => Err(Error::unknown_variant(value, $variants_name)),
+ Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)),
+ }
+ }
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(KindVisitor)
}
}
}
}
#[cfg(feature = "std")]
-parse_impl!(net::IpAddr);
+macro_rules! deserialize_enum {
+ (
+ $name: ident $name_kind: ident ( $($variant: ident; $bytes: expr; $index: expr),* )
+ $expecting_message: expr,
+ $deserializer: expr
+ ) => {
+ variant_identifier!{
+ $name_kind ( $($variant; $bytes; $index),* )
+ $expecting_message,
+ VARIANTS
+ }
+
+ struct EnumVisitor;
+ impl<'de> Visitor<'de> for EnumVisitor {
+ type Value = $name;
-#[cfg(feature = "std")]
-parse_impl!(net::Ipv4Addr);
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str(concat!("a ", stringify!($name)))
+ }
+
+
+ fn visit_enum<A>(self, data: A) -> Result<Self::Value, A::Error>
+ where
+ A: EnumAccess<'de>,
+ {
+ match try!(data.variant()) {
+ $(
+ ($name_kind :: $variant, v) => v.newtype_variant().map($name :: $variant),
+ )*
+ }
+ }
+ }
+ $deserializer.deserialize_enum(stringify!($name), VARIANTS, EnumVisitor)
+ }
+}
#[cfg(feature = "std")]
-parse_impl!(net::Ipv6Addr);
+impl<'de> Deserialize<'de> for net::IpAddr {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ if deserializer.is_human_readable() {
+ let s = try!(String::deserialize(deserializer));
+ s.parse().map_err(Error::custom)
+ } else {
+ use lib::net::IpAddr;
+ deserialize_enum!{
+ IpAddr IpAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
+ "`V4` or `V6`",
+ deserializer
+ }
+ }
+ }
+}
+
+#[cfg(feature = "std")]
+parse_ip_impl!(net::Ipv4Addr; 4);
+
+#[cfg(feature = "std")]
+parse_ip_impl!(net::Ipv6Addr; 16);
#[cfg(feature = "std")]
-parse_impl!(net::SocketAddr);
+macro_rules! parse_socket_impl {
+ ($ty:ty, $new: expr) => {
+ impl<'de> Deserialize<'de> for $ty {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ if deserializer.is_human_readable() {
+ let s = try!(String::deserialize(deserializer));
+ s.parse().map_err(Error::custom)
+ } else {
+ <(_, u16)>::deserialize(deserializer).map(|(ip, port)| $new(ip, port))
+ }
+ }
+ }
+ }
+}
#[cfg(feature = "std")]
-parse_impl!(net::SocketAddrV4);
+impl<'de> Deserialize<'de> for net::SocketAddr {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ if deserializer.is_human_readable() {
+ let s = try!(String::deserialize(deserializer));
+ s.parse().map_err(Error::custom)
+ } else {
+ use lib::net::SocketAddr;
+ deserialize_enum!{
+ SocketAddr SocketAddrKind (V4; b"V4"; 0, V6; b"V6"; 1)
+ "`V4` or `V6`",
+ deserializer
+ }
+ }
+ }
+}
#[cfg(feature = "std")]
-parse_impl!(net::SocketAddrV6);
+parse_socket_impl!(net::SocketAddrV4, net::SocketAddrV4::new);
+
+#[cfg(feature = "std")]
+parse_socket_impl!(net::SocketAddrV6, |ip, port| net::SocketAddrV6::new(ip, port, 0, 0));
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
struct PathVisitor;
#[cfg(feature = "std")]
impl<'a> Visitor<'a> for PathVisitor {
@@ -973,80 +1382,20 @@ impl<'de> Deserialize<'de> for PathBuf {
////////////////////////////////////////////////////////////////////////////////
// If this were outside of the serde crate, it would just use:
//
// #[derive(Deserialize)]
// #[serde(variant_identifier)]
#[cfg(all(feature = "std", any(unix, windows)))]
-enum OsStringKind {
- Unix,
- Windows,
-}
-
-#[cfg(all(feature = "std", any(unix, windows)))]
-static OSSTR_VARIANTS: &'static [&'static str] = &["Unix", "Windows"];
-
-#[cfg(all(feature = "std", any(unix, windows)))]
-impl<'de> Deserialize<'de> for OsStringKind {
- fn deserialize<D>(deserializer: D) -> Result<OsStringKind, D::Error>
- where
- D: Deserializer<'de>,
- {
- struct KindVisitor;
-
- impl<'de> Visitor<'de> for KindVisitor {
- type Value = OsStringKind;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("`Unix` or `Windows`")
- }
-
- fn visit_u32<E>(self, value: u32) -> Result<OsStringKind, E>
- where
- E: Error,
- {
- match value {
- 0 => Ok(OsStringKind::Unix),
- 1 => Ok(OsStringKind::Windows),
- _ => Err(Error::invalid_value(Unexpected::Unsigned(value as u64), &self),),
- }
- }
-
- fn visit_str<E>(self, value: &str) -> Result<OsStringKind, E>
- where
- E: Error,
- {
- match value {
- "Unix" => Ok(OsStringKind::Unix),
- "Windows" => Ok(OsStringKind::Windows),
- _ => Err(Error::unknown_variant(value, OSSTR_VARIANTS)),
- }
- }
-
- fn visit_bytes<E>(self, value: &[u8]) -> Result<OsStringKind, E>
- where
- E: Error,
- {
- match value {
- b"Unix" => Ok(OsStringKind::Unix),
- b"Windows" => Ok(OsStringKind::Windows),
- _ => {
- match str::from_utf8(value) {
- Ok(value) => Err(Error::unknown_variant(value, OSSTR_VARIANTS)),
- Err(_) => Err(Error::invalid_value(Unexpected::Bytes(value), &self)),
- }
- }
- }
- }
- }
-
- deserializer.deserialize_identifier(KindVisitor)
- }
+variant_identifier!{
+ OsStringKind (Unix; b"Unix"; 0, Windows; b"Windows"; 1)
+ "`Unix` or `Windows`",
+ OSSTR_VARIANTS
}
#[cfg(all(feature = "std", any(unix, windows)))]
struct OsStringVisitor;
#[cfg(all(feature = "std", any(unix, windows)))]
impl<'de> Visitor<'de> for OsStringVisitor {
type Value = OsString;
@@ -1093,143 +1442,91 @@ impl<'de> Deserialize<'de> for OsString
{
deserializer.deserialize_enum("OsString", OSSTR_VARIANTS, OsStringVisitor)
}
}
////////////////////////////////////////////////////////////////////////////////
#[cfg(any(feature = "std", feature = "alloc"))]
-impl<'de, T> Deserialize<'de> for Box<T>
-where
- T: Deserialize<'de>,
-{
- fn deserialize<D>(deserializer: D) -> Result<Box<T>, D::Error>
- where
- D: Deserializer<'de>,
- {
- T::deserialize(deserializer).map(Box::new)
- }
-}
+forwarded_impl!((T), Box<T>, Box::new);
-#[cfg(any(feature = "std", feature = "collections"))]
-impl<'de, T> Deserialize<'de> for Box<[T]>
-where
- T: Deserialize<'de>,
-{
- fn deserialize<D>(deserializer: D) -> Result<Box<[T]>, D::Error>
- where
- D: Deserializer<'de>,
- {
- Vec::<T>::deserialize(deserializer).map(Vec::into_boxed_slice)
- }
-}
+#[cfg(any(feature = "std", feature = "alloc"))]
+forwarded_impl!((T), Box<[T]>, Vec::into_boxed_slice);
+
+#[cfg(any(feature = "std", feature = "alloc"))]
+forwarded_impl!((), Box<str>, String::into_boxed_str);
-#[cfg(any(feature = "std", feature = "collections"))]
-impl<'de> Deserialize<'de> for Box<str> {
- fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
- where
- D: Deserializer<'de>,
- {
- String::deserialize(deserializer).map(String::into_boxed_str)
- }
-}
+#[cfg(all(not(feature = "unstable"), feature = "rc", any(feature = "std", feature = "alloc")))]
+forwarded_impl!((T), Arc<T>, Arc::new);
-#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
-impl<'de, T> Deserialize<'de> for Arc<T>
-where
- T: Deserialize<'de>,
-{
- fn deserialize<D>(deserializer: D) -> Result<Arc<T>, D::Error>
- where
- D: Deserializer<'de>,
- {
- T::deserialize(deserializer).map(Arc::new)
- }
-}
+#[cfg(all(not(feature = "unstable"), feature = "rc", any(feature = "std", feature = "alloc")))]
+forwarded_impl!((T), Rc<T>, Rc::new);
-#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
-impl<'de, T> Deserialize<'de> for Rc<T>
-where
- T: Deserialize<'de>,
-{
- fn deserialize<D>(deserializer: D) -> Result<Rc<T>, D::Error>
- where
- D: Deserializer<'de>,
- {
- T::deserialize(deserializer).map(Rc::new)
- }
-}
-
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, T: ?Sized> Deserialize<'de> for Cow<'a, T>
where
T: ToOwned,
T::Owned: Deserialize<'de>,
{
#[inline]
fn deserialize<D>(deserializer: D) -> Result<Cow<'a, T>, D::Error>
where
D: Deserializer<'de>,
{
T::Owned::deserialize(deserializer).map(Cow::Owned)
}
}
////////////////////////////////////////////////////////////////////////////////
+#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
+macro_rules! box_forwarded_impl {
+ ($t:ident) => {
+ impl<'de, T: ?Sized> Deserialize<'de> for $t<T>
+ where
+ Box<T>: Deserialize<'de>,
+ {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Box::deserialize(deserializer).map(Into::into)
+ }
+ }
+ }
+}
+
+#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
+box_forwarded_impl!(Rc);
+
+#[cfg(all(feature = "unstable", feature = "rc", any(feature = "std", feature = "alloc")))]
+box_forwarded_impl!(Arc);
+
+////////////////////////////////////////////////////////////////////////////////
+
impl<'de, T> Deserialize<'de> for Cell<T>
where
T: Deserialize<'de> + Copy,
{
fn deserialize<D>(deserializer: D) -> Result<Cell<T>, D::Error>
where
D: Deserializer<'de>,
{
T::deserialize(deserializer).map(Cell::new)
}
}
-impl<'de, T> Deserialize<'de> for RefCell<T>
-where
- T: Deserialize<'de>,
-{
- fn deserialize<D>(deserializer: D) -> Result<RefCell<T>, D::Error>
- where
- D: Deserializer<'de>,
- {
- T::deserialize(deserializer).map(RefCell::new)
- }
-}
+forwarded_impl!((T), RefCell<T>, RefCell::new);
#[cfg(feature = "std")]
-impl<'de, T> Deserialize<'de> for Mutex<T>
-where
- T: Deserialize<'de>,
-{
- fn deserialize<D>(deserializer: D) -> Result<Mutex<T>, D::Error>
- where
- D: Deserializer<'de>,
- {
- T::deserialize(deserializer).map(Mutex::new)
- }
-}
+forwarded_impl!((T), Mutex<T>, Mutex::new);
#[cfg(feature = "std")]
-impl<'de, T> Deserialize<'de> for RwLock<T>
-where
- T: Deserialize<'de>,
-{
- fn deserialize<D>(deserializer: D) -> Result<RwLock<T>, D::Error>
- where
- D: Deserializer<'de>,
- {
- T::deserialize(deserializer).map(RwLock::new)
- }
-}
+forwarded_impl!((T), RwLock<T>, RwLock::new);
////////////////////////////////////////////////////////////////////////////////
// This is a cleaned-up version of the impl generated by:
//
// #[derive(Deserialize)]
// #[serde(deny_unknown_fields)]
// struct Duration {
@@ -1359,16 +1656,142 @@ impl<'de> Deserialize<'de> for Duration
const FIELDS: &'static [&'static str] = &["secs", "nanos"];
deserializer.deserialize_struct("Duration", FIELDS, DurationVisitor)
}
}
////////////////////////////////////////////////////////////////////////////////
+#[cfg(feature = "std")]
+impl<'de> Deserialize<'de> for SystemTime {
+ fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ // Reuse duration
+ enum Field {
+ Secs,
+ Nanos,
+ };
+
+ impl<'de> Deserialize<'de> for Field {
+ fn deserialize<D>(deserializer: D) -> Result<Field, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ struct FieldVisitor;
+
+ impl<'de> Visitor<'de> for FieldVisitor {
+ type Value = Field;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("`secs_since_epoch` or `nanos_since_epoch`")
+ }
+
+ fn visit_str<E>(self, value: &str) -> Result<Field, E>
+ where
+ E: Error,
+ {
+ match value {
+ "secs_since_epoch" => Ok(Field::Secs),
+ "nanos_since_epoch" => Ok(Field::Nanos),
+ _ => Err(Error::unknown_field(value, FIELDS)),
+ }
+ }
+
+ fn visit_bytes<E>(self, value: &[u8]) -> Result<Field, E>
+ where
+ E: Error,
+ {
+ match value {
+ b"secs_since_epoch" => Ok(Field::Secs),
+ b"nanos_since_epoch" => Ok(Field::Nanos),
+ _ => {
+ let value = String::from_utf8_lossy(value);
+ Err(Error::unknown_field(&value, FIELDS))
+ }
+ }
+ }
+ }
+
+ deserializer.deserialize_identifier(FieldVisitor)
+ }
+ }
+
+ struct DurationVisitor;
+
+ impl<'de> Visitor<'de> for DurationVisitor {
+ type Value = Duration;
+
+ fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ formatter.write_str("struct SystemTime")
+ }
+
+ fn visit_seq<A>(self, mut seq: A) -> Result<Duration, A::Error>
+ where
+ A: SeqAccess<'de>,
+ {
+ let secs: u64 = match try!(seq.next_element()) {
+ Some(value) => value,
+ None => {
+ return Err(Error::invalid_length(0, &self));
+ }
+ };
+ let nanos: u32 = match try!(seq.next_element()) {
+ Some(value) => value,
+ None => {
+ return Err(Error::invalid_length(1, &self));
+ }
+ };
+ Ok(Duration::new(secs, nanos))
+ }
+
+ fn visit_map<A>(self, mut map: A) -> Result<Duration, A::Error>
+ where
+ A: MapAccess<'de>,
+ {
+ let mut secs: Option<u64> = None;
+ let mut nanos: Option<u32> = None;
+ while let Some(key) = try!(map.next_key()) {
+ match key {
+ Field::Secs => {
+ if secs.is_some() {
+ return Err(<A::Error as Error>::duplicate_field("secs_since_epoch"));
+ }
+ secs = Some(try!(map.next_value()));
+ }
+ Field::Nanos => {
+ if nanos.is_some() {
+ return Err(<A::Error as Error>::duplicate_field("nanos_since_epoch"));
+ }
+ nanos = Some(try!(map.next_value()));
+ }
+ }
+ }
+ let secs = match secs {
+ Some(secs) => secs,
+ None => return Err(<A::Error as Error>::missing_field("secs_since_epoch")),
+ };
+ let nanos = match nanos {
+ Some(nanos) => nanos,
+ None => return Err(<A::Error as Error>::missing_field("nanos_since_epoch")),
+ };
+ Ok(Duration::new(secs, nanos))
+ }
+ }
+
+ const FIELDS: &'static [&'static str] = &["secs_since_epoch", "nanos_since_epoch"];
+ let duration = try!(deserializer.deserialize_struct("SystemTime", FIELDS, DurationVisitor));
+ Ok(UNIX_EPOCH + duration)
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
// Similar to:
//
// #[derive(Deserialize)]
// #[serde(deny_unknown_fields)]
// struct Range {
// start: u64,
// end: u32,
// }
@@ -1513,24 +1936,19 @@ impl<'de, T> Deserialize<'de> for NonZer
where
T: Deserialize<'de> + Zeroable,
{
fn deserialize<D>(deserializer: D) -> Result<NonZero<T>, D::Error>
where
D: Deserializer<'de>,
{
let value = try!(Deserialize::deserialize(deserializer));
- unsafe {
- let ptr = &value as *const T as *const u8;
- if slice::from_raw_parts(ptr, mem::size_of::<T>()).iter().all(|&b| b == 0) {
- return Err(Error::custom("expected a non-zero value"));
- }
- // Waiting for a safe way to construct NonZero<T>:
- // https://github.com/rust-lang/rust/issues/27730#issuecomment-269726075
- Ok(NonZero::new(value))
+ match NonZero::new(value) {
+ Some(nonzero) => Ok(nonzero),
+ None => Err(Error::custom("expected a non-zero value")),
}
}
}
////////////////////////////////////////////////////////////////////////////////
impl<'de, T, E> Deserialize<'de> for Result<T, E>
where
@@ -1636,8 +2054,23 @@ where
}
}
const VARIANTS: &'static [&'static str] = &["Ok", "Err"];
deserializer.deserialize_enum("Result", VARIANTS, ResultVisitor(PhantomData))
}
}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+impl<'de, T> Deserialize<'de> for Wrapping<T>
+where
+ T: Deserialize<'de>
+{
+ fn deserialize<D>(deserializer: D) -> Result<Wrapping<T>, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ Deserialize::deserialize(deserializer).map(Wrapping)
+ }
+}
--- a/third_party/rust/serde/src/de/mod.rs
+++ b/third_party/rust/serde/src/de/mod.rs
@@ -89,16 +89,17 @@
//! - &str
//! - &[u8]
//! - **FFI types**:
//! - CString
//! - Box\<CStr\>
//! - OsString
//! - **Miscellaneous standard library types**:
//! - Duration
+//! - SystemTime
//! - Path
//! - PathBuf
//! - Range\<T\>
//! - NonZero\<T\> (unstable)
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
//! - Ipv6Addr
@@ -498,16 +499,45 @@ pub trait Deserialize<'de>: Sized {
///
/// See the [Implementing `Deserialize`][impl-deserialize] section of the
/// manual for more information about how to implement this method.
///
/// [impl-deserialize]: https://serde.rs/impl-deserialize.html
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: Deserializer<'de>;
+
+ /// Deserializes a value into `self` from the given Deserializer.
+ ///
+ /// The purpose of this method is to allow the deserializer to reuse
+ /// resources and avoid copies. As such, if this method returns an error,
+ /// `self` will be in an indeterminate state where some parts of the struct
+ /// have been overwritten. Although whatever state that is will be
+ /// memory-safe.
+ ///
+ /// This is generally useful when repeateadly deserializing values that
+ /// are processed one at a time, where the value of `self` doesn't matter
+ /// when the next deserialization occurs.
+ ///
+ /// If you manually implement this, your recursive deserializations should
+ /// use `deserialize_from`.
+ ///
+ /// TODO: example
+ ///
+ /// ```
+ /// // Something with a loop that returns on error.
+ ///
+ /// ```
+ fn deserialize_from<D>(&mut self, deserializer: D) -> Result<(), D::Error>
+ where D: Deserializer<'de>
+ {
+ // Default implementation just delegates to `deserialize` impl.
+ *self = Deserialize::deserialize(deserializer)?;
+ Ok(())
+ }
}
/// A data structure that can be deserialized without borrowing any data from
/// the deserializer.
///
/// This is primarily useful for trait bounds on functions. For example a
/// `from_str` function may be able to deserialize a data structure that borrows
/// from the input string, but a `from_reader` function may only deserialize
@@ -1005,16 +1035,84 @@ pub trait Deserializer<'de>: Sized {
/// Hint that the `Deserialize` type needs to deserialize a value whose type
/// doesn't matter because it is ignored.
///
/// Deserializers for non-self-describing formats may not support this mode.
fn deserialize_ignored_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
V: Visitor<'de>;
+
+ /// Determine whether `Deserialize` implementations should expect to
+ /// deserialize their human-readable form.
+ ///
+ /// Some types have a human-readable form that may be somewhat expensive to
+ /// construct, as well as a binary form that is compact and efficient.
+ /// Generally text-based formats like JSON and YAML will prefer to use the
+ /// human-readable one and binary formats like Bincode will prefer the
+ /// compact one.
+ ///
+ /// ```
+ /// # use std::ops::Add;
+ /// # use std::str::FromStr;
+ /// #
+ /// # struct Timestamp;
+ /// #
+ /// # impl Timestamp {
+ /// # const EPOCH: Timestamp = Timestamp;
+ /// # }
+ /// #
+ /// # impl FromStr for Timestamp {
+ /// # type Err = String;
+ /// # fn from_str(_: &str) -> Result<Self, Self::Err> {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// # struct Duration;
+ /// #
+ /// # impl Duration {
+ /// # fn seconds(_: u64) -> Self { unimplemented!() }
+ /// # }
+ /// #
+ /// # impl Add<Duration> for Timestamp {
+ /// # type Output = Timestamp;
+ /// # fn add(self, _: Duration) -> Self::Output {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// use serde::de::{self, Deserialize, Deserializer};
+ ///
+ /// impl<'de> Deserialize<'de> for Timestamp {
+ /// fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
+ /// where D: Deserializer<'de>
+ /// {
+ /// if deserializer.is_human_readable() {
+ /// // Deserialize from a human-readable string like "2015-05-15T17:01:00Z".
+ /// let s = String::deserialize(deserializer)?;
+ /// Timestamp::from_str(&s).map_err(de::Error::custom)
+ /// } else {
+ /// // Deserialize from a compact binary representation, seconds since
+ /// // the Unix epoch.
+ /// let n = u64::deserialize(deserializer)?;
+ /// Ok(Timestamp::EPOCH + Duration::seconds(n))
+ /// }
+ /// }
+ /// }
+ /// ```
+ ///
+ /// The default implementation of this method returns `true`. Data formats
+ /// may override this to `false` to request a compact form for types that
+ /// support one. Note that modifying this method to change a format from
+ /// human-readable to compact or vice versa should be regarded as a breaking
+ /// change, as a value serialized in human-readable mode is not required to
+ /// deserialize from the same data in compact mode.
+ #[inline]
+ fn is_human_readable(&self) -> bool { true }
}
////////////////////////////////////////////////////////////////////////////////
/// This trait represents a visitor that walks through a deserializer.
///
/// ```rust
/// # use std::fmt;
@@ -1114,17 +1212,17 @@ pub trait Visitor<'de>: Sized {
/// [`visit_i64`]: #method.visit_i64
fn visit_i32<E>(self, v: i32) -> Result<Self::Value, E>
where
E: Error,
{
self.visit_i64(v as i64)
}
- /// The input contains an `i32`.
+ /// The input contains an `i64`.
///
/// The default implementation fails with a type error.
fn visit_i64<E>(self, v: i64) -> Result<Self::Value, E>
where
E: Error,
{
Err(Error::invalid_type(Unexpected::Signed(v), &self))
}
@@ -1257,17 +1355,17 @@ pub trait Visitor<'de>: Sized {
/// will honor such a request.
///
/// It is never correct to implement `visit_string` without implementing
/// `visit_str`. Implement neither, both, or just `visit_str`.
///
/// The default implementation forwards to `visit_str` and then drops the
/// `String`.
#[inline]
- #[cfg(any(feature = "std", feature = "collections"))]
+ #[cfg(any(feature = "std", feature = "alloc"))]
fn visit_string<E>(self, v: String) -> Result<Self::Value, E>
where
E: Error,
{
self.visit_str(&v)
}
/// The input contains a byte array. The lifetime of the byte array is
@@ -1316,17 +1414,17 @@ pub trait Visitor<'de>: Sized {
/// `Deserializer::deserialize_bytes`, although not every deserializer will
/// honor such a request.
///
/// It is never correct to implement `visit_byte_buf` without implementing
/// `visit_bytes`. Implement neither, both, or just `visit_bytes`.
///
/// The default implementation forwards to `visit_bytes` and then drops the
/// `Vec<u8>`.
- #[cfg(any(feature = "std", feature = "collections"))]
+ #[cfg(any(feature = "std", feature = "alloc"))]
fn visit_byte_buf<E>(self, v: Vec<u8>) -> Result<Self::Value, E>
where
E: Error,
{
self.visit_bytes(&v)
}
/// The input contains an optional that is absent.
@@ -1418,17 +1516,17 @@ pub trait SeqAccess<'de> {
/// The error type that can be returned if some error occurs during
/// deserialization.
type Error: Error;
/// This returns `Ok(Some(value))` for the next value in the sequence, or
/// `Ok(None)` if there are no more remaining items.
///
/// `Deserialize` implementations should typically use
- /// `SeqAcccess::next_element` instead.
+ /// `SeqAccess::next_element` instead.
fn next_element_seed<T>(&mut self, seed: T) -> Result<Option<T::Value>, Self::Error>
where
T: DeserializeSeed<'de>;
/// This returns `Ok(Some(value))` for the next value in the sequence, or
/// `Ok(None)` if there are no more remaining items.
///
/// This method exists as a convenience for `Deserialize` implementations.
--- a/third_party/rust/serde/src/de/value.rs
+++ b/third_party/rust/serde/src/de/value.rs
@@ -46,31 +46,31 @@ use self::private::{First, Second};
/// A minimal representation of all possible errors that can occur using the
/// `IntoDeserializer` trait.
#[derive(Clone, Debug, PartialEq)]
pub struct Error {
err: ErrorImpl,
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
type ErrorImpl = Box<str>;
-#[cfg(not(any(feature = "std", feature = "collections")))]
+#[cfg(not(any(feature = "std", feature = "alloc")))]
type ErrorImpl = ();
impl de::Error for Error {
- #[cfg(any(feature = "std", feature = "collections"))]
+ #[cfg(any(feature = "std", feature = "alloc"))]
fn custom<T>(msg: T) -> Self
where
T: Display,
{
Error { err: msg.to_string().into_boxed_str() }
}
- #[cfg(not(any(feature = "std", feature = "collections")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
fn custom<T>(msg: T) -> Self
where
T: Display,
{
let _ = msg;
Error { err: () }
}
}
@@ -80,22 +80,22 @@ impl ser::Error for Error {
where
T: Display,
{
de::Error::custom(msg)
}
}
impl Display for Error {
- #[cfg(any(feature = "std", feature = "collections"))]
+ #[cfg(any(feature = "std", feature = "alloc"))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str(&self.err)
}
- #[cfg(not(any(feature = "std", feature = "collections")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
fn fmt(&self, formatter: &mut fmt::Formatter) -> Result<(), fmt::Error> {
formatter.write_str("Serde deserialization error")
}
}
#[cfg(feature = "std")]
impl error::Error for Error {
fn description(&self) -> &str {
@@ -420,39 +420,39 @@ where
{
seed.deserialize(self).map(private::unit_only)
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `String`.
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Clone, Debug)]
pub struct StringDeserializer<E> {
value: String,
marker: PhantomData<E>,
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, E> IntoDeserializer<'de, E> for String
where
E: de::Error,
{
type Deserializer = StringDeserializer<E>;
fn into_deserializer(self) -> StringDeserializer<E> {
StringDeserializer {
value: self,
marker: PhantomData,
}
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, E> de::Deserializer<'de> for StringDeserializer<E>
where
E: de::Error,
{
type Error = E;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
@@ -477,17 +477,17 @@ where
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 identifier ignored_any
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> de::EnumAccess<'de> for StringDeserializer<E>
where
E: de::Error,
{
type Error = E;
type Variant = private::UnitOnly<E>;
fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
@@ -496,39 +496,39 @@ where
{
seed.deserialize(self).map(private::unit_only)
}
}
////////////////////////////////////////////////////////////////////////////////
/// A deserializer holding a `Cow<str>`.
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
#[derive(Clone, Debug)]
pub struct CowStrDeserializer<'a, E> {
value: Cow<'a, str>,
marker: PhantomData<E>,
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> IntoDeserializer<'de, E> for Cow<'a, str>
where
E: de::Error,
{
type Deserializer = CowStrDeserializer<'a, E>;
fn into_deserializer(self) -> CowStrDeserializer<'a, E> {
CowStrDeserializer {
value: self,
marker: PhantomData,
}
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> de::Deserializer<'de> for CowStrDeserializer<'a, E>
where
E: de::Error,
{
type Error = E;
fn deserialize_any<V>(self, visitor: V) -> Result<V::Value, Self::Error>
where
@@ -556,17 +556,17 @@ where
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 identifier ignored_any
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, 'a, E> de::EnumAccess<'de> for CowStrDeserializer<'a, E>
where
E: de::Error,
{
type Error = E;
type Variant = private::UnitOnly<E>;
fn variant_seed<T>(self, seed: T) -> Result<(T::Value, Self::Variant), Self::Error>
@@ -722,49 +722,50 @@ impl Expected for ExpectedInSeq {
} else {
write!(formatter, "{} elements in sequence", self.0)
}
}
}
////////////////////////////////////////////////////////////////////////////////
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, T, E> IntoDeserializer<'de, E> for Vec<T>
where
T: IntoDeserializer<'de, E>,
E: de::Error,
{
- type Deserializer = SeqDeserializer<<Vec<T> as IntoIterator>::IntoIter, E>;
+ type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>;
fn into_deserializer(self) -> Self::Deserializer {
SeqDeserializer::new(self.into_iter())
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, T, E> IntoDeserializer<'de, E> for BTreeSet<T>
where
T: IntoDeserializer<'de, E> + Eq + Ord,
E: de::Error,
{
- type Deserializer = SeqDeserializer<<BTreeSet<T> as IntoIterator>::IntoIter, E>;
+ type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>;
fn into_deserializer(self) -> Self::Deserializer {
SeqDeserializer::new(self.into_iter())
}
}
#[cfg(feature = "std")]
-impl<'de, T, E> IntoDeserializer<'de, E> for HashSet<T>
+impl<'de, T, S, E> IntoDeserializer<'de, E> for HashSet<T, S>
where
T: IntoDeserializer<'de, E> + Eq + Hash,
+ S: BuildHasher,
E: de::Error,
{
- type Deserializer = SeqDeserializer<<HashSet<T> as IntoIterator>::IntoIter, E>;
+ type Deserializer = SeqDeserializer<<Self as IntoIterator>::IntoIter, E>;
fn into_deserializer(self) -> Self::Deserializer {
SeqDeserializer::new(self.into_iter())
}
}
////////////////////////////////////////////////////////////////////////////////
@@ -1140,38 +1141,39 @@ impl Expected for ExpectedInMap {
} else {
write!(formatter, "{} elements in map", self.0)
}
}
}
////////////////////////////////////////////////////////////////////////////////
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl<'de, K, V, E> IntoDeserializer<'de, E> for BTreeMap<K, V>
where
K: IntoDeserializer<'de, E> + Eq + Ord,
V: IntoDeserializer<'de, E>,
E: de::Error,
{
- type Deserializer = MapDeserializer<'de, <BTreeMap<K, V> as IntoIterator>::IntoIter, E>;
+ type Deserializer = MapDeserializer<'de, <Self as IntoIterator>::IntoIter, E>;
fn into_deserializer(self) -> Self::Deserializer {
MapDeserializer::new(self.into_iter())
}
}
#[cfg(feature = "std")]
-impl<'de, K, V, E> IntoDeserializer<'de, E> for HashMap<K, V>
+impl<'de, K, V, S, E> IntoDeserializer<'de, E> for HashMap<K, V, S>
where
K: IntoDeserializer<'de, E> + Eq + Hash,
V: IntoDeserializer<'de, E>,
+ S: BuildHasher,
E: de::Error,
{
- type Deserializer = MapDeserializer<'de, <HashMap<K, V> as IntoIterator>::IntoIter, E>;
+ type Deserializer = MapDeserializer<'de, <Self as IntoIterator>::IntoIter, E>;
fn into_deserializer(self) -> Self::Deserializer {
MapDeserializer::new(self.into_iter())
}
}
////////////////////////////////////////////////////////////////////////////////
--- a/third_party/rust/serde/src/export.rs
+++ b/third_party/rust/serde/src/export.rs
@@ -14,28 +14,28 @@ 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"))]
+ #[cfg(any(feature = "std", feature = "alloc"))]
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")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
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}")
}
}
--- a/third_party/rust/serde/src/lib.rs
+++ b/third_party/rust/serde/src/lib.rs
@@ -74,53 +74,77 @@
//! [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
////////////////////////////////////////////////////////////////////////////////
// Serde types in rustdoc of other crates get linked to here.
-#![doc(html_root_url = "https://docs.rs/serde/1.0.8")]
+#![doc(html_root_url = "https://docs.rs/serde/1.0.23")]
// Support using Serde without the standard library!
#![cfg_attr(not(feature = "std"), no_std)]
// 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))]
-// 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))]
+#![cfg_attr(feature = "cargo-clippy", deny(clippy, clippy_pedantic))]
+// Whitelisted clippy lints
+#![cfg_attr(feature = "cargo-clippy", allow(
+ cast_lossless,
+ const_static_lifetime,
+ doc_markdown,
+ linkedlist,
+ needless_pass_by_value,
+ type_complexity,
+ unreadable_literal,
+ zero_prefixed_literal,
+))]
+// Whitelisted clippy_pedantic lints
+#![cfg_attr(feature = "cargo-clippy", allow(
+// integer and float ser/de requires these sorts of casts
+ cast_possible_truncation,
+ cast_possible_wrap,
+ cast_precision_loss,
+ cast_sign_loss,
+// simplifies some macros
+ invalid_upcast_comparisons,
+// things are often more readable this way
+ option_unwrap_used,
+ result_unwrap_used,
+ shadow_reuse,
+ single_match_else,
+ stutter,
+ use_self,
+// not practical
+ missing_docs_in_private_items,
+// alternative is not stable
+ empty_enum,
+ use_debug,
+))]
// Blacklisted Rust lints.
#![deny(missing_docs, unused_imports)]
////////////////////////////////////////////////////////////////////////////////
-#[cfg(feature = "collections")]
-extern crate collections;
-
#[cfg(feature = "alloc")]
extern crate alloc;
#[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.
+/// A facade around all the types we need from the `std`, `core`, and `alloc`
+/// 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::*;
}
@@ -135,28 +159,28 @@ mod lib {
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(all(feature = "alloc", not(feature = "std")))]
+ pub use alloc::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(all(feature = "alloc", not(feature = "std")))]
+ pub use alloc::string::{String, ToString};
#[cfg(feature = "std")]
pub use std::vec::Vec;
- #[cfg(all(feature = "collections", not(feature = "std")))]
- pub use collections::vec::Vec;
+ #[cfg(all(feature = "alloc", not(feature = "std")))]
+ pub use alloc::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;
@@ -165,34 +189,36 @@ mod lib {
#[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(all(feature = "alloc", not(feature = "std")))]
+ pub use alloc::{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::num::Wrapping;
+ #[cfg(feature = "std")]
pub use std::path::{Path, PathBuf};
#[cfg(feature = "std")]
- pub use std::time::Duration;
+ pub use std::time::{Duration, SystemTime, UNIX_EPOCH};
#[cfg(feature = "std")]
pub use std::sync::{Mutex, RwLock};
#[cfg(feature = "unstable")]
pub use core::nonzero::{NonZero, Zeroable};
}
////////////////////////////////////////////////////////////////////////////////
--- a/third_party/rust/serde/src/private/de.rs
+++ b/third_party/rust/serde/src/private/de.rs
@@ -3,22 +3,22 @@
// 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, IntoDeserializer, Error, Visitor};
+use de::{Deserialize, Deserializer, DeserializeSeed, IntoDeserializer, Error, Visitor};
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
use de::Unexpected;
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
pub use self::content::{Content, ContentRefDeserializer, ContentDeserializer,
TaggedContentVisitor, TagOrContentField, TagOrContentFieldVisitor,
TagContentOtherField, TagContentOtherFieldVisitor,
InternallyTaggedUnitVisitor, UntaggedUnitVisitor};
/// If the missing field is of type `Option<T>` then treat is as `None`,
/// otherwise it is an error.
pub fn missing_field<'de, V, E>(field: &'static str) -> Result<V, E>
@@ -54,17 +54,17 @@ where
struct enum identifier ignored_any
}
}
let deserializer = MissingFieldDeserializer(field, PhantomData);
Deserialize::deserialize(deserializer)
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
pub fn borrow_cow_str<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, str>, D::Error>
where
D: Deserializer<'de>,
{
struct CowStrVisitor;
impl<'a> Visitor<'a> for CowStrVisitor {
type Value = Cow<'a, str>;
@@ -123,17 +123,17 @@ where
Err(e) => Err(Error::invalid_value(Unexpected::Bytes(&e.into_bytes()), &self),),
}
}
}
deserializer.deserialize_str(CowStrVisitor)
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
pub fn borrow_cow_bytes<'de: 'a, 'a, D>(deserializer: D) -> Result<Cow<'a, [u8]>, D::Error>
where
D: Deserializer<'de>,
{
struct CowBytesVisitor;
impl<'a> Visitor<'a> for CowBytesVisitor {
type Value = Cow<'a, [u8]>;
@@ -193,29 +193,30 @@ pub mod size_hint {
pub fn from_bounds<I>(iter: &I) -> Option<usize>
where
I: Iterator,
{
helper(iter.size_hint())
}
+ #[inline]
pub fn cautious(hint: Option<usize>) -> usize {
cmp::min(hint.unwrap_or(0), 4096)
}
fn helper(bounds: (usize, Option<usize>)) -> Option<usize> {
match bounds {
(lower, Some(upper)) if lower == upper => Some(upper),
_ => None,
}
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
mod content {
// This module is private and nothing here should be used outside of
// generated code.
//
// We will iterate on the implementation for a few releases and only have to
// worry about backward compatibility for the `untagged` and `tag` attributes
// rather than for this entire mechanism.
//
@@ -829,36 +830,53 @@ mod content {
impl<'de, T> Visitor<'de> for TaggedContentVisitor<'de, T>
where
T: Deserialize<'de>,
{
type Value = TaggedContent<'de, T>;
fn expecting(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
- fmt.write_str("any value")
+ fmt.write_str("internally tagged enum")
}
- fn visit_map<V>(self, mut visitor: V) -> Result<Self::Value, V::Error>
+ fn visit_seq<S>(self, mut seq: S) -> Result<Self::Value, S::Error>
where
- V: MapAccess<'de>,
+ S: SeqAccess<'de>,
+ {
+ let tag = match try!(seq.next_element()) {
+ Some(tag) => tag,
+ None => {
+ return Err(de::Error::missing_field(self.tag_name));
+ }
+ };
+ let rest = de::value::SeqAccessDeserializer::new(seq);
+ Ok(TaggedContent {
+ tag: tag,
+ content: try!(Content::deserialize(rest)),
+ })
+ }
+
+ fn visit_map<M>(self, mut map: M) -> Result<Self::Value, M::Error>
+ where
+ M: MapAccess<'de>,
{
let mut tag = None;
- let mut vec = Vec::with_capacity(size_hint::cautious(visitor.size_hint()));
+ let mut vec = Vec::with_capacity(size_hint::cautious(map.size_hint()));
while let Some(k) =
- try!(visitor.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
+ try!(map.next_key_seed(TagOrContentVisitor::new(self.tag_name))) {
match k {
TagOrContent::Tag => {
if tag.is_some() {
return Err(de::Error::duplicate_field(self.tag_name));
}
- tag = Some(try!(visitor.next_value()));
+ tag = Some(try!(map.next_value()));
}
TagOrContent::Content(k) => {
- let v = try!(visitor.next_value());
+ let v = try!(map.next_value());
vec.push((k, v));
}
}
}
match tag {
None => Err(de::Error::missing_field(self.tag_name)),
Some(tag) => {
Ok(
@@ -1092,20 +1110,48 @@ mod content {
EnumDeserializer {
variant: variant,
value: value,
err: PhantomData,
},
)
}
+ fn deserialize_unit_struct<V>(
+ self,
+ _name: &'static str,
+ visitor: V
+ ) -> Result<V::Value, Self::Error>
+ where
+ V: Visitor<'de>,
+ {
+ match self.content {
+ // As a special case, allow deserializing untagged newtype
+ // variant containing unit struct.
+ //
+ // #[derive(Deserialize)]
+ // struct Info;
+ //
+ // #[derive(Deserialize)]
+ // #[serde(tag = "topic")]
+ // enum Message {
+ // Info(Info),
+ // }
+ //
+ // We want {"topic":"Info"} to deserialize even though
+ // ordinarily unit structs do not deserialize from empty map.
+ Content::Map(ref v) if v.is_empty() => visitor.visit_unit(),
+ _ => self.deserialize_any(visitor),
+ }
+ }
+
forward_to_deserialize_any! {
bool i8 i16 i32 i64 u8 u16 u32 u64 f32 f64 char str string bytes
- byte_buf unit unit_struct seq tuple tuple_struct map struct
- identifier ignored_any
+ byte_buf unit seq tuple tuple_struct map struct identifier
+ ignored_any
}
}
impl<'de, E> ContentDeserializer<'de, E> {
/// private API, don't use
pub fn new(content: Content<'de>) -> Self {
ContentDeserializer {
content: content,
@@ -1196,16 +1242,19 @@ mod content {
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
match self.value {
Some(Content::Map(v)) => {
de::Deserializer::deserialize_any(MapDeserializer::new(v), visitor)
}
+ Some(Content::Seq(v)) => {
+ de::Deserializer::deserialize_any(SeqDeserializer::new(v), visitor)
+ }
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),),
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),),
}
}
}
struct SeqDeserializer<'de, E>
where
@@ -1590,16 +1639,19 @@ mod content {
) -> Result<V::Value, Self::Error>
where
V: de::Visitor<'de>,
{
match self.value {
Some(&Content::Map(ref v)) => {
de::Deserializer::deserialize_any(MapRefDeserializer::new(v), visitor)
}
+ Some(&Content::Seq(ref v)) => {
+ de::Deserializer::deserialize_any(SeqRefDeserializer::new(v), visitor)
+ }
Some(other) => Err(de::Error::invalid_type(other.unexpected(), &"struct variant"),),
_ => Err(de::Error::invalid_type(de::Unexpected::UnitVariant, &"struct variant"),),
}
}
}
struct SeqRefDeserializer<'a, 'de: 'a, E>
where
@@ -1797,19 +1849,26 @@ mod content {
impl<'de, 'a> Visitor<'de> for InternallyTaggedUnitVisitor<'a> {
type Value = ();
fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
write!(formatter, "unit variant {}::{}", self.type_name, self.variant_name)
}
- fn visit_map<V>(self, _: V) -> Result<(), V::Error>
+ fn visit_seq<S>(self, _: S) -> Result<(), S::Error>
where
- V: MapAccess<'de>,
+ S: SeqAccess<'de>,
+ {
+ Ok(())
+ }
+
+ fn visit_map<M>(self, _: M) -> Result<(), M::Error>
+ where
+ M: MapAccess<'de>,
{
Ok(())
}
}
/// Visitor for deserializing an untagged unit variant.
///
/// Not public API.
@@ -1945,8 +2004,25 @@ where
}
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
}
}
+
+/// A DeserializeSeed helper for implementing deserialize_from Visitors.
+///
+/// Wraps a mutable reference and calls deserialize_from on it.
+pub struct DeserializeFromSeed<'a, T: 'a>(pub &'a mut T);
+
+impl<'a, 'de, T> DeserializeSeed<'de> for DeserializeFromSeed<'a, T>
+ where T: Deserialize<'de>,
+{
+ type Value = ();
+ fn deserialize<D>(self, deserializer: D) -> Result<Self::Value, D::Error>
+ where
+ D: Deserializer<'de>,
+ {
+ self.0.deserialize_from(deserializer)
+ }
+}
--- a/third_party/rust/serde/src/private/ser.rs
+++ b/third_party/rust/serde/src/private/ser.rs
@@ -5,17 +5,17 @@
// <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 ser::{self, Serialize, Serializer, SerializeMap, SerializeStruct, Impossible};
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
use self::content::{SerializeTupleVariantAsMapValue, SerializeStructVariantAsMapValue};
/// Used to check that serde(getter) attributes return the expected type.
/// Not public API.
pub fn constrain<T: ?Sized>(t: &T) -> &T {
t
}
@@ -55,40 +55,38 @@ enum Unsupported {
Boolean,
Integer,
Float,
Char,
String,
ByteArray,
Optional,
Unit,
- UnitStruct,
Sequence,
Tuple,
TupleStruct,
- #[cfg(not(any(feature = "std", feature = "collections")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
Enum,
}
impl Display for Unsupported {
fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
match *self {
Unsupported::Boolean => formatter.write_str("a boolean"),
Unsupported::Integer => formatter.write_str("an integer"),
Unsupported::Float => formatter.write_str("a float"),
Unsupported::Char => formatter.write_str("a char"),
Unsupported::String => formatter.write_str("a string"),
Unsupported::ByteArray => formatter.write_str("a byte array"),
Unsupported::Optional => formatter.write_str("an optional"),
Unsupported::Unit => formatter.write_str("unit"),
- Unsupported::UnitStruct => formatter.write_str("a unit struct"),
Unsupported::Sequence => formatter.write_str("a sequence"),
Unsupported::Tuple => formatter.write_str("a tuple"),
Unsupported::TupleStruct => formatter.write_str("a tuple struct"),
- #[cfg(not(any(feature = "std", feature = "collections")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
Unsupported::Enum => formatter.write_str("an enum"),
}
}
}
impl<S> TaggedSerializer<S>
where
S: Serializer,
@@ -112,24 +110,24 @@ where
type Error = S::Error;
type SerializeSeq = Impossible<S::Ok, S::Error>;
type SerializeTuple = Impossible<S::Ok, S::Error>;
type SerializeTupleStruct = Impossible<S::Ok, S::Error>;
type SerializeMap = S::SerializeMap;
type SerializeStruct = S::SerializeStruct;
- #[cfg(not(any(feature = "std", feature = "collections")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
type SerializeTupleVariant = Impossible<S::Ok, S::Error>;
- #[cfg(any(feature = "std", feature = "collections"))]
+ #[cfg(any(feature = "std", feature = "alloc"))]
type SerializeTupleVariant = SerializeTupleVariantAsMapValue<S::SerializeMap>;
- #[cfg(not(any(feature = "std", feature = "collections")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
type SerializeStructVariant = Impossible<S::Ok, S::Error>;
- #[cfg(any(feature = "std", feature = "collections"))]
+ #[cfg(any(feature = "std", feature = "alloc"))]
type SerializeStructVariant = SerializeStructVariantAsMapValue<S::SerializeMap>;
fn serialize_bool(self, _: bool) -> Result<Self::Ok, Self::Error> {
Err(self.bad_type(Unsupported::Boolean))
}
fn serialize_i8(self, _: i8) -> Result<Self::Ok, Self::Error> {
Err(self.bad_type(Unsupported::Integer))
@@ -194,17 +192,19 @@ where
Err(self.bad_type(Unsupported::Optional))
}
fn serialize_unit(self) -> Result<Self::Ok, Self::Error> {
Err(self.bad_type(Unsupported::Unit))
}
fn serialize_unit_struct(self, _: &'static str) -> Result<Self::Ok, Self::Error> {
- Err(self.bad_type(Unsupported::UnitStruct))
+ let mut map = try!(self.delegate.serialize_map(Some(1)));
+ try!(map.serialize_entry(self.tag, self.variant_name));
+ map.end()
}
fn serialize_unit_variant(
self,
_: &'static str,
_: u32,
inner_variant: &'static str,
) -> Result<Self::Ok, Self::Error> {
@@ -252,30 +252,30 @@ where
fn serialize_tuple_struct(
self,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleStruct, Self::Error> {
Err(self.bad_type(Unsupported::TupleStruct))
}
- #[cfg(not(any(feature = "std", feature = "collections")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
// Lack of push-based serialization means we need to buffer the content
// of the tuple variant, so it requires std.
Err(self.bad_type(Unsupported::Enum))
}
- #[cfg(any(feature = "std", feature = "collections"))]
+ #[cfg(any(feature = "std", feature = "alloc"))]
fn serialize_tuple_variant(
self,
_: &'static str,
_: u32,
inner_variant: &'static str,
len: usize,
) -> Result<Self::SerializeTupleVariant, Self::Error> {
let mut map = try!(self.delegate.serialize_map(Some(2)));
@@ -295,44 +295,44 @@ where
name: &'static str,
len: usize,
) -> Result<Self::SerializeStruct, Self::Error> {
let mut state = try!(self.delegate.serialize_struct(name, len + 1));
try!(state.serialize_field(self.tag, self.variant_name));
Ok(state)
}
- #[cfg(not(any(feature = "std", feature = "collections")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
_: &'static str,
_: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
// Lack of push-based serialization means we need to buffer the content
// of the struct variant, so it requires std.
Err(self.bad_type(Unsupported::Enum))
}
- #[cfg(any(feature = "std", feature = "collections"))]
+ #[cfg(any(feature = "std", feature = "alloc"))]
fn serialize_struct_variant(
self,
_: &'static str,
_: u32,
inner_variant: &'static str,
len: usize,
) -> Result<Self::SerializeStructVariant, Self::Error> {
let mut map = try!(self.delegate.serialize_map(Some(2)));
try!(map.serialize_entry(self.tag, self.variant_name));
try!(map.serialize_key(inner_variant));
Ok(SerializeStructVariantAsMapValue::new(map, inner_variant, len),)
}
- #[cfg(not(any(feature = "std", feature = "collections")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
fn collect_str<T: ?Sized>(self, _: &T) -> Result<Self::Ok, Self::Error>
where
T: Display,
{
Err(self.bad_type(Unsupported::String))
}
}
@@ -358,17 +358,17 @@ impl error::Error for Error {
}
impl Display for Error {
fn fmt(&self, _: &mut fmt::Formatter) -> fmt::Result {
unimplemented!()
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
mod content {
use lib::*;
use ser::{self, Serialize, Serializer};
pub struct SerializeTupleVariantAsMapValue<M> {
map: M,
name: &'static str,
--- a/third_party/rust/serde/src/ser/impls.rs
+++ b/third_party/rust/serde/src/ser/impls.rs
@@ -51,17 +51,17 @@ impl Serialize for str {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self)
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
impl Serialize for String {
#[inline]
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.serialize_str(self)
}
@@ -172,16 +172,17 @@ where
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
serializer.collect_seq(self)
}
}
+#[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! seq_impl {
($ty:ident < T $(: $tbound1:ident $(+ $tbound2:ident)*)* $(, $typaram:ident : $bound:ident)* >) => {
impl<T $(, $typaram)*> Serialize for $ty<T $(, $typaram)*>
where
T: Serialize $(+ $tbound1 $(+ $tbound2)*)*,
$($typaram: $bound,)*
{
#[inline]
@@ -190,32 +191,32 @@ macro_rules! seq_impl {
S: Serializer,
{
serializer.collect_seq(self)
}
}
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(BinaryHeap<T: Ord>);
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(BTreeSet<T: Ord>);
#[cfg(feature = "std")]
seq_impl!(HashSet<T: Eq + Hash, H: BuildHasher>);
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(LinkedList<T>);
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(Vec<T>);
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
seq_impl!(VecDeque<T>);
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl<Idx> Serialize for ops::Range<Idx>
where
Idx: Serialize,
@@ -285,16 +286,17 @@ tuple_impls! {
13 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12)
14 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13)
15 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14)
16 => (0 T0 1 T1 2 T2 3 T3 4 T4 5 T5 6 T6 7 T7 8 T8 9 T9 10 T10 11 T11 12 T12 13 T13 14 T14 15 T15)
}
////////////////////////////////////////////////////////////////////////////////
+#[cfg(any(feature = "std", feature = "alloc"))]
macro_rules! map_impl {
($ty:ident < K $(: $kbound1:ident $(+ $kbound2:ident)*)*, V $(, $typaram:ident : $bound:ident)* >) => {
impl<K, V $(, $typaram)*> Serialize for $ty<K, V $(, $typaram)*>
where
K: Serialize $(+ $kbound1 $(+ $kbound2)*)*,
V: Serialize,
$($typaram: $bound,)*
{
@@ -304,17 +306,17 @@ macro_rules! map_impl {
S: Serializer,
{
serializer.collect_map(self)
}
}
}
}
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
map_impl!(BTreeMap<K: Ord, V>);
#[cfg(feature = "std")]
map_impl!(HashMap<K: Eq + Hash, V, H: BuildHasher>);
////////////////////////////////////////////////////////////////////////////////
macro_rules! deref_impl {
@@ -333,22 +335,22 @@ macro_rules! deref_impl {
deref_impl!(<'a, T: ?Sized> Serialize for &'a T where T: Serialize);
deref_impl!(<'a, T: ?Sized> Serialize for &'a mut T where T: Serialize);
#[cfg(any(feature = "std", feature = "alloc"))]
deref_impl!(<T: ?Sized> Serialize for Box<T> where T: Serialize);
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
-deref_impl!(<T> Serialize for Rc<T> where T: Serialize);
+deref_impl!(<T: ?Sized> Serialize for Rc<T> where T: Serialize);
#[cfg(all(feature = "rc", any(feature = "std", feature = "alloc")))]
-deref_impl!(<T> Serialize for Arc<T> where T: Serialize);
+deref_impl!(<T: ?Sized> Serialize for Arc<T> where T: Serialize);
-#[cfg(any(feature = "std", feature = "collections"))]
+#[cfg(any(feature = "std", feature = "alloc"))]
deref_impl!(<'a, T: ?Sized> Serialize for Cow<'a, T> where T: Serialize + ToOwned);
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "unstable")]
impl<T> Serialize for NonZero<T>
where
T: Serialize + Zeroable + Clone,
@@ -450,16 +452,33 @@ impl Serialize for Duration {
try!(state.serialize_field("secs", &self.as_secs()));
try!(state.serialize_field("nanos", &self.subsec_nanos()));
state.end()
}
}
////////////////////////////////////////////////////////////////////////////////
+#[cfg(feature = "std")]
+impl Serialize for SystemTime {
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ use super::SerializeStruct;
+ let duration_since_epoch = self.duration_since(UNIX_EPOCH).expect("SystemTime must be later than UNIX_EPOCH");
+ let mut state = try!(serializer.serialize_struct("SystemTime", 2));
+ try!(state.serialize_field("secs_since_epoch", &duration_since_epoch.as_secs()));
+ try!(state.serialize_field("nanos_since_epoch", &duration_since_epoch.subsec_nanos()));
+ state.end()
+ }
+}
+
+////////////////////////////////////////////////////////////////////////////////
+
/// Serialize a 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")]
macro_rules! serialize_display_bounded_length {
($value:expr, $max:expr, $serializer:expr) => {{
let mut buffer: [u8; $max] = unsafe { mem::uninitialized() };
@@ -482,81 +501,115 @@ macro_rules! serialize_display_bounded_l
}
#[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),
+ if serializer.is_human_readable() {
+ match *self {
+ net::IpAddr::V4(ref a) => a.serialize(serializer),
+ net::IpAddr::V6(ref a) => a.serialize(serializer),
+ }
+ } else {
+ match *self {
+ net::IpAddr::V4(ref a) =>
+ serializer.serialize_newtype_variant("IpAddr", 0, "V4", a),
+ net::IpAddr::V6(ref a) =>
+ serializer.serialize_newtype_variant("IpAddr", 1, "V6", a),
+ }
}
}
}
#[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)
+ if serializer.is_human_readable() {
+ const MAX_LEN: usize = 15;
+ debug_assert_eq!(MAX_LEN, "101.102.103.104".len());
+ serialize_display_bounded_length!(self, MAX_LEN, serializer)
+ } else {
+ self.octets().serialize(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)
+ if serializer.is_human_readable() {
+ const MAX_LEN: usize = 39;
+ debug_assert_eq!(MAX_LEN, "1001:1002:1003:1004:1005:1006:1007:1008".len());
+ serialize_display_bounded_length!(self, MAX_LEN, serializer)
+ } else {
+ self.octets().serialize(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),
+ if serializer.is_human_readable() {
+ match *self {
+ net::SocketAddr::V4(ref addr) => addr.serialize(serializer),
+ net::SocketAddr::V6(ref addr) => addr.serialize(serializer),
+ }
+ } else {
+ match *self {
+ net::SocketAddr::V4(ref addr) =>
+ serializer.serialize_newtype_variant("SocketAddr", 0, "V4", addr),
+ net::SocketAddr::V6(ref addr) =>
+ serializer.serialize_newtype_variant("SocketAddr", 1, "V6", addr),
+ }
}
}
}
#[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)
+ if serializer.is_human_readable() {
+ const MAX_LEN: usize = 21;
+ debug_assert_eq!(MAX_LEN, "101.102.103.104:65000".len());
+ serialize_display_bounded_length!(self, MAX_LEN, serializer)
+ } else {
+ (self.ip(), self.port()).serialize(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)
+ if serializer.is_human_readable() {
+ const MAX_LEN: usize = 47;
+ debug_assert_eq!(MAX_LEN, "[1001:1002:1003:1004:1005:1006:1007:1008]:65000".len());
+ serialize_display_bounded_length!(self, MAX_LEN, serializer)
+ } else {
+ (self.ip(), self.port()).serialize(serializer)
+ }
}
}
////////////////////////////////////////////////////////////////////////////////
#[cfg(feature = "std")]
impl Serialize for Path {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
@@ -606,8 +659,24 @@ impl Serialize for OsStr {
impl Serialize for OsString {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: Serializer,
{
self.as_os_str().serialize(serializer)
}
}
+
+////////////////////////////////////////////////////////////////////////////////
+
+#[cfg(feature = "std")]
+impl<T> Serialize for Wrapping<T>
+where
+ T: Serialize,
+{
+ #[inline]
+ fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ where
+ S: Serializer,
+ {
+ self.0.serialize(serializer)
+ }
+}
--- a/third_party/rust/serde/src/ser/mod.rs
+++ b/third_party/rust/serde/src/ser/mod.rs
@@ -84,16 +84,17 @@
//! - EnumSet\<T\> (unstable)
//! - **FFI types**:
//! - CStr
//! - CString
//! - OsStr
//! - OsString
//! - **Miscellaneous standard library types**:
//! - Duration
+//! - SystemTime
//! - Path
//! - PathBuf
//! - Range\<T\>
//! - NonZero\<T\> (unstable)
//! - **Net types**:
//! - IpAddr
//! - Ipv4Addr
//! - Ipv6Addr
@@ -1316,17 +1317,17 @@ pub trait Serializer: Sized {
/// self.naive_local(),
/// self.offset()))
/// }
/// }
/// ```
///
/// [`String`]: https://doc.rust-lang.org/std/string/struct.String.html
/// [`serialize_str`]: #tymethod.serialize_str
- #[cfg(any(feature = "std", feature = "collections"))]
+ #[cfg(any(feature = "std", feature = "alloc"))]
fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Display,
{
use lib::fmt::Write;
let mut string = String::new();
write!(string, "{}", value).unwrap();
self.serialize_str(&string)
@@ -1353,20 +1354,70 @@ pub trait Serializer: Sized {
/// where S: Serializer
/// {
/// serializer.collect_str(&format_args!("{:?}{:?}",
/// self.naive_local(),
/// self.offset()))
/// }
/// }
/// ```
- #[cfg(not(any(feature = "std", feature = "collections")))]
+ #[cfg(not(any(feature = "std", feature = "alloc")))]
fn collect_str<T: ?Sized>(self, value: &T) -> Result<Self::Ok, Self::Error>
where
T: Display;
+
+ /// Determine whether `Serialize` implementations should serialize in
+ /// human-readable form.
+ ///
+ /// Some types have a human-readable form that may be somewhat expensive to
+ /// construct, as well as a binary form that is compact and efficient.
+ /// Generally text-based formats like JSON and YAML will prefer to use the
+ /// human-readable one and binary formats like Bincode will prefer the
+ /// compact one.
+ ///
+ /// ```
+ /// # use std::fmt::{self, Display};
+ /// #
+ /// # struct Timestamp;
+ /// #
+ /// # impl Timestamp {
+ /// # fn seconds_since_epoch(&self) -> u64 { unimplemented!() }
+ /// # }
+ /// #
+ /// # impl Display for Timestamp {
+ /// # fn fmt(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
+ /// # unimplemented!()
+ /// # }
+ /// # }
+ /// #
+ /// use serde::{Serialize, Serializer};
+ ///
+ /// impl Serialize for Timestamp {
+ /// fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
+ /// where S: Serializer
+ /// {
+ /// if serializer.is_human_readable() {
+ /// // Serialize to a human-readable string "2015-05-15T17:01:00Z".
+ /// self.to_string().serialize(serializer)
+ /// } else {
+ /// // Serialize to a compact binary representation.
+ /// self.seconds_since_epoch().serialize(serializer)
+ /// }
+ /// }
+ /// }
+ /// ```
+ ///
+ /// The default implementation of this method returns `true`. Data formats
+ /// may override this to `false` to request a compact form for types that
+ /// support one. Note that modifying this method to change a format from
+ /// human-readable to compact or vice versa should be regarded as a breaking
+ /// change, as a value serialized in human-readable mode is not required to
+ /// deserialize from the same data in compact mode.
+ #[inline]
+ fn is_human_readable(&self) -> bool { true }
}
/// Returned from `Serializer::serialize_seq`.
///
/// ```rust
/// # use std::marker::PhantomData;
/// #
/// # struct Vec<T>(PhantomData<T>);
@@ -1721,16 +1772,23 @@ pub trait SerializeStruct {
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize;
+ /// Indicate that a struct field has been skipped.
+ #[inline]
+ fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
+ let _ = key;
+ Ok(())
+ }
+
/// Finish serializing a struct.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
/// Returned from `Serializer::serialize_struct_variant`.
///
/// ```rust
/// use serde::ser::{Serialize, Serializer, SerializeStructVariant};
@@ -1766,16 +1824,23 @@ pub trait SerializeStructVariant {
fn serialize_field<T: ?Sized>(
&mut self,
key: &'static str,
value: &T,
) -> Result<(), Self::Error>
where
T: Serialize;
+ /// Indicate that a struct variant field has been skipped.
+ #[inline]
+ fn skip_field(&mut self, key: &'static str) -> Result<(), Self::Error> {
+ let _ = key;
+ Ok(())
+ }
+
/// Finish serializing a struct variant.
fn end(self) -> Result<Self::Ok, Self::Error>;
}
trait LenHint: Iterator {
fn len_hint(&self) -> Option<usize>;
}
--- a/third_party/rust/serde_derive/.cargo-checksum.json
+++ b/third_party/rust/serde_derive/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"fc1c90305d1d8d6debda370913068486b2465b4ac548651f9122169def6da94c","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"eedee04bddb61e99bc816656bb3b8ae2fa50ff00045ecdb5212682f3592d9ab2","src/bound.rs":"c01b1ec82b830b01a840d27654f2b1d3354e62a2b404227fccbb84d80cc6a593","src/de.rs":"518d74b38a7c254383fa6b2e5bfd71137e3abfbeda8b2577d25b7d8acdb03df5","src/fragment.rs":"f1642a1c2abbc36191206a5ec8077e314bdc20a420d7649e4bec3a69d555f78d","src/lib.rs":"fda8bd7ae031370f004d2672c12bfb9a5ae4314f499b5c7cbf9947e810d1d255","src/ser.rs":"b573af63ecfc51849b1157e2c3ae55b3bc256c3ce4b2712a639c5750e42eddfa"},"package":"10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3"}
\ No newline at end of file
+{"files":{"Cargo.toml":"972517c9f00568bfc6806f09dad62aa94ed9f86afe35b4ab0e8d30f1600a04c5","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/bound.rs":"4999df0c898ae4d5f0fdcd7a6365edabd5101027d67224ce54901c1653060f15","src/de.rs":"6783ba15e53f5d494c9af609474fa15d99d5e76bb0fea71e4d85829f3eeec2d0","src/fragment.rs":"f1642a1c2abbc36191206a5ec8077e314bdc20a420d7649e4bec3a69d555f78d","src/lib.rs":"49832577d7d7451cb6aedab7fdb1c9013e4ad0b8962d0d5d0936e69c9c9fc7ce","src/ser.rs":"e10042683c58f5eb833d9811ed3c2115e93f412188ac6f116c063851584fbec5"},"package":null}
\ No newline at end of file
--- a/third_party/rust/serde_derive/Cargo.toml
+++ b/third_party/rust/serde_derive/Cargo.toml
@@ -1,41 +1,31 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
[package]
name = "serde_derive"
-version = "1.0.8"
+version = "1.0.23" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
-include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+license = "MIT/Apache-2.0"
description = "Macros 1.1 implementation of #[derive(Serialize, Deserialize)]"
homepage = "https://serde.rs"
+repository = "https://github.com/serde-rs/serde"
documentation = "https://serde.rs/codegen.html"
-readme = "README.md"
keywords = ["serde", "serialization", "no_std"]
-license = "MIT/Apache-2.0"
-repository = "https://github.com/serde-rs/serde"
+readme = "README.md"
+include = ["Cargo.toml", "src/**/*.rs", "README.md", "LICENSE-APACHE", "LICENSE-MIT"]
+
+[badges]
+travis-ci = { repository = "serde-rs/serde" }
+
+[features]
+default = []
+deserialize_from = []
[lib]
name = "serde_derive"
proc-macro = true
[dependencies]
quote = "0.3.8"
-
-[dependencies.syn]
-version = "0.11"
-features = ["visit"]
+serde_derive_internals = { version = "=0.17.0", default-features = false, path = "../serde_derive_internals" }
+syn = { version = "0.11", features = ["visit"] }
-[dependencies.serde_derive_internals]
-version = "=0.15.1"
-default-features = false
-[badges.travis-ci]
-repository = "serde-rs/serde"
+[dev-dependencies]
+serde = { version = "1.0", path = "../serde" }
--- a/third_party/rust/serde_derive/README.md
+++ b/third_party/rust/serde_derive/README.md
@@ -15,19 +15,40 @@ You may be looking for:
- [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>
+<details>
+<summary>
+Click to show Cargo.toml.
+<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
+</summary>
+
+```toml
+[dependencies]
+
+# The core APIs, including the Serialize and Deserialize traits. Always
+# required when using Serde.
+serde = "1.0"
+
+# Support for #[derive(Serialize, Deserialize)]. Required if you want Serde
+# to work for structs and enums defined in your crate.
+serde_derive = "1.0"
+
+# Each data format lives in its own crate; the sample code below uses JSON
+# but you may be using a different one.
+serde_json = "1.0"
+```
+
+</details>
+<p></p>
```rust
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
--- a/third_party/rust/serde_derive/src/bound.rs
+++ b/third_party/rust/serde_derive/src/bound.rs
@@ -5,22 +5,22 @@
// <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::collections::HashSet;
use syn::{self, visit};
-use internals::ast::Container;
+use internals::ast::{Body, Container};
use internals::attr;
macro_rules! path {
($($path:tt)+) => {
- syn::parse_path(stringify!($($path)+)).unwrap()
+ syn::parse_path(quote!($($path)+).as_str()).unwrap()
};
}
// Remove the default from every type parameter because in the generated impls
// they look like associated types: "error: associated type bindings are not
// allowed here".
pub fn without_defaults(generics: &syn::Generics) -> syn::Generics {
syn::Generics {
@@ -83,17 +83,17 @@ where
// }
pub fn with_bound<F>(
cont: &Container,
generics: &syn::Generics,
filter: F,
bound: &syn::Path,
) -> syn::Generics
where
- F: Fn(&attr::Field) -> bool,
+ F: Fn(&attr::Field, Option<&attr::Variant>) -> bool,
{
struct FindTyParams {
// Set of all generic type parameters on the current struct (A, B, C in
// the example). Initialized up front.
all_ty_params: HashSet<syn::Ident>,
// Set of generic type parameters used in fields for which filter
// returns true (A and B in the example). Filled in as the visitor sees
// them.
@@ -111,35 +111,53 @@ where
if !path.global && path.segments.len() == 1 {
let id = path.segments[0].ident.clone();
if self.all_ty_params.contains(&id) {
self.relevant_ty_params.insert(id);
}
}
visit::walk_path(self, path);
}
+
+ // Type parameter should not be considered used by a macro path.
+ //
+ // struct TypeMacro<T> {
+ // mac: T!(),
+ // marker: PhantomData<T>,
+ // }
+ fn visit_mac(&mut self, _mac: &syn::Mac) {}
}
let all_ty_params: HashSet<_> = generics
.ty_params
.iter()
.map(|ty_param| ty_param.ident.clone())
.collect();
- let relevant_tys = cont.body
- .all_fields()
- .filter(|&field| filter(&field.attrs))
- .map(|field| &field.ty);
-
let mut visitor = FindTyParams {
all_ty_params: all_ty_params,
relevant_ty_params: HashSet::new(),
};
- for ty in relevant_tys {
- visit::walk_ty(&mut visitor, ty);
+ match cont.body {
+ Body::Enum(_, ref variants) => {
+ for variant in variants.iter() {
+ let relevant_fields = variant
+ .fields
+ .iter()
+ .filter(|field| filter(&field.attrs, Some(&variant.attrs)));
+ for field in relevant_fields {
+ visit::walk_ty(&mut visitor, field.ty);
+ }
+ }
+ }
+ Body::Struct(_, ref fields) => {
+ for field in fields.iter().filter(|field| filter(&field.attrs, None)) {
+ visit::walk_ty(&mut visitor, field.ty);
+ }
+ }
}
let new_predicates = generics
.ty_params
.iter()
.map(|ty_param| ty_param.ident.clone())
.filter(|id| visitor.relevant_ty_params.contains(id))
.map(
--- a/third_party/rust/serde_derive/src/de.rs
+++ b/third_party/rust/serde_derive/src/de.rs
@@ -6,218 +6,291 @@
// option. This file may not be copied, modified, or distributed
// except according to those terms.
use syn::{self, Ident};
use quote::{self, Tokens, ToTokens};
use bound;
use fragment::{Fragment, Expr, Stmts, Match};
-use internals::ast::{Body, Container, Field, Style, Variant};
+use internals::ast::{Body, Container, Field, Repr, Style, Variant};
use internals::{self, attr};
use std::collections::BTreeSet;
pub fn expand_derive_deserialize(input: &syn::DeriveInput) -> Result<Tokens, String> {
let ctxt = internals::Ctxt::new();
let cont = Container::from_ast(&ctxt, input);
try!(ctxt.check());
let ident = &cont.ident;
let params = Parameters::new(&cont);
+ let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(¶ms);
let dummy_const = Ident::new(format!("_IMPL_DESERIALIZE_FOR_{}", ident));
- let body = Stmts(deserialize_body(&cont, ¶ms));
+ let main_body = Stmts(deserialize_body(&cont, ¶ms));
+ let delife = params.borrowed.de_lifetime();
let impl_block = if let Some(remote) = cont.attrs.remote() {
- let (impl_generics, ty_generics, where_clause) = cont.generics.split_for_impl();
- let de_lifetime = params.de_lifetime_def();
+ let vis = &input.vis;
quote! {
- impl #impl_generics #ident #ty_generics #where_clause {
- fn deserialize<#de_lifetime, __D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
- where __D: _serde::Deserializer<'de>
+ impl #de_impl_generics #ident #ty_generics #where_clause {
+ #vis fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<#remote #ty_generics, __D::Error>
+ where __D: _serde::Deserializer<#delife>
{
- #body
+ #main_body
}
}
}
} else {
- let (de_impl_generics, _, ty_generics, where_clause) = split_with_de_lifetime(¶ms);
+ let from_body = deserialize_from_body(&cont, ¶ms);
+ let from_impl = from_body.map(|from_body| {
+ let from_body = Stmts(from_body);
+
+ quote! {
+ fn deserialize_from<__D>(&mut self, __deserializer: __D) -> _serde::export::Result<(), __D::Error>
+ where __D: _serde::Deserializer<#delife>
+ {
+ #from_body
+ }
+ }
+ });
+
quote! {
#[automatically_derived]
- impl #de_impl_generics _serde::Deserialize<'de> for #ident #ty_generics #where_clause {
+ impl #de_impl_generics _serde::Deserialize<#delife> for #ident #ty_generics #where_clause {
fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
- where __D: _serde::Deserializer<'de>
+ where __D: _serde::Deserializer<#delife>
{
- #body
+ #main_body
}
+
+ #from_impl
}
}
};
let generated = quote! {
#[allow(non_upper_case_globals, unused_attributes, unused_qualifications)]
const #dummy_const: () = {
extern crate serde as _serde;
#impl_block
};
};
Ok(generated)
}
+#[derive(Clone)]
struct Parameters {
/// Name of the type the `derive` is on.
local: syn::Ident,
/// Path to the type the impl is for. Either a single `Ident` for local
/// types or `some::remote::Ident` for remote types. Does not include
/// generic parameters.
this: syn::Path,
/// Generics including any explicit and inferred bounds for the impl.
generics: syn::Generics,
/// Lifetimes borrowed from the deserializer. These will become bounds on
/// the `'de` lifetime of the deserializer.
- borrowed: BTreeSet<syn::Lifetime>,
+ borrowed: BorrowedLifetimes,
/// At least one field has a serde(getter) attribute, implying that the
/// remote type has a private field.
has_getter: bool,
}
impl Parameters {
fn new(cont: &Container) -> Self {
let local = cont.ident.clone();
let this = match cont.attrs.remote() {
Some(remote) => remote.clone(),
None => cont.ident.clone().into(),
};
- let generics = build_generics(cont);
let borrowed = borrowed_lifetimes(cont);
+ let generics = build_generics(cont, &borrowed);
let has_getter = cont.body.has_getter();
Parameters {
local: local,
this: this,
generics: generics,
borrowed: borrowed,
has_getter: has_getter,
}
}
/// Type name to use in error messages and `&'static str` arguments to
/// various Deserializer methods.
fn type_name(&self) -> &str {
self.this.segments.last().unwrap().ident.as_ref()
}
-
- fn de_lifetime_def(&self) -> syn::LifetimeDef {
- syn::LifetimeDef {
- attrs: Vec::new(),
- lifetime: syn::Lifetime::new("'de"),
- bounds: self.borrowed.iter().cloned().collect(),
- }
- }
}
// All the generics in the input, plus a bound `T: Deserialize` for each generic
// field type that will be deserialized by us, plus a bound `T: Default` for
// each generic field type that will be set to a default value.
-fn build_generics(cont: &Container) -> syn::Generics {
+fn build_generics(cont: &Container, borrowed: &BorrowedLifetimes) -> syn::Generics {
let generics = bound::without_defaults(cont.generics);
let generics = bound::with_where_predicates_from_fields(cont, &generics, attr::Field::de_bound);
match cont.attrs.de_bound() {
Some(predicates) => bound::with_where_predicates(&generics, predicates),
None => {
let generics = match *cont.attrs.default() {
attr::Default::Default => {
bound::with_self_bound(cont, &generics, &path!(_serde::export::Default))
}
attr::Default::None |
attr::Default::Path(_) => generics,
};
+ let delife = borrowed.de_lifetime();
let generics = bound::with_bound(
cont,
&generics,
needs_deserialize_bound,
- &path!(_serde::Deserialize<'de>),
+ &path!(_serde::Deserialize<#delife>),
);
bound::with_bound(
cont,
&generics,
requires_default,
&path!(_serde::export::Default),
)
}
}
}
// Fields with a `skip_deserializing` or `deserialize_with` attribute are not
// deserialized by us so we do not generate a bound. Fields with a `bound`
// attribute specify their own bound so we do not generate one. All other fields
// may need a `T: Deserialize` bound where T is the type of the field.
-fn needs_deserialize_bound(attrs: &attr::Field) -> bool {
- !attrs.skip_deserializing() && attrs.deserialize_with().is_none() && attrs.de_bound().is_none()
+fn needs_deserialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
+ !field.skip_deserializing() &&
+ field.deserialize_with().is_none() &&
+ field.de_bound().is_none() &&
+ variant.map_or(true, |variant| variant.deserialize_with().is_none())
}
// Fields with a `default` attribute (not `default=...`), and fields with a
// `skip_deserializing` attribute that do not also have `default=...`.
-fn requires_default(attrs: &attr::Field) -> bool {
- attrs.default() == &attr::Default::Default
+fn requires_default(field: &attr::Field, _variant: Option<&attr::Variant>) -> bool {
+ field.default() == &attr::Default::Default
+}
+
+#[derive(Clone)]
+enum BorrowedLifetimes {
+ Borrowed(BTreeSet<syn::Lifetime>),
+ Static,
+}
+
+impl BorrowedLifetimes {
+ fn de_lifetime(&self) -> syn::Lifetime {
+ match *self {
+ BorrowedLifetimes::Borrowed(_) => syn::Lifetime::new("'de"),
+ BorrowedLifetimes::Static => syn::Lifetime::new("'static"),
+ }
+ }
+
+ fn de_lifetime_def(&self) -> Option<syn::LifetimeDef> {
+ match *self {
+ BorrowedLifetimes::Borrowed(ref bounds) => {
+ Some(syn::LifetimeDef {
+ attrs: Vec::new(),
+ lifetime: syn::Lifetime::new("'de"),
+ bounds: bounds.iter().cloned().collect(),
+ })
+ }
+ BorrowedLifetimes::Static => None,
+ }
+ }
}
// The union of lifetimes borrowed by each field of the container.
//
// These turn into bounds on the `'de` lifetime of the Deserialize impl. If
// lifetimes `'a` and `'b` are borrowed but `'c` is not, the impl is:
//
// impl<'de: 'a + 'b, 'a, 'b, 'c> Deserialize<'de> for S<'a, 'b, 'c>
-fn borrowed_lifetimes(cont: &Container) -> BTreeSet<syn::Lifetime> {
+//
+// If any borrowed lifetime is `'static`, then `'de: 'static` would be redundant
+// and we use plain `'static` instead of `'de`.
+fn borrowed_lifetimes(cont: &Container) -> BorrowedLifetimes {
let mut lifetimes = BTreeSet::new();
for field in cont.body.all_fields() {
- lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned());
+ if !field.attrs.skip_deserializing() {
+ lifetimes.extend(field.attrs.borrowed_lifetimes().iter().cloned());
+ }
}
- lifetimes
+ if lifetimes.iter().any(|b| b.ident == "'static") {
+ BorrowedLifetimes::Static
+ } else {
+ BorrowedLifetimes::Borrowed(lifetimes)
+ }
}
fn deserialize_body(cont: &Container, params: &Parameters) -> Fragment {
if let Some(from_type) = cont.attrs.from_type() {
deserialize_from(from_type)
} else if let attr::Identifier::No = cont.attrs.identifier() {
match cont.body {
- Body::Enum(ref variants) => deserialize_enum(params, variants, &cont.attrs),
+ Body::Enum(_, ref variants) => deserialize_enum(params, variants, &cont.attrs),
Body::Struct(Style::Struct, ref fields) => {
if fields.iter().any(|field| field.ident.is_none()) {
panic!("struct has unnamed fields");
}
- deserialize_struct(None, params, fields, &cont.attrs, None)
+ deserialize_struct(None, params, fields, &cont.attrs, None, Untagged::No)
}
Body::Struct(Style::Tuple, ref fields) |
Body::Struct(Style::Newtype, ref fields) => {
if fields.iter().any(|field| field.ident.is_some()) {
panic!("tuple struct has named fields");
}
deserialize_tuple(None, params, fields, &cont.attrs, None)
}
Body::Struct(Style::Unit, _) => deserialize_unit_struct(params, &cont.attrs),
}
} else {
match cont.body {
- Body::Enum(ref variants) => {
+ Body::Enum(_, ref variants) => {
deserialize_custom_identifier(params, variants, &cont.attrs)
}
Body::Struct(_, _) => unreachable!("checked in serde_derive_internals"),
}
}
}
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_body(cont: &Container, params: &Parameters) -> Option<Fragment> {
+ if let (None, attr::Identifier::No) = (cont.attrs.from_type(), cont.attrs.identifier()) {
+ match cont.body {
+ Body::Enum(ref repr, ref variants) => deserialize_from_enum(params, repr, variants, &cont.attrs),
+ Body::Struct(Style::Struct, ref fields) => {
+ deserialize_from_struct(None, params, fields, &cont.attrs, None, Untagged::No)
+ }
+ Body::Struct(Style::Tuple, ref fields) |
+ Body::Struct(Style::Newtype, ref fields) => {
+ deserialize_from_tuple(None, params, fields, &cont.attrs, None)
+ }
+ Body::Struct(Style::Unit, _) => None,
+ }
+ } else {
+ None
+ }
+}
+
+#[cfg(not(feature = "deserialize_from"))]
+fn deserialize_from_body(_cont: &Container, _params: &Parameters) -> Option<Fragment> {
+ None
+}
+
fn deserialize_from(from_type: &syn::Ty) -> Fragment {
quote_block! {
_serde::export::Result::map(
<#from_type as _serde::Deserialize>::deserialize(__deserializer),
_serde::export::From::from)
}
}
@@ -253,16 +326,17 @@ fn deserialize_tuple(
variant_ident: Option<&syn::Ident>,
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
deserializer: Option<Tokens>,
) -> Fragment {
let this = ¶ms.this;
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+ let delife = params.borrowed.de_lifetime();
// If there are getters (implying private fields), construct the local type
// and use an `Into` conversion to get the remote type. If there are no
// getters then construct the target type directly.
let construct = if params.has_getter {
let local = ¶ms.local;
quote!(#local)
} else {
@@ -314,40 +388,153 @@ fn deserialize_tuple(
quote!(_)
} else {
quote!(mut __seq)
};
quote_block! {
struct __Visitor #de_impl_generics #where_clause {
marker: _serde::export::PhantomData<#this #ty_generics>,
- lifetime: _serde::export::PhantomData<&'de ()>,
+ lifetime: _serde::export::PhantomData<&#delife ()>,
}
- impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause {
+ impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
type Value = #this #ty_generics;
fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(formatter, #expecting)
}
#visit_newtype_struct
#[inline]
fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::SeqAccess<'de>
+ where __A: _serde::de::SeqAccess<#delife>
{
#visit_seq
}
}
#dispatch
}
}
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_tuple(
+ variant_ident: Option<&syn::Ident>,
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+ deserializer: Option<Tokens>,
+) -> Option<Fragment> {
+ let this = ¶ms.this;
+ let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+ let delife = params.borrowed.de_lifetime();
+
+ // If there are getters (implying private fields), construct the local type
+ // and use an `Into` conversion to get the remote type. If there are no
+ // getters then construct the target type directly.
+ let construct = if params.has_getter {
+ let local = ¶ms.local;
+ quote!(#local)
+ } else {
+ quote!(#this)
+ };
+
+ let is_enum = variant_ident.is_some();
+ let type_path = match variant_ident {
+ Some(variant_ident) => quote!(#construct::#variant_ident),
+ None => construct,
+ };
+ let expecting = match variant_ident {
+ Some(variant_ident) => format!("tuple variant {}::{}", params.type_name(), variant_ident),
+ None => format!("tuple struct {}", params.type_name()),
+ };
+
+ let nfields = fields.len();
+
+ let visit_newtype_struct = if !is_enum && nfields == 1 {
+ Some(deserialize_from_newtype_struct(&type_path, params, &fields[0]))
+ } else {
+ None
+ };
+
+ let visit_seq = Stmts(deserialize_from_seq(params, fields, is_enum, cattrs));
+
+ let visitor_expr = if is_enum {
+ quote! {
+ __Visitor {
+ dest: this,
+ lifetime: _serde::export::PhantomData,
+ }
+ }
+ } else {
+ quote! {
+ __Visitor {
+ dest: self,
+ lifetime: _serde::export::PhantomData,
+ }
+ }
+ };
+
+ let dispatch = if let Some(deserializer) = deserializer {
+ quote!(_serde::Deserializer::deserialize_tuple(#deserializer, #nfields, #visitor_expr))
+ } else if is_enum {
+ quote!(try!(_serde::de::VariantAccess::tuple_variant(__variant, #nfields, #visitor_expr)))
+ } else if nfields == 1 {
+ let type_name = cattrs.name().deserialize_name();
+ quote!(_serde::Deserializer::deserialize_newtype_struct(__deserializer, #type_name, #visitor_expr))
+ } else {
+ let type_name = cattrs.name().deserialize_name();
+ quote!(_serde::Deserializer::deserialize_tuple_struct(__deserializer, #type_name, #nfields, #visitor_expr))
+ };
+
+ let all_skipped = fields
+ .iter()
+ .all(|field| field.attrs.skip_deserializing());
+ let visitor_var = if all_skipped {
+ quote!(_)
+ } else {
+ quote!(mut __seq)
+ };
+
+ if params.has_getter {
+ None
+ } else {
+ let de_from_impl_generics = de_impl_generics.with_dest();
+ let de_from_ty_generics = de_ty_generics.with_dest();
+ let dest_life = dest_lifetime();
+ Some(quote_block! {
+ struct __Visitor #de_from_impl_generics #where_clause {
+ dest: &#dest_life mut #this #ty_generics,
+ lifetime: _serde::export::PhantomData<&#delife ()>,
+ }
+
+ impl #de_from_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_from_ty_generics #where_clause {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(formatter, #expecting)
+ }
+
+ #visit_newtype_struct
+
+ #[inline]
+ fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
+ where __A: _serde::de::SeqAccess<#delife>
+ {
+ #visit_seq
+ }
+ }
+
+ #dispatch
+ })
+ }
+}
+
fn deserialize_seq(
type_path: &Tokens,
params: &Parameters,
fields: &[Field],
is_struct: bool,
cattrs: &attr::Container,
) -> Fragment {
let vars = (0..fields.len()).map(field_i as fn(_) -> _);
@@ -368,30 +555,30 @@ fn deserialize_seq(
}
} else {
let visit = match field.attrs.deserialize_with() {
None => {
let field_ty = &field.ty;
quote!(try!(_serde::de::SeqAccess::next_element::<#field_ty>(&mut __seq)))
}
Some(path) => {
- let (wrapper, wrapper_ty) = wrap_deserialize_with(
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
params, field.ty, path);
quote!({
#wrapper
_serde::export::Option::map(
try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)),
|__wrap| __wrap.value)
})
}
};
let assign = quote! {
let #var = match #visit {
- Some(__value) => __value,
- None => {
+ _serde::export::Some(__value) => __value,
+ _serde::export::None => {
return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
}
};
};
index_in_seq += 1;
assign
}
});
@@ -415,26 +602,100 @@ fn deserialize_seq(
}
quote_block! {
#(#let_values)*
_serde::export::Ok(#result)
}
}
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_seq(
+ params: &Parameters,
+ fields: &[Field],
+ increment_fields: bool,
+ cattrs: &attr::Container,
+) -> Fragment {
+ // For enums there's a secret `tag` field at the start which we shouldn't touch,
+ // so we need to bump all the indices up by 1.
+ let index_names = if increment_fields {
+ (0..fields.len())
+ } else {
+ (1..fields.len() + 1)
+ };
+ let vars = index_names.map(field_i as fn(_) -> _);
+
+ let deserialized_count = fields
+ .iter()
+ .filter(|field| !field.attrs.skip_deserializing())
+ .count();
+ let expecting = format!("tuple of {} elements", deserialized_count);
+
+ let mut index_in_seq = 0usize;
+ let write_values = vars.clone().zip(fields).enumerate()
+ .map(|(field_index, (_, field))| {
+ // If there's no field name, assume we're a tuple-struct and use a numeric index
+ let field_name = field.ident.clone()
+ .unwrap_or_else(|| Ident::new(field_index.to_string()));
+
+ if field.attrs.skip_deserializing() {
+ let default = Expr(expr_is_missing(&field, cattrs));
+ quote! {
+ self.dest.#field_name = #default;
+ }
+ } else {
+ let handle_none = quote! {
+ if visit.is_none() {
+ return _serde::export::Err(_serde::de::Error::invalid_length(#index_in_seq, &#expecting));
+ }
+ };
+ let write = match field.attrs.deserialize_with() {
+ None => {
+ quote! {
+ let visit = try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
+ _serde::private::de::DeserializeFromSeed(&mut self.dest.#field_name)));
+ #handle_none
+ }
+ }
+ Some(path) => {
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
+ params, field.ty, path);
+ quote!({
+ #wrapper
+ let visit = _serde::export::Option::map(
+ try!(_serde::de::SeqAccess::next_element::<#wrapper_ty>(&mut __seq)),
+ |__wrap| __wrap.value);
+ #handle_none
+ self.dest.#field_name = visit.unwrap();
+ })
+ }
+ };
+ index_in_seq += 1;
+ write
+ }
+ });
+
+ quote_block! {
+ #(#write_values)*
+ _serde::export::Ok(())
+ }
+}
+
fn deserialize_newtype_struct(type_path: &Tokens, params: &Parameters, field: &Field) -> Tokens {
+ let delife = params.borrowed.de_lifetime();
+
let value = match field.attrs.deserialize_with() {
None => {
let field_ty = &field.ty;
quote! {
try!(<#field_ty as _serde::Deserialize>::deserialize(__e))
}
}
Some(path) => {
- let (wrapper, wrapper_ty) = wrap_deserialize_with(params, field.ty, path);
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
quote!({
#wrapper
try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value
})
}
};
let mut result = quote!(#type_path(#value));
@@ -443,35 +704,98 @@ fn deserialize_newtype_struct(type_path:
result = quote! {
_serde::export::Into::<#this>::into(#result)
};
}
quote! {
#[inline]
fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
- where __E: _serde::Deserializer<'de>
+ where __E: _serde::Deserializer<#delife>
{
_serde::export::Ok(#result)
}
}
}
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_newtype_struct(
+ type_path: &Tokens,
+ params: &Parameters,
+ field: &Field
+) -> Tokens {
+ let delife = params.borrowed.de_lifetime();
+
+ // FIXME: can we reject this condition earlier so we don't have to handle it?
+ // If there's conversions that we need to do, we can't do this properly.
+ if field.attrs.deserialize_with().is_some() || params.has_getter {
+ let value = match field.attrs.deserialize_with() {
+ None => {
+ let field_ty = &field.ty;
+ quote! {
+ try!(<#field_ty as _serde::Deserialize>::deserialize(__e))
+ }
+ }
+ Some(path) => {
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
+ quote!({
+ #wrapper
+ try!(<#wrapper_ty as _serde::Deserialize>::deserialize(__e)).value
+ })
+ }
+ };
+
+ let mut result = quote!(#type_path(#value));
+ if params.has_getter {
+ let this = ¶ms.this;
+ result = quote! {
+ _serde::export::Into::<#this>::into(#result)
+ };
+ }
+
+ quote! {
+ #[inline]
+ fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
+ where __E: _serde::Deserializer<#delife>
+ {
+ *self.dest = #result;
+ _serde::export::Ok(())
+ }
+ }
+ } else {
+ // No conversions, just recurse on the field.
+ quote! {
+ #[inline]
+ fn visit_newtype_struct<__E>(self, __e: __E) -> _serde::export::Result<Self::Value, __E::Error>
+ where __E: _serde::Deserializer<#delife>
+ {
+ _serde::Deserialize::deserialize_from(&mut self.dest.0, __e)
+ }
+ }
+ }
+}
+
+enum Untagged {
+ Yes,
+ No,
+}
+
fn deserialize_struct(
variant_ident: Option<&syn::Ident>,
params: &Parameters,
fields: &[Field],
cattrs: &attr::Container,
deserializer: Option<Tokens>,
+ untagged: Untagged,
) -> Fragment {
let is_enum = variant_ident.is_some();
- let is_untagged = deserializer.is_some();
let this = ¶ms.this;
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+ let delife = params.borrowed.de_lifetime();
// If there are getters (implying private fields), construct the local type
// and use an `Into` conversion to get the remote type. If there are no
// getters then construct the target type directly.
let construct = if params.has_getter {
let local = ¶ms.local;
quote!(#local)
} else {
@@ -520,61 +844,177 @@ fn deserialize_struct(
.iter()
.all(|field| field.attrs.skip_deserializing());
let visitor_var = if all_skipped {
quote!(_)
} else {
quote!(mut __seq)
};
- let visit_seq = if is_untagged {
- // untagged struct variants do not get a visit_seq method
- None
- } else {
- Some(quote! {
- #[inline]
- fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::SeqAccess<'de>
- {
- #visit_seq
- }
- })
+ // untagged struct variants do not get a visit_seq method
+ let visit_seq = match untagged {
+ Untagged::Yes => None,
+ Untagged::No => {
+ Some(quote! {
+ #[inline]
+ fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
+ where __A: _serde::de::SeqAccess<#delife>
+ {
+ #visit_seq
+ }
+ })
+ }
};
quote_block! {
#field_visitor
struct __Visitor #de_impl_generics #where_clause {
marker: _serde::export::PhantomData<#this #ty_generics>,
- lifetime: _serde::export::PhantomData<&'de ()>,
+ lifetime: _serde::export::PhantomData<&#delife ()>,
}
- impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause {
+ impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
type Value = #this #ty_generics;
fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(formatter, #expecting)
}
#visit_seq
#[inline]
fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::MapAccess<'de>
+ where __A: _serde::de::MapAccess<#delife>
{
#visit_map
}
}
#fields_stmt
#dispatch
}
}
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_struct(
+ variant_ident: Option<&syn::Ident>,
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+ deserializer: Option<Tokens>,
+ untagged: Untagged,
+) -> Option<Fragment> {
+ let is_enum = variant_ident.is_some();
+
+ let this = ¶ms.this;
+ let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+ let delife = params.borrowed.de_lifetime();
+
+ let expecting = match variant_ident {
+ Some(variant_ident) => format!("struct variant {}::{}", params.type_name(), variant_ident),
+ None => format!("struct {}", params.type_name()),
+ };
+
+ let visit_seq = Stmts(deserialize_from_seq(params, fields, false, cattrs));
+
+ let (field_visitor, fields_stmt, visit_map) =
+ deserialize_from_struct_visitor(params, fields, cattrs);
+ let field_visitor = Stmts(field_visitor);
+ let fields_stmt = Stmts(fields_stmt);
+ let visit_map = Stmts(visit_map);
+
+ let visitor_expr = quote! {
+ __Visitor {
+ dest: self,
+ lifetime: _serde::export::PhantomData,
+ }
+ };
+ let dispatch = if let Some(deserializer) = deserializer {
+ quote! {
+ _serde::Deserializer::deserialize_any(#deserializer, #visitor_expr)
+ }
+ } else if is_enum {
+ quote! {
+ _serde::de::VariantAccess::struct_variant(__variant, FIELDS, #visitor_expr)
+ }
+ } else {
+ let type_name = cattrs.name().deserialize_name();
+ quote! {
+ _serde::Deserializer::deserialize_struct(__deserializer, #type_name, FIELDS, #visitor_expr)
+ }
+ };
+
+
+ let all_skipped = fields
+ .iter()
+ .all(|field| field.attrs.skip_deserializing());
+ let visitor_var = if all_skipped {
+ quote!(_)
+ } else {
+ quote!(mut __seq)
+ };
+
+ // untagged struct variants do not get a visit_seq method
+ let visit_seq = match untagged {
+ Untagged::Yes => None,
+ Untagged::No => {
+ Some(quote! {
+ #[inline]
+ fn visit_seq<__A>(self, #visitor_var: __A) -> _serde::export::Result<Self::Value, __A::Error>
+ where __A: _serde::de::SeqAccess<#delife>
+ {
+ #visit_seq
+ }
+ })
+
+ }
+ };
+
+ if params.has_getter {
+ None
+ } else {
+ let de_from_impl_generics = de_impl_generics.with_dest();
+ let de_from_ty_generics = de_ty_generics.with_dest();
+ let dest_life = dest_lifetime();
+
+ Some(quote_block! {
+ #field_visitor
+
+ struct __Visitor #de_from_impl_generics #where_clause {
+ dest: &#dest_life mut #this #ty_generics,
+ lifetime: _serde::export::PhantomData<&#delife ()>,
+ }
+
+ impl #de_from_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_from_ty_generics #where_clause {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(formatter, #expecting)
+ }
+
+ #visit_seq
+
+ #[inline]
+ #[allow(unreachable_code)]
+ fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
+ where __A: _serde::de::MapAccess<#delife>
+ {
+ #visit_map
+ }
+ }
+
+ #fields_stmt
+
+ #dispatch
+ })
+ }
+}
+
fn deserialize_enum(
params: &Parameters,
variants: &[Variant],
cattrs: &attr::Container,
) -> Fragment {
match *cattrs.tag() {
attr::EnumTag::External => deserialize_externally_tagged_enum(params, variants, cattrs),
attr::EnumTag::Internal { ref tag } => {
@@ -583,23 +1023,37 @@ fn deserialize_enum(
attr::EnumTag::Adjacent {
ref tag,
ref content,
} => deserialize_adjacently_tagged_enum(params, variants, cattrs, tag, content),
attr::EnumTag::None => deserialize_untagged_enum(params, variants, cattrs),
}
}
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_enum(
+ params: &Parameters,
+ repr: &Repr,
+ variants: &[Variant],
+ cattrs: &attr::Container,
+) -> Option<Fragment> {
+ match *cattrs.tag() {
+ attr::EnumTag::External => deserialize_from_externally_tagged_enum(params, repr, variants, cattrs),
+ _ => None,
+ }
+}
+
fn deserialize_externally_tagged_enum(
params: &Parameters,
variants: &[Variant],
cattrs: &attr::Container,
) -> Fragment {
let this = ¶ms.this;
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+ let delife = params.borrowed.de_lifetime();
let type_name = cattrs.name().deserialize_name();
let expecting = format!("enum {}", params.type_name());
let variant_names_idents: Vec<_> = variants
.iter()
.enumerate()
@@ -655,43 +1109,290 @@ fn deserialize_externally_tagged_enum(
}
};
quote_block! {
#variant_visitor
struct __Visitor #de_impl_generics #where_clause {
marker: _serde::export::PhantomData<#this #ty_generics>,
- lifetime: _serde::export::PhantomData<&'de ()>,
+ lifetime: _serde::export::PhantomData<&#delife ()>,
}
- impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause {
+ impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
type Value = #this #ty_generics;
fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(formatter, #expecting)
}
fn visit_enum<__A>(self, __data: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::EnumAccess<'de>
+ where __A: _serde::de::EnumAccess<#delife>
{
#match_variant
}
}
#variants_stmt
_serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS,
__Visitor {
marker: _serde::export::PhantomData::<#this #ty_generics>,
lifetime: _serde::export::PhantomData,
})
}
}
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_externally_tagged_enum(
+ params: &Parameters,
+ repr: &Repr,
+ variants: &[Variant],
+ cattrs: &attr::Container,
+) -> Option<Fragment> {
+ let int_repr = repr.get_stable_rust_enum_layout().map(|int_repr| {
+ let int_repr = Ident::new(int_repr);
+ quote!(#[repr(#int_repr)])
+ });
+
+ let unit_variant = variants.iter().position(|variant| is_unit(variant));
+ let non_unit_variant = variants.iter().enumerate().find(|&(_, variant)| !is_unit(variant));
+
+ // We need an int_repr, unit variant, and a non-unit variant to proceed
+ if int_repr.is_none() || unit_variant.is_none() || non_unit_variant.is_none() {
+ return None;
+ }
+
+ let unit_index = unit_variant.unwrap();
+ let (non_unit_index, non_unit_variant) = non_unit_variant.unwrap();
+ let int_repr = int_repr.unwrap();
+
+ let this = ¶ms.this;
+ let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+ let delife = params.borrowed.de_lifetime();
+
+ let type_name = cattrs.name().deserialize_name();
+
+ let expecting = format!("enum {}", params.type_name());
+
+ let variant_names_idents: Vec<_> = variants
+ .iter()
+ .enumerate()
+ .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
+ .map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),)
+ .collect();
+
+ let variants_stmt = {
+ let variant_names = variant_names_idents.iter().map(|&(ref name, _)| name);
+ quote! {
+ const VARIANTS: &'static [&'static str] = &[ #(#variant_names),* ];
+ }
+ };
+
+ let variant_visitor = Stmts(deserialize_generated_identifier(variant_names_idents, cattrs, true),);
+
+ let non_unit_field = field_i(non_unit_index);
+ let tag_access = match non_unit_variant.style {
+ Style::Struct => {
+ quote!(repr.#non_unit_field.tag)
+ }
+ Style::Tuple | Style::Newtype => {
+ quote!(repr.#non_unit_field.0)
+ }
+ _ => unreachable!()
+ };
+
+ let mut sub_params = params.clone();
+ let variant_arms_from = variants
+ .iter()
+ .enumerate()
+ .filter(|&(_, variant)| !variant.attrs.skip_deserializing())
+ .map(
+ |(i, variant)| {
+ let variant_name = field_i(i);
+ sub_params.this = syn::Path::from(variant_name.clone());
+
+ let this_decl = if is_unit(variant) {
+ None
+ } else {
+ Some(quote!(let this = &mut repr.#variant_name;))
+ };
+ let block = Stmts(deserialize_from_externally_tagged_variant(&sub_params, variant, cattrs));
+ quote! {
+ (__Field::#variant_name, __variant) => {
+ {
+ #this_decl
+ #block;
+ }
+ #tag_access = __Tag::#variant_name;
+ _serde::export::Result::Ok(())
+ }
+ }
+ },
+ );
+
+ let all_skipped = variants
+ .iter()
+ .all(|variant| variant.attrs.skip_deserializing());
+
+ let match_variant_from = if all_skipped {
+ // This is an empty enum like `enum Impossible {}` or an enum in which
+ // all variants have `#[serde(skip_deserializing)]`.
+ quote! {
+ // FIXME: Once we drop support for Rust 1.15:
+ // let _serde::export::Err(__err) = _serde::de::EnumAccess::variant::<__Field>(__data);
+ // _serde::export::Err(__err)
+ _serde::export::Result::map(
+ _serde::de::EnumAccess::variant::<__Field>(__data),
+ |(__impossible, _)| match __impossible {})
+ }
+ } else {
+ let unit_field = field_i(unit_index);
+
+ quote! {
+ unsafe {
+ let repr = ::std::mem::transmute::<&mut #this #ty_generics, &mut __EnumRepr>(self.dest);
+ #tag_access = __Tag::#unit_field;
+ match try!(_serde::de::EnumAccess::variant(__data)) {
+ #(#variant_arms_from)*
+ }
+ }
+ }
+ };
+
+ let repr_cases = variants
+ .iter()
+ .enumerate()
+ .filter_map(
+ |(i, variant)| {
+ if is_unit(&variant) {
+ None
+ } else {
+ let variant_name = field_i(i);
+ Some(quote!(#variant_name: #variant_name))
+ }
+ }
+ );
+
+ let tag_cases = variants
+ .iter()
+ .enumerate()
+ .map(
+ |(i, _variant)| {
+ let variant_name = field_i(i);
+
+ quote!(#variant_name)
+ }
+ );
+
+
+ let repr_payloads = variants
+ .iter()
+ .enumerate()
+ .filter_map(
+ |(i, variant)| {
+ let variant_name = field_i(i);
+ match variant.style {
+ Style::Struct => {
+ let fields = variant.fields.iter().enumerate().map(|(j, field)| {
+ let field_name = field_i(j);
+ let field_ty = field.ty;
+ quote!(#field_name: #field_ty)
+ });
+
+ let payload = quote! {
+ #[repr(C)]
+ #[derive(Copy, Clone)]
+ #[allow(non_camel_case_types)]
+ struct #variant_name #ty_generics {
+ tag: __Tag,
+ #(#fields),*
+ }
+ };
+ Some(payload)
+ }
+ Style::Tuple | Style::Newtype => {
+ let fields = variant.fields.iter().map(|field| {
+ let field_ty = field.ty;
+ quote!(#field_ty)
+ });
+
+ let payload = quote! {
+ #[repr(C)]
+ #[derive(Copy, Clone)]
+ #[allow(non_camel_case_types)]
+ struct #variant_name #ty_generics (
+ __Tag,
+ #(#fields),*
+
+ );
+ };
+ Some(payload)
+ }
+ Style::Unit => None,
+ }
+
+ }
+ );
+
+ let raw_repr = quote! {
+ #[repr(C)]
+ #[allow(non_camel_case_types)]
+ union __EnumRepr #ty_generics {
+ #(#repr_cases),*
+ }
+
+ #int_repr
+ #[derive(Copy, Clone)]
+ #[allow(non_camel_case_types)]
+ enum __Tag {
+ #(#tag_cases),*
+ }
+
+ #(#repr_payloads)*
+ };
+
+ let de_from_impl_generics = de_impl_generics.with_dest();
+ let de_from_ty_generics = de_ty_generics.with_dest();
+ let dest_life = dest_lifetime();
+
+ Some(quote_block! {
+ #variant_visitor
+
+ struct __Visitor #de_from_impl_generics #where_clause {
+ dest: &#dest_life mut #this #ty_generics,
+ lifetime: _serde::export::PhantomData<&#delife ()>,
+ }
+
+ impl #de_from_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_from_ty_generics #where_clause {
+ type Value = ();
+
+ fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
+ _serde::export::Formatter::write_str(formatter, #expecting)
+ }
+
+ fn visit_enum<__A>(self, __data: __A) -> _serde::export::Result<Self::Value, __A::Error>
+ where __A: _serde::de::EnumAccess<#delife>
+ {
+ #raw_repr
+
+ #match_variant_from
+ }
+ }
+
+ #variants_stmt
+
+ _serde::Deserializer::deserialize_enum(__deserializer, #type_name, VARIANTS,
+ __Visitor {
+ dest: self,
+ lifetime: _serde::export::PhantomData,
+ })
+ })
+}
+
fn deserialize_internally_tagged_enum(
params: &Parameters,
variants: &[Variant],
cattrs: &attr::Container,
tag: &str,
) -> Fragment {
let variant_names_idents: Vec<_> = variants
.iter()
@@ -747,16 +1448,17 @@ fn deserialize_adjacently_tagged_enum(
params: &Parameters,
variants: &[Variant],
cattrs: &attr::Container,
tag: &str,
content: &str,
) -> Fragment {
let this = ¶ms.this;
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+ let delife = params.borrowed.de_lifetime();
let variant_names_idents: Vec<_> = variants
.iter()
.enumerate()
.filter(|&(_, variant)| !variant.attrs.skip_deserializing())
.map(|(i, variant)| (variant.attrs.name().deserialize_name(), field_i(i)),)
.collect();
@@ -792,39 +1494,31 @@ fn deserialize_adjacently_tagged_enum(
},
)
.collect();
let expecting = format!("adjacently tagged enum {}", params.type_name());
let type_name = cattrs.name().deserialize_name();
let deny_unknown_fields = cattrs.deny_unknown_fields();
- /// If unknown fields are allowed, we pick the visitor that can
- /// step over those. Otherwise we pick the visitor that fails on
- /// unknown keys.
+ // If unknown fields are allowed, we pick the visitor that can step over
+ // those. Otherwise we pick the visitor that fails on unknown keys.
let field_visitor_ty = if deny_unknown_fields {
quote! { _serde::private::de::TagOrContentFieldVisitor }
} else {
quote! { _serde::private::de::TagContentOtherFieldVisitor }
};
let tag_or_content = quote! {
#field_visitor_ty {
tag: #tag,
content: #content,
}
};
- fn is_unit(variant: &Variant) -> bool {
- match variant.style {
- Style::Unit => true,
- Style::Struct | Style::Tuple | Style::Newtype => false,
- }
- }
-
let mut missing_content = quote! {
_serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#content))
};
if variants.iter().any(is_unit) {
let fallthrough = if variants.iter().all(is_unit) {
None
} else {
Some(
@@ -849,23 +1543,23 @@ fn deserialize_adjacently_tagged_enum(
missing_content = quote! {
match __field {
#(#arms)*
#fallthrough
}
};
}
- /// Advance the map by one key, returning early in case of error.
+ // Advance the map by one key, returning early in case of error.
let next_key = quote! {
try!(_serde::de::MapAccess::next_key_seed(&mut __map, #tag_or_content))
};
- /// When allowing unknown fields, we want to transparently step through keys we don't care
- /// about until we find `tag`, `content`, or run out of keys.
+ // When allowing unknown fields, we want to transparently step through keys
+ // we don't care about until we find `tag`, `content`, or run out of keys.
let next_relevant_key = if deny_unknown_fields {
next_key
} else {
quote! {
{
let mut __rk : _serde::export::Option<_serde::private::de::TagOrContentField> = _serde::export::None;
while let _serde::export::Some(__k) = #next_key {
match __k {
@@ -884,19 +1578,19 @@ fn deserialize_adjacently_tagged_enum(
}
}
__rk
}
}
};
- /// Step through remaining keys, looking for duplicates of previously-seen keys.
- /// When unknown fields are denied, any key that isn't a duplicate will at this
- /// point immediately produce an error.
+ // Step through remaining keys, looking for duplicates of previously-seen
+ // keys. When unknown fields are denied, any key that isn't a duplicate will
+ // at this point immediately produce an error.
let visit_remaining_keys = quote! {
match #next_relevant_key {
_serde::export::Some(_serde::private::de::TagOrContentField::Tag) => {
_serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#tag))
}
_serde::export::Some(_serde::private::de::TagOrContentField::Content) => {
_serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#content))
}
@@ -907,45 +1601,45 @@ fn deserialize_adjacently_tagged_enum(
quote_block! {
#variant_visitor
#variants_stmt
struct __Seed #de_impl_generics #where_clause {
field: __Field,
marker: _serde::export::PhantomData<#this #ty_generics>,
- lifetime: _serde::export::PhantomData<&'de ()>,
+ lifetime: _serde::export::PhantomData<&#delife ()>,
}
- impl #de_impl_generics _serde::de::DeserializeSeed<'de> for __Seed #de_ty_generics #where_clause {
+ impl #de_impl_generics _serde::de::DeserializeSeed<#delife> for __Seed #de_ty_generics #where_clause {
type Value = #this #ty_generics;
fn deserialize<__D>(self, __deserializer: __D) -> _serde::export::Result<Self::Value, __D::Error>
- where __D: _serde::Deserializer<'de>
+ where __D: _serde::Deserializer<#delife>
{
match self.field {
#(#variant_arms)*
}
}
}
struct __Visitor #de_impl_generics #where_clause {
marker: _serde::export::PhantomData<#this #ty_generics>,
- lifetime: _serde::export::PhantomData<&'de ()>,
+ lifetime: _serde::export::PhantomData<&#delife ()>,
}
- impl #de_impl_generics _serde::de::Visitor<'de> for __Visitor #de_ty_generics #where_clause {
+ impl #de_impl_generics _serde::de::Visitor<#delife> for __Visitor #de_ty_generics #where_clause {
type Value = #this #ty_generics;
fn expecting(&self, formatter: &mut _serde::export::Formatter) -> _serde::export::fmt::Result {
_serde::export::Formatter::write_str(formatter, #expecting)
}
fn visit_map<__A>(self, mut __map: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::MapAccess<'de>
+ where __A: _serde::de::MapAccess<#delife>
{
// Visit the first relevant key.
match #next_relevant_key {
// First key is the tag.
_serde::export::Some(_serde::private::de::TagOrContentField::Tag) => {
// Parse the tag.
let __field = try!(_serde::de::MapAccess::next_value(&mut __map));
// Visit the second key.
@@ -999,17 +1693,17 @@ fn deserialize_adjacently_tagged_enum(
// There is no first key.
_serde::export::None => {
_serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#tag))
}
}
}
fn visit_seq<__A>(self, mut __seq: __A) -> _serde::export::Result<Self::Value, __A::Error>
- where __A: _serde::de::SeqAccess<'de>
+ where __A: _serde::de::SeqAccess<#delife>
{
// Visit the first element - the tag.
match try!(_serde::de::SeqAccess::next_element(&mut __seq)) {
_serde::export::Some(__field) => {
// Visit the second element - the content.
match try!(_serde::de::SeqAccess::next_element_seed(&mut __seq,
__Seed {
field: __field,
@@ -1081,16 +1775,26 @@ fn deserialize_untagged_enum(
}
}
fn deserialize_externally_tagged_variant(
params: &Parameters,
variant: &Variant,
cattrs: &attr::Container,
) -> Fragment {
+ if let Some(path) = variant.attrs.deserialize_with() {
+ let (wrapper, wrapper_ty, unwrap_fn) =
+ wrap_deserialize_variant_with(params, &variant, path);
+ return quote_block! {
+ #wrapper
+ _serde::export::Result::map(
+ _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn)
+ };
+ }
+
let variant_ident = &variant.ident;
match variant.style {
Style::Unit => {
let this = ¶ms.this;
quote_block! {
try!(_serde::de::VariantAccess::unit_variant(__variant));
_serde::export::Ok(#this::#variant_ident)
@@ -1098,52 +1802,121 @@ fn deserialize_externally_tagged_variant
}
Style::Newtype => {
deserialize_externally_tagged_newtype_variant(variant_ident, params, &variant.fields[0])
}
Style::Tuple => {
deserialize_tuple(Some(variant_ident), params, &variant.fields, cattrs, None)
}
Style::Struct => {
- deserialize_struct(Some(variant_ident), params, &variant.fields, cattrs, None)
+ deserialize_struct(Some(variant_ident), params, &variant.fields, cattrs, None, Untagged::No)
+ }
+ }
+}
+
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_externally_tagged_variant(
+ params: &Parameters,
+ variant: &Variant,
+ cattrs: &attr::Container,
+) -> Fragment {
+ if let Some(_path) = variant.attrs.deserialize_with() {
+ unimplemented!()
+ /*
+ let (wrapper, wrapper_ty, unwrap_fn) =
+ wrap_deserialize_variant_with(params, &variant, path);
+ return quote_block! {
+ #wrapper
+ _serde::export::Result::map(
+ _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant), #unwrap_fn)
+ };
+ */
+ }
+
+ let variant_ident = &variant.ident;
+
+ match variant.style {
+ Style::Unit => {
+ quote_block! {
+ try!(_serde::de::VariantAccess::unit_variant(__variant));
+ }
+ }
+ Style::Newtype => {
+ deserialize_from_externally_tagged_newtype_variant(variant_ident, params, &variant.fields[0])
+ }
+ Style::Tuple => {
+ deserialize_from_tuple(Some(variant_ident), params, &variant.fields, cattrs, None).expect("???")
+ }
+ Style::Struct => {
+ unimplemented!()
+ // deserialize_struct(None, params, &variant.fields, cattrs, None, Untagged::No).0
}
}
}
fn deserialize_internally_tagged_variant(
params: &Parameters,
variant: &Variant,
cattrs: &attr::Container,
deserializer: Tokens,
) -> Fragment {
+ if variant.attrs.deserialize_with().is_some() {
+ return deserialize_untagged_variant(params, variant, cattrs, deserializer);
+ }
+
let variant_ident = &variant.ident;
match variant.style {
Style::Unit => {
let this = ¶ms.this;
let type_name = params.type_name();
let variant_name = variant.ident.as_ref();
quote_block! {
try!(_serde::Deserializer::deserialize_any(#deserializer, _serde::private::de::InternallyTaggedUnitVisitor::new(#type_name, #variant_name)));
_serde::export::Ok(#this::#variant_ident)
}
}
- Style::Newtype | Style::Struct => {
- deserialize_untagged_variant(params, variant, cattrs, deserializer)
+ Style::Newtype => {
+ deserialize_untagged_newtype_variant(
+ variant_ident,
+ params,
+ &variant.fields[0],
+ deserializer,
+ )
+ }
+ Style::Struct => {
+ deserialize_struct(
+ Some(variant_ident),
+ params,
+ &variant.fields,
+ cattrs,
+ Some(deserializer),
+ Untagged::No,
+ )
}
Style::Tuple => unreachable!("checked in serde_derive_internals"),
}
}
fn deserialize_untagged_variant(
params: &Parameters,
variant: &Variant,
cattrs: &attr::Container,
deserializer: Tokens,
) -> Fragment {
+ if let Some(path) = variant.attrs.deserialize_with() {
+ let (wrapper, wrapper_ty, unwrap_fn) =
+ wrap_deserialize_variant_with(params, &variant, path);
+ return quote_block! {
+ #wrapper
+ _serde::export::Result::map(
+ <#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer), #unwrap_fn)
+ };
+ }
+
let variant_ident = &variant.ident;
match variant.style {
Style::Unit => {
let this = ¶ms.this;
let type_name = params.type_name();
let variant_name = variant.ident.as_ref();
quote_expr! {
@@ -1174,16 +1947,17 @@ fn deserialize_untagged_variant(
}
Style::Struct => {
deserialize_struct(
Some(variant_ident),
params,
&variant.fields,
cattrs,
Some(deserializer),
+ Untagged::Yes,
)
}
}
}
fn deserialize_externally_tagged_newtype_variant(
variant_ident: &syn::Ident,
params: &Parameters,
@@ -1195,27 +1969,54 @@ fn deserialize_externally_tagged_newtype
let field_ty = &field.ty;
quote_expr! {
_serde::export::Result::map(
_serde::de::VariantAccess::newtype_variant::<#field_ty>(__variant),
#this::#variant_ident)
}
}
Some(path) => {
- let (wrapper, wrapper_ty) = wrap_deserialize_with(params, field.ty, path);
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
quote_block! {
#wrapper
_serde::export::Result::map(
_serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant),
|__wrapper| #this::#variant_ident(__wrapper.value))
}
}
}
}
+fn deserialize_from_externally_tagged_newtype_variant(
+ _variant_ident: &syn::Ident,
+ params: &Parameters,
+ field: &Field,
+) -> Fragment {
+ let _this = ¶ms.this;
+ match field.attrs.deserialize_with() {
+ None => {
+ quote_expr! {
+ try!(_serde::de::VariantAccess::newtype_variant_seed(__variant, _serde::private::de::DeserializeFromSeed(&mut this.1)));
+ }
+ }
+ Some(_path) => {
+ unimplemented!();
+ /*
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
+ quote_block! {
+ #wrapper
+ _serde::export::Result::map(
+ _serde::de::VariantAccess::newtype_variant::<#wrapper_ty>(__variant),
+ |__wrapper| #this::#variant_ident(__wrapper.value))
+ }
+ */
+ }
+ }
+}
+
fn deserialize_untagged_newtype_variant(
variant_ident: &syn::Ident,
params: &Parameters,
field: &Field,
deserializer: Tokens,
) -> Fragment {
let this = ¶ms.this;
match field.attrs.deserialize_with() {
@@ -1223,17 +2024,17 @@ fn deserialize_untagged_newtype_variant(
let field_ty = &field.ty;
quote_expr! {
_serde::export::Result::map(
<#field_ty as _serde::Deserialize>::deserialize(#deserializer),
#this::#variant_ident)
}
}
Some(path) => {
- let (wrapper, wrapper_ty) = wrap_deserialize_with(params, field.ty, path);
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(params, field.ty, path);
quote_block! {
#wrapper
_serde::export::Result::map(
<#wrapper_ty as _serde::Deserialize>::deserialize(#deserializer),
|__wrapper| #this::#variant_ident(__wrapper.value))
}
}
}
@@ -1336,28 +2137,29 @@ fn deserialize_custom_identifier(
} else {
let fields = quote! {
const FIELDS: &'static [&'static str] = &[ #(#names),* ];
};
Some(fields)
};
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+ let delife = params.borrowed.de_lifetime();
let visitor_impl =
Stmts(deserialize_identifier(this.clone(), &names_idents, is_variant, fallthrough),);
quote_block! {
#names_const
struct __FieldVisitor #de_impl_generics #where_clause {
marker: _serde::export::PhantomData<#this #ty_generics>,
- lifetime: _serde::export::PhantomData<&'de ()>,
+ lifetime: _serde::export::PhantomData<&#delife ()>,
}
- impl #de_impl_generics _serde::de::Visitor<'de> for __FieldVisitor #de_ty_generics #where_clause {
+ impl #de_impl_generics _serde::de::Visitor<#delife> for __FieldVisitor #de_ty_generics #where_clause {
type Value = #this #ty_generics;
#visitor_impl
}
let __visitor = __FieldVisitor {
marker: _serde::export::PhantomData::<#this #ty_generics>,
lifetime: _serde::export::PhantomData,
@@ -1381,36 +2183,37 @@ fn deserialize_identifier(
.collect();
let expecting = if is_variant {
"variant identifier"
} else {
"field identifier"
};
- let visit_index = if is_variant {
- let variant_indices = 0u32..;
- let fallthrough_msg = format!("variant index 0 <= i < {}", fields.len());
- let visit_index = quote! {
- fn visit_u32<__E>(self, __value: u32) -> _serde::export::Result<Self::Value, __E>
- where __E: _serde::de::Error
- {
- match __value {
- #(
- #variant_indices => _serde::export::Ok(#constructors),
- )*
- _ => _serde::export::Err(_serde::de::Error::invalid_value(
- _serde::de::Unexpected::Unsigned(__value as u64),
- &#fallthrough_msg))
- }
+ let index_expecting = if is_variant {
+ "variant"
+ } else {
+ "field"
+ };
+
+ let variant_indices = 0u64..;
+ let fallthrough_msg = format!("{} index 0 <= i < {}", index_expecting, fields.len());
+ let visit_index = quote! {
+ fn visit_u64<__E>(self, __value: u64) -> _serde::export::Result<Self::Value, __E>
+ where __E: _serde::de::Error
+ {
+ match __value {
+ #(
+ #variant_indices => _serde::export::Ok(#constructors),
+ )*
+ _ => _serde::export::Err(_serde::de::Error::invalid_value(
+ _serde::de::Unexpected::Unsigned(__value),
+ &#fallthrough_msg))
}
- };
- Some(visit_index)
- } else {
- None
+ }
};
let bytes_to_str = if fallthrough.is_some() {
None
} else {
let conversion = quote! {
let __value = &_serde::export::from_utf8_lossy(__value);
};
@@ -1525,17 +2328,17 @@ fn deserialize_map(
let visit = match field.attrs.deserialize_with() {
None => {
let field_ty = &field.ty;
quote! {
try!(_serde::de::MapAccess::next_value::<#field_ty>(&mut __map))
}
}
Some(path) => {
- let (wrapper, wrapper_ty) = wrap_deserialize_with(
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
params, field.ty, path);
quote!({
#wrapper
try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
})
}
};
quote! {
@@ -1650,55 +2453,288 @@ fn deserialize_map(
#let_default
#(#extract_values)*
_serde::export::Ok(#result)
}
}
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_struct_visitor(
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+) -> (Fragment, Fragment, Fragment) {
+ let field_names_idents: Vec<_> = fields
+ .iter()
+ .enumerate()
+ .filter(|&(_, field)| !field.attrs.skip_deserializing())
+ .map(|(i, field)| (field.attrs.name().deserialize_name(), field_i(i)),)
+ .collect();
+
+ let fields_stmt = {
+ let field_names = field_names_idents.iter().map(|&(ref name, _)| name);
+ quote_block! {
+ const FIELDS: &'static [&'static str] = &[ #(#field_names),* ];
+ }
+ };
+
+ let field_visitor = deserialize_generated_identifier(field_names_idents, cattrs, false);
+
+ let visit_map = deserialize_from_map(params, fields, cattrs);
+
+ (field_visitor, fields_stmt, visit_map)
+}
+
+#[cfg(feature = "deserialize_from")]
+fn deserialize_from_map(
+ params: &Parameters,
+ fields: &[Field],
+ cattrs: &attr::Container,
+) -> Fragment {
+ // Create the field names for the fields.
+ let fields_names: Vec<_> = fields
+ .iter()
+ .enumerate()
+ .map(|(i, field)| (field, field_i(i)))
+ .collect();
+
+ // For deserialize_from, declare booleans for each field that will be deserialized.
+ let let_flags = fields_names
+ .iter()
+ .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+ .map(
+ |&(_, ref name)| {
+ quote! {
+ let mut #name: bool = false;
+ }
+ },
+ );
+
+ // Match arms to extract a value for a field.
+ let value_arms_from = fields_names.iter()
+ .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+ .map(|&(field, ref name)| {
+ let deser_name = field.attrs.name().deserialize_name();
+ let field_name = &field.ident;
+
+ let visit = match field.attrs.deserialize_with() {
+ None => {
+ quote! {
+ try!(_serde::de::MapAccess::next_value_seed(&mut __map, _serde::private::de::DeserializeFromSeed(&mut self.dest.#field_name)))
+ }
+ }
+ Some(path) => {
+ let (wrapper, wrapper_ty) = wrap_deserialize_field_with(
+ params, field.ty, path);
+ quote!({
+ #wrapper
+ self.dest.#field_name = try!(_serde::de::MapAccess::next_value::<#wrapper_ty>(&mut __map)).value
+ })
+ }
+ };
+ quote! {
+ __Field::#name => {
+ if #name {
+ return _serde::export::Err(<__A::Error as _serde::de::Error>::duplicate_field(#deser_name));
+ }
+ #visit;
+ #name = true;
+ }
+ }
+ });
+
+ // Visit ignored values to consume them
+ let ignored_arm = if cattrs.deny_unknown_fields() {
+ None
+ } else {
+ Some(quote! {
+ _ => { let _ = try!(_serde::de::MapAccess::next_value::<_serde::de::IgnoredAny>(&mut __map)); }
+ })
+ };
+
+ let all_skipped = fields
+ .iter()
+ .all(|field| field.attrs.skip_deserializing());
+
+ let match_keys = if cattrs.deny_unknown_fields() && all_skipped {
+ quote! {
+ // FIXME: Once we drop support for Rust 1.15:
+ // let _serde::export::None::<__Field> = try!(_serde::de::MapAccess::next_key(&mut __map));
+ _serde::export::Option::map(
+ try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)),
+ |__impossible| match __impossible {});
+ }
+ } else {
+ quote! {
+ while let _serde::export::Some(__key) = try!(_serde::de::MapAccess::next_key::<__Field>(&mut __map)) {
+ match __key {
+ #(#value_arms_from)*
+ #ignored_arm
+ }
+ }
+ }
+ };
+
+ let check_flags = fields_names
+ .iter()
+ .filter(|&&(field, _)| !field.attrs.skip_deserializing())
+ .map(
+ |&(field, ref name)| {
+ let missing_expr = Expr(expr_is_missing(&field, cattrs));
+ let field_name = &field.ident;
+ quote! {
+ if !#name {
+ self.dest.#field_name = #missing_expr;
+ };
+ }
+ },
+ );
+
+ let this = ¶ms.this;
+ let (_, _, ty_generics, _) = split_with_de_lifetime(params,);
+
+ let let_default = match *cattrs.default() {
+ attr::Default::Default => {
+ Some(
+ quote!(
+ let __default: #this #ty_generics = _serde::export::Default::default();
+ ),
+ )
+ }
+ attr::Default::Path(ref path) => {
+ Some(
+ quote!(
+ let __default: #this #ty_generics = #path();
+ ),
+ )
+ }
+ attr::Default::None => {
+ // We don't need the default value, to prevent an unused variable warning
+ // we'll leave the line empty.
+ None
+ }
+ };
+
+ quote_block! {
+ #(#let_flags)*
+
+ #match_keys
+
+ #let_default
+
+ #(#check_flags)*
+
+ _serde::export::Ok(())
+ }
+}
+
fn field_i(i: usize) -> Ident {
Ident::new(format!("__field{}", i))
}
/// This function wraps the expression in `#[serde(deserialize_with = "...")]`
/// in a trait to prevent it from accessing the internal `Deserialize` state.
fn wrap_deserialize_with(
params: &Parameters,
- field_ty: &syn::Ty,
+ value_ty: Tokens,
deserialize_with: &syn::Path,
) -> (Tokens, Tokens) {
let this = ¶ms.this;
let (de_impl_generics, de_ty_generics, ty_generics, where_clause) = split_with_de_lifetime(params,);
+ let delife = params.borrowed.de_lifetime();
let wrapper = quote! {
struct __DeserializeWith #de_impl_generics #where_clause {
- value: #field_ty,
+ value: #value_ty,
phantom: _serde::export::PhantomData<#this #ty_generics>,
- lifetime: _serde::export::PhantomData<&'de ()>,
+ lifetime: _serde::export::PhantomData<&#delife ()>,
}
- impl #de_impl_generics _serde::Deserialize<'de> for __DeserializeWith #de_ty_generics #where_clause {
+ impl #de_impl_generics _serde::Deserialize<#delife> for __DeserializeWith #de_ty_generics #where_clause {
fn deserialize<__D>(__deserializer: __D) -> _serde::export::Result<Self, __D::Error>
- where __D: _serde::Deserializer<'de>
+ where __D: _serde::Deserializer<#delife>
{
_serde::export::Ok(__DeserializeWith {
value: try!(#deserialize_with(__deserializer)),
phantom: _serde::export::PhantomData,
lifetime: _serde::export::PhantomData,
})
}
}
};
let wrapper_ty = quote!(__DeserializeWith #de_ty_generics);
(wrapper, wrapper_ty)
}
+fn wrap_deserialize_field_with(
+ params: &Parameters,
+ field_ty: &syn::Ty,
+ deserialize_with: &syn::Path,
+) -> (Tokens, Tokens) {
+ wrap_deserialize_with(params, quote!(#field_ty), deserialize_with)
+}
+
+fn wrap_deserialize_variant_with(
+ params: &Parameters,
+ variant: &Variant,
+ deserialize_with: &syn::Path,
+) -> (Tokens, Tokens, Tokens) {
+ let this = ¶ms.this;
+ let variant_ident = &variant.ident;
+
+ let field_tys = variant.fields.iter().map(|field| field.ty);
+ let (wrapper, wrapper_ty) =
+ wrap_deserialize_with(params, quote!((#(#field_tys),*)), deserialize_with);
+
+ let field_access = (0..variant.fields.len()).map(|n| Ident::new(format!("{}", n)));
+ let unwrap_fn = match variant.style {
+ Style::Struct => {
+ let field_idents = variant.fields.iter().map(|field| field.ident.as_ref().unwrap());
+ quote! {
+ {
+ |__wrap| {
+ #this::#variant_ident { #(#field_idents: __wrap.value.#field_access),* }
+ }
+ }
+ }
+ }
+ Style::Tuple => {
+ quote! {
+ {
+ |__wrap| {
+ #this::#variant_ident(#(__wrap.value.#field_access),*)
+ }
+ }
+ }
+ }
+ Style::Newtype => {
+ quote! {
+ {
+ |__wrap| {
+ #this::#variant_ident(__wrap.value)
+ }
+ }
+ }
+ }
+ Style::Unit => {
+ quote! {
+ {
+ |__wrap| { #this::#variant_ident }
+ }
+ }
+ }
+ };
+
+ (wrapper, wrapper_ty, unwrap_fn)
+}
+
fn expr_is_missing(field: &Field, cattrs: &attr::Container) -> Fragment {
match *field.attrs.default() {
attr::Default::Default => {
return quote_expr!(_serde::export::Default::default());
}
attr::Default::Path(ref path) => {
return quote_expr!(#path());
}
@@ -1725,38 +2761,110 @@ fn expr_is_missing(field: &Field, cattrs
quote_expr! {
return _serde::export::Err(<__A::Error as _serde::de::Error>::missing_field(#name))
}
}
}
}
struct DeImplGenerics<'a>(&'a Parameters);
+#[cfg(feature = "deserialize_from")]
+struct DeFromImplGenerics<'a>(&'a Parameters);
impl<'a> ToTokens for DeImplGenerics<'a> {
fn to_tokens(&self, tokens: &mut Tokens) {
let mut generics = self.0.generics.clone();
- generics.lifetimes.insert(0, self.0.de_lifetime_def());
+ if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
+ generics.lifetimes.insert(0, de_lifetime);
+ }
+ let (impl_generics, _, _) = generics.split_for_impl();
+ impl_generics.to_tokens(tokens);
+ }
+}
+
+#[cfg(feature = "deserialize_from")]
+impl<'a> ToTokens for DeFromImplGenerics<'a> {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ let dest_lifetime = dest_lifetime();
+ let mut generics = self.0.generics.clone();
+
+ // Add lifetime for `&'dest mut Self, and `'a: 'dest`
+ for lifetime in &mut generics.lifetimes {
+ lifetime.bounds.push(dest_lifetime.lifetime.clone());
+ }
+ for generic in &mut generics.ty_params {
+ generic.bounds.push(syn::TyParamBound::Region(dest_lifetime.lifetime.clone()));
+ }
+ generics.lifetimes.insert(0, dest_lifetime);
+ if let Some(de_lifetime) = self.0.borrowed.de_lifetime_def() {
+ generics.lifetimes.insert(0, de_lifetime);
+ }
let (impl_generics, _, _) = generics.split_for_impl();
impl_generics.to_tokens(tokens);
}
}
-struct DeTyGenerics<'a>(&'a syn::Generics);
+#[cfg(feature = "deserialize_from")]
+impl<'a> DeImplGenerics<'a> {
+ fn with_dest(&self) -> DeFromImplGenerics<'a> {
+ DeFromImplGenerics(self.0)
+ }
+}
+
+struct DeTyGenerics<'a>(&'a Parameters);
+#[cfg(feature = "deserialize_from")]
+struct DeFromTyGenerics<'a>(&'a Parameters);
impl<'a> ToTokens for DeTyGenerics<'a> {
fn to_tokens(&self, tokens: &mut Tokens) {
- let mut generics = self.0.clone();
- generics
- .lifetimes
- .insert(0, syn::LifetimeDef::new("'de"));
+ let mut generics = self.0.generics.clone();
+ if self.0.borrowed.de_lifetime_def().is_some() {
+ generics
+ .lifetimes
+ .insert(0, syn::LifetimeDef::new("'de"));
+ }
let (_, ty_generics, _) = generics.split_for_impl();
ty_generics.to_tokens(tokens);
}
}
+#[cfg(feature = "deserialize_from")]
+impl<'a> ToTokens for DeFromTyGenerics<'a> {
+ fn to_tokens(&self, tokens: &mut Tokens) {
+ let mut generics = self.0.generics.clone();
+ generics.lifetimes.insert(0, dest_lifetime());
+
+ if self.0.borrowed.de_lifetime_def().is_some() {
+ generics
+ .lifetimes
+ .insert(0, syn::LifetimeDef::new("'de"));
+ }
+ let (_, ty_generics, _) = generics.split_for_impl();
+ ty_generics.to_tokens(tokens);
+ }
+}
+
+#[cfg(feature = "deserialize_from")]
+impl<'a> DeTyGenerics<'a> {
+ fn with_dest(&self) -> DeFromTyGenerics<'a> {
+ DeFromTyGenerics(self.0)
+ }
+}
+
+#[cfg(feature = "deserialize_from")]
+fn dest_lifetime() -> syn::LifetimeDef {
+ syn::LifetimeDef::new("'dest")
+}
+
fn split_with_de_lifetime(params: &Parameters,)
-> (DeImplGenerics, DeTyGenerics, syn::TyGenerics, &syn::WhereClause) {
let de_impl_generics = DeImplGenerics(¶ms);
- let de_ty_generics = DeTyGenerics(¶ms.generics);
+ let de_ty_generics = DeTyGenerics(¶ms);
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
(de_impl_generics, de_ty_generics, ty_generics, where_clause)
}
+
+fn is_unit(variant: &Variant) -> bool {
+ match variant.style {
+ Style::Unit => true,
+ Style::Struct | Style::Tuple | Style::Newtype => false,
+ }
+}
--- a/third_party/rust/serde_derive/src/lib.rs
+++ b/third_party/rust/serde_derive/src/lib.rs
@@ -3,25 +3,31 @@
// 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 Serde's two derive macros.
//!
-//! ```rust,ignore
+//! ```rust
+//! # #[macro_use]
+//! # extern crate serde_derive;
+//! #
//! #[derive(Serialize, Deserialize)]
+//! # struct S;
+//! #
+//! # fn main() {}
//! ```
//!
//! Please refer to [https://serde.rs/derive.html] for how to set this up.
//!
//! [https://serde.rs/derive.html]: https://serde.rs/derive.html
-#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.8")]
+#![doc(html_root_url = "https://docs.rs/serde_derive/1.0.23")]
#![cfg_attr(feature = "cargo-clippy", allow(too_many_arguments))]
#![cfg_attr(feature = "cargo-clippy", allow(used_underscore_binding))]
// The `quote!` macro requires deep recursion.
#![recursion_limit = "192"]
extern crate syn;
--- a/third_party/rust/serde_derive/src/ser.rs
+++ b/third_party/rust/serde_derive/src/ser.rs
@@ -24,19 +24,20 @@ pub fn expand_derive_serialize(input: &s
let ident = &cont.ident;
let params = Parameters::new(&cont);
let (impl_generics, ty_generics, where_clause) = params.generics.split_for_impl();
let dummy_const = Ident::new(format!("_IMPL_SERIALIZE_FOR_{}", ident));
let body = Stmts(serialize_body(&cont, ¶ms));
let impl_block = if let Some(remote) = cont.attrs.remote() {
+ let vis = &input.vis;
quote! {
impl #impl_generics #ident #ty_generics #where_clause {
- fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
+ #vis fn serialize<__S>(__self: &#remote #ty_generics, __serializer: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer
{
#body
}
}
}
} else {
quote! {
@@ -137,30 +138,34 @@ fn build_generics(cont: &Container) -> s
&generics,
needs_serialize_bound,
&path!(_serde::Serialize),
)
}
}
}
-// Fields with a `skip_serializing` or `serialize_with` attribute are not
-// serialized by us so we do not generate a bound. Fields with a `bound`
-// attribute specify their own bound so we do not generate one. All other fields
-// may need a `T: Serialize` bound where T is the type of the field.
-fn needs_serialize_bound(attrs: &attr::Field) -> bool {
- !attrs.skip_serializing() && attrs.serialize_with().is_none() && attrs.ser_bound().is_none()
+// Fields with a `skip_serializing` or `serialize_with` attribute, or which
+// belong to a variant with a `serialize_with` attribute, are not serialized by
+// us so we do not generate a bound. Fields with a `bound` attribute specify
+// their own bound so we do not generate one. All other fields may need a `T:
+// Serialize` bound where T is the type of the field.
+fn needs_serialize_bound(field: &attr::Field, variant: Option<&attr::Variant>) -> bool {
+ !field.skip_serializing() &&
+ field.serialize_with().is_none() &&
+ field.ser_bound().is_none() &&
+ variant.map_or(true, |variant| variant.serialize_with().is_none())
}
fn serialize_body(cont: &Container, params: &Parameters) -> Fragment {
if let Some(into_type) = cont.attrs.into_type() {
serialize_into(params, into_type)
} else {
match cont.body {
- Body::Enum(ref variants) => serialize_enum(params, variants, &cont.attrs),
+ Body::Enum(_, ref variants) => serialize_enum(params, variants, &cont.attrs),
Body::Struct(Style::Struct, ref fields) => {
if fields.iter().any(|field| field.ident.is_none()) {
panic!("struct has unnamed fields");
}
serialize_struct(params, fields, &cont.attrs)
}
Body::Struct(Style::Tuple, ref fields) => {
if fields.iter().any(|field| field.ident.is_some()) {
@@ -197,17 +202,17 @@ fn serialize_newtype_struct(
params: &Parameters,
field: &Field,
cattrs: &attr::Container,
) -> Fragment {
let type_name = cattrs.name().serialize_name();
let mut field_expr = get_field(params, field, 0);
if let Some(path) = field.attrs.serialize_with() {
- field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+ field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
}
quote_expr! {
_serde::Serializer::serialize_newtype_struct(__serializer, #type_name, #field_expr)
}
}
fn serialize_tuple_struct(
@@ -236,16 +241,17 @@ fn serialize_tuple_struct(
fn serialize_struct(params: &Parameters, fields: &[Field], cattrs: &attr::Container) -> Fragment {
assert!(fields.len() as u64 <= u32::MAX as u64);
let serialize_fields = serialize_struct_visitor(
fields,
params,
false,
quote!(_serde::ser::SerializeStruct::serialize_field),
+ quote!(_serde::ser::SerializeStruct::skip_field),
);
let type_name = cattrs.name().serialize_name();
let mut serialized_fields = fields
.iter()
.filter(|&field| !field.attrs.skip_serializing())
.peekable();
@@ -389,32 +395,45 @@ fn serialize_externally_tagged_variant(
params: &Parameters,
variant: &Variant,
variant_index: u32,
cattrs: &attr::Container,
) -> Fragment {
let type_name = cattrs.name().serialize_name();
let variant_name = variant.attrs.name().serialize_name();
+ if let Some(path) = variant.attrs.serialize_with() {
+ let ser = wrap_serialize_variant_with(params, path, &variant);
+ return quote_expr! {
+ _serde::Serializer::serialize_newtype_variant(
+ __serializer,
+ #type_name,
+ #variant_index,
+ #variant_name,
+ #ser,
+ )
+ };
+ }
+
match variant.style {
Style::Unit => {
quote_expr! {
_serde::Serializer::serialize_unit_variant(
__serializer,
#type_name,
#variant_index,
#variant_name,
)
}
}
Style::Newtype => {
let field = &variant.fields[0];
let mut field_expr = quote!(__field0);
if let Some(path) = field.attrs.serialize_with() {
- field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+ field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
}
quote_expr! {
_serde::Serializer::serialize_newtype_variant(
__serializer,
#type_name,
#variant_index,
#variant_name,
@@ -454,31 +473,45 @@ fn serialize_internally_tagged_variant(
tag: &str,
) -> Fragment {
let type_name = cattrs.name().serialize_name();
let variant_name = variant.attrs.name().serialize_name();
let enum_ident_str = params.type_name();
let variant_ident_str = variant.ident.as_ref();
+ if let Some(path) = variant.attrs.serialize_with() {
+ let ser = wrap_serialize_variant_with(params, path, &variant);
+ return quote_expr! {
+ _serde::private::ser::serialize_tagged_newtype(
+ __serializer,
+ #enum_ident_str,
+ #variant_ident_str,
+ #tag,
+ #variant_name,
+ #ser,
+ )
+ };
+ }
+
match variant.style {
Style::Unit => {
quote_block! {
let mut __struct = try!(_serde::Serializer::serialize_struct(
__serializer, #type_name, 1));
try!(_serde::ser::SerializeStruct::serialize_field(
&mut __struct, #tag, #variant_name));
_serde::ser::SerializeStruct::end(__struct)
}
}
Style::Newtype => {
let field = &variant.fields[0];
let mut field_expr = quote!(__field0);
if let Some(path) = field.attrs.serialize_with() {
- field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+ field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
}
quote_expr! {
_serde::private::ser::serialize_tagged_newtype(
__serializer,
#enum_ident_str,
#variant_ident_str,
#tag,
@@ -509,54 +542,67 @@ fn serialize_adjacently_tagged_variant(
tag: &str,
content: &str,
) -> Fragment {
let this = ¶ms.this;
let type_name = cattrs.name().serialize_name();
let variant_name = variant.attrs.name().serialize_name();
let inner = Stmts(
- match variant.style {
- Style::Unit => {
- return quote_block! {
- let mut __struct = try!(_serde::Serializer::serialize_struct(
- __serializer, #type_name, 1));
- try!(_serde::ser::SerializeStruct::serialize_field(
- &mut __struct, #tag, #variant_name));
- _serde::ser::SerializeStruct::end(__struct)
- };
+ if let Some(path) = variant.attrs.serialize_with() {
+ let ser = wrap_serialize_variant_with(params, path, &variant);
+ quote_expr! {
+ _serde::Serialize::serialize(#ser, __serializer)
}
- Style::Newtype => {
- let field = &variant.fields[0];
- let mut field_expr = quote!(__field0);
- if let Some(path) = field.attrs.serialize_with() {
- field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+ } else {
+ match variant.style {
+ Style::Unit => {
+ return quote_block! {
+ let mut __struct = try!(_serde::Serializer::serialize_struct(
+ __serializer, #type_name, 1));
+ try!(_serde::ser::SerializeStruct::serialize_field(
+ &mut __struct, #tag, #variant_name));
+ _serde::ser::SerializeStruct::end(__struct)
+ };
}
+ Style::Newtype => {
+ let field = &variant.fields[0];
+ let mut field_expr = quote!(__field0);
+ if let Some(path) = field.attrs.serialize_with() {
+ field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
+ }
- quote_expr! {
- _serde::Serialize::serialize(#field_expr, __serializer)
+ quote_expr! {
+ _serde::Serialize::serialize(#field_expr, __serializer)
+ }
}
- }
- Style::Tuple => {
- serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
- }
- Style::Struct => {
- serialize_struct_variant(
- StructVariant::Untagged,
- params,
- &variant.fields,
- &variant_name,
- )
+ Style::Tuple => {
+ serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields)
+ }
+ Style::Struct => {
+ serialize_struct_variant(
+ StructVariant::Untagged,
+ params,
+ &variant.fields,
+ &variant_name,
+ )
+ }
}
},
);
let fields_ty = variant.fields.iter().map(|f| &f.ty);
let ref fields_ident: Vec<_> = match variant.style {
- Style::Unit => unreachable!(),
+ Style::Unit => {
+ if variant.attrs.serialize_with().is_some() {
+ vec![]
+ } else {
+ unreachable!()
+ }
+ }
Style::Newtype => vec![Ident::new("__field0")],
Style::Tuple => {
(0..variant.fields.len())
.map(|i| Ident::new(format!("__field{}", i)))
.collect()
}
Style::Struct => {
variant
@@ -570,17 +616,21 @@ fn serialize_adjacently_tagged_variant(
},
)
.collect()
}
};
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
- let wrapper_generics = bound::with_lifetime_bound(¶ms.generics, "'__a");
+ let wrapper_generics = if let Style::Unit = variant.style {
+ params.generics.clone()
+ } else {
+ bound::with_lifetime_bound(¶ms.generics, "'__a")
+ };
let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
quote_block! {
struct __AdjacentlyTagged #wrapper_generics #where_clause {
data: (#(&'__a #fields_ty,)*),
phantom: _serde::export::PhantomData<#this #ty_generics>,
}
@@ -606,27 +656,34 @@ fn serialize_adjacently_tagged_variant(
}
}
fn serialize_untagged_variant(
params: &Parameters,
variant: &Variant,
cattrs: &attr::Container,
) -> Fragment {
+ if let Some(path) = variant.attrs.serialize_with() {
+ let ser = wrap_serialize_variant_with(params, path, &variant);
+ return quote_expr! {
+ _serde::Serialize::serialize(#ser, __serializer)
+ };
+ }
+
match variant.style {
Style::Unit => {
quote_expr! {
_serde::Serializer::serialize_unit(__serializer)
}
}
Style::Newtype => {
let field = &variant.fields[0];
let mut field_expr = quote!(__field0);
if let Some(path) = field.attrs.serialize_with() {
- field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+ field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
}
quote_expr! {
_serde::Serialize::serialize(#field_expr, __serializer)
}
}
Style::Tuple => serialize_tuple_variant(TupleVariant::Untagged, params, &variant.fields),
Style::Struct => {
@@ -701,25 +758,33 @@ enum StructVariant<'a> {
}
fn serialize_struct_variant<'a>(
context: StructVariant<'a>,
params: &Parameters,
fields: &[Field],
name: &str,
) -> Fragment {
- let method = match context {
+ let (method, skip_method) = match context {
StructVariant::ExternallyTagged { .. } => {
- quote!(_serde::ser::SerializeStructVariant::serialize_field)
+ (
+ quote!(_serde::ser::SerializeStructVariant::serialize_field),
+ quote!(_serde::ser::SerializeStructVariant::skip_field),
+ )
}
StructVariant::InternallyTagged { .. } |
- StructVariant::Untagged => quote!(_serde::ser::SerializeStruct::serialize_field),
+ StructVariant::Untagged => {
+ (
+ quote!(_serde::ser::SerializeStruct::serialize_field),
+ quote!(_serde::ser::SerializeStruct::skip_field),
+ )
+ }
};
- let serialize_fields = serialize_struct_visitor(fields, params, true, method);
+ let serialize_fields = serialize_struct_visitor(fields, params, true, method, skip_method);
let mut serialized_fields = fields
.iter()
.filter(|&field| !field.attrs.skip_serializing())
.peekable();
let let_mut = mut_if(serialized_fields.peek().is_some());
@@ -802,17 +867,17 @@ fn serialize_tuple_struct_visitor(
};
let skip = field
.attrs
.skip_serializing_if()
.map(|path| quote!(#path(#field_expr)));
if let Some(path) = field.attrs.serialize_with() {
- field_expr = wrap_serialize_with(params, field.ty, path, field_expr);
+ field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
}
let ser = quote! {
try!(#func(&mut __serde_state, #field_expr));
};
match skip {
None => ser,
@@ -823,16 +888,17 @@ fn serialize_tuple_struct_visitor(
.collect()
}
fn serialize_struct_visitor(
fields: &[Field],
params: &Parameters,
is_enum: bool,
func: Tokens,
+ skip_func: Tokens,
) -> Vec<Tokens> {
fields
.iter()
.filter(|&field| !field.attrs.skip_serializing())
.map(
|field| {
let field_ident = field.ident.clone().expect("struct has unnamed field");
let mut field_expr = if is_enum {
@@ -844,60 +910,103 @@ fn serialize_struct_visitor(
let key_expr = field.attrs.name().serialize_name();
let skip = field
.attrs
.skip_serializing_if()
.map(|path| quote!(#path(#field_expr)));
if let Some(path) = field.attrs.serialize_with() {
- field_expr = wrap_serialize_with(params, field.ty, path, field_expr)
+ field_expr = wrap_serialize_field_with(params, field.ty, path, field_expr);
}
let ser = quote! {
try!(#func(&mut __serde_state, #key_expr, #field_expr));
};
match skip {
None => ser,
- Some(skip) => quote!(if !#skip { #ser }),
+ Some(skip) => {
+ quote! {
+ if !#skip {
+ #ser
+ } else {
+ try!(#skip_func(&mut __serde_state, #key_expr));
+ }
+ }
+ }
}
},
)
.collect()
}
-fn wrap_serialize_with(
+fn wrap_serialize_field_with(
params: &Parameters,
field_ty: &syn::Ty,
serialize_with: &syn::Path,
- value: Tokens,
+ field_expr: Tokens,
+) -> Tokens {
+ wrap_serialize_with(params,
+ serialize_with,
+ &[field_ty],
+ &[quote!(#field_expr)])
+}
+
+fn wrap_serialize_variant_with(
+ params: &Parameters,
+ serialize_with: &syn::Path,
+ variant: &Variant,
+) -> Tokens {
+ let field_tys: Vec<_> = variant.fields.iter().map(|field| field.ty).collect();
+ let field_exprs: Vec<_> = variant.fields.iter()
+ .enumerate()
+ .map(|(i, field)| {
+ let id = field.ident.as_ref().map_or_else(|| Ident::new(format!("__field{}", i)),
+ |id| id.clone());
+ quote!(#id)
+ })
+ .collect();
+ wrap_serialize_with(params, serialize_with, field_tys.as_slice(), field_exprs.as_slice())
+}
+
+fn wrap_serialize_with(
+ params: &Parameters,
+ serialize_with: &syn::Path,
+ field_tys: &[&syn::Ty],
+ field_exprs: &[Tokens],
) -> Tokens {
let this = ¶ms.this;
let (_, ty_generics, where_clause) = params.generics.split_for_impl();
- let wrapper_generics = bound::with_lifetime_bound(¶ms.generics, "'__a");
+ let wrapper_generics = if field_exprs.len() == 0 {
+ params.generics.clone()
+ } else {
+ bound::with_lifetime_bound(¶ms.generics, "'__a")
+ };
let (wrapper_impl_generics, wrapper_ty_generics, _) = wrapper_generics.split_for_impl();
+ let field_access = (0..field_exprs.len()).map(|n| Ident::new(format!("{}", n)));
+
quote!({
struct __SerializeWith #wrapper_impl_generics #where_clause {
- value: &'__a #field_ty,
+ values: (#(&'__a #field_tys, )*),
phantom: _serde::export::PhantomData<#this #ty_generics>,
}
impl #wrapper_impl_generics _serde::Serialize for __SerializeWith #wrapper_ty_generics #where_clause {
fn serialize<__S>(&self, __s: __S) -> _serde::export::Result<__S::Ok, __S::Error>
where __S: _serde::Serializer
{
- #serialize_with(self.value, __s)
+ #serialize_with(#(self.values.#field_access, )* __s)
}
}
&__SerializeWith {
- value: #value,
+ values: (#(#field_exprs, )*),
phantom: _serde::export::PhantomData::<#this #ty_generics>,
}
})
}
// Serialization of an empty struct results in code like:
//
// let mut __serde_state = try!(serializer.serialize_struct("S", 0));
--- a/third_party/rust/serde_derive_internals/.cargo-checksum.json
+++ b/third_party/rust/serde_derive_internals/.cargo-checksum.json
@@ -1,1 +1,1 @@
-{"files":{"Cargo.toml":"511194979a2e34ebea7b27d4abe9350a6d6d2beb4ee074e296c5b95f4c8fc6e9","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"eedee04bddb61e99bc816656bb3b8ae2fa50ff00045ecdb5212682f3592d9ab2","src/ast.rs":"6d41e5055cc012474f72a2fb25874d8f59b872ccccddc2dee83ceaaa08135cd9","src/attr.rs":"bfd6120502807f8a5531a846fd76128ce133b9f9d162a6ea35e471afb73a3b20","src/case.rs":"036711fc550a405ab86d9470c94bac1d58dcdcad4e3a672c73cc0c5a0ecc138b","src/check.rs":"69ecc07d0916ae33ba868eb697ca35f7cd2e97127187f1e95efdcf7ad8e5e2f8","src/ctxt.rs":"98eab1acd3de8617b516d1de7d5d870bb1d2a1c1aca258a4cca2bde3f8df88e4","src/lib.rs":"7fef231c76b77486d813fa43a5dc7394fdeb8b1e95e02f5c1205213725ed400b"},"package":"37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"}
\ No newline at end of file
+{"files":{"Cargo.toml":"0435204d95404e25ee07fa3169ddf5eef26bde3fce03f4e63e9e55774d620199","LICENSE-APACHE":"a60eea817514531668d7e00765731449fe14d059d3249e0bc93b36de45f759f2","LICENSE-MIT":"6485b8ed310d3f0340bf1ad1f47645069ce4069dcc6bb46c7d5c6faf41de1fdb","README.md":"7dc6376a88195594cd6b43cb891aad10f57144ff737178b55d046aa04739b43a","src/ast.rs":"bc9936766227f78bf34cf003d271ffd70ad056e1272caafc1b185bdd32cc46bb","src/attr.rs":"51c92750f7b490a2c46950a68b5491d83181815d98e0fe3db102369b1ca9fe6e","src/case.rs":"be3288491dae43ca53643cb8409431e5e65ccf39c69c8047676e89c997827b0c","src/check.rs":"e976c9bac0daa334b2c82c6a91ac472235c7a1d91c5fe0deb2a83fe71b7c0663","src/ctxt.rs":"98eab1acd3de8617b516d1de7d5d870bb1d2a1c1aca258a4cca2bde3f8df88e4","src/lib.rs":"f242433bcb42c2360b8887d6e9f1b286a332080f1f0a081de06b0c061b563348"},"package":null}
\ No newline at end of file
--- a/third_party/rust/serde_derive_internals/Cargo.toml
+++ b/third_party/rust/serde_derive_internals/Cargo.toml
@@ -1,11 +1,11 @@
[package]
name = "serde_derive_internals"
-version = "0.15.1" # remember to update html_root_url
+version = "0.17.0" # remember to update html_root_url
authors = ["Erick Tryzelaar <erick.tryzelaar@gmail.com>", "David Tolnay <dtolnay@gmail.com>"]
license = "MIT/Apache-2.0"
description = "AST representation used by Serde derive macros. Unstable."
homepage = "https://serde.rs"
repository = "https://github.com/serde-rs/serde"
documentation = "https://docs.serde.rs/serde_derive_internals/"
keywords = ["serde", "serialization"]
readme = "README.md"
--- a/third_party/rust/serde_derive_internals/README.md
+++ b/third_party/rust/serde_derive_internals/README.md
@@ -15,19 +15,40 @@ You may be looking for:
- [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>
+<details>
+<summary>
+Click to show Cargo.toml.
+<a href="http://play.integer32.com/?gist=9003c5b88c1f4989941925d7190c6eec" target="_blank">Run this code in the playground.</a>
+</summary>
+
+```toml
+[dependencies]
+
+# The core APIs, including the Serialize and Deserialize traits. Always
+# required when using Serde.
+serde = "1.0"
+
+# Support for #[derive(Serialize, Deserialize)]. Required if you want Serde
+# to work for structs and enums defined in your crate.
+serde_derive = "1.0"
+
+# Each data format lives in its own crate; the sample code below uses JSON
+# but you may be using a different one.
+serde_json = "1.0"
+```
+
+</details>
+<p></p>
```rust
#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
--- a/third_party/rust/serde_derive_internals/src/ast.rs
+++ b/third_party/rust/serde_derive_internals/src/ast.rs
@@ -14,61 +14,69 @@ use Ctxt;
pub struct Container<'a> {
pub ident: syn::Ident,
pub attrs: attr::Container,
pub body: Body<'a>,
pub generics: &'a syn::Generics,
}
pub enum Body<'a> {
- Enum(Vec<Variant<'a>>),
+ Enum(Repr, Vec<Variant<'a>>),
Struct(Style, Vec<Field<'a>>),
}
pub struct Variant<'a> {
pub ident: syn::Ident,
pub attrs: attr::Variant,
pub style: Style,
pub fields: Vec<Field<'a>>,
}
pub struct Field<'a> {
pub ident: Option<syn::Ident>,
pub attrs: attr::Field,
pub ty: &'a syn::Ty,
}
+pub struct Repr {
+ pub int_repr: Option<&'static str>,
+ pub c_repr: bool,
+ pub other_repr: bool,
+}
+
#[derive(Copy, Clone)]
pub enum Style {
Struct,
Tuple,
Newtype,
Unit,
}
impl<'a> Container<'a> {
pub fn from_ast(cx: &Ctxt, item: &'a syn::DeriveInput) -> Container<'a> {
let attrs = attr::Container::from_ast(cx, item);
let mut body = match item.body {
- syn::Body::Enum(ref variants) => Body::Enum(enum_from_ast(cx, variants)),
+ syn::Body::Enum(ref variants) => enum_from_ast(cx, item, variants),
syn::Body::Struct(ref variant_data) => {
- let (style, fields) = struct_from_ast(cx, variant_data);
+ let (style, fields) = struct_from_ast(cx, variant_data, None);
Body::Struct(style, fields)
}
};
match body {
- Body::Enum(ref mut variants) => {
+ Body::Enum(_, ref mut variants) => {
for ref mut variant in variants {
variant.attrs.rename_by_rule(attrs.rename_all());
for ref mut field in &mut variant.fields {
field.attrs.rename_by_rule(variant.attrs.rename_all());
}
}
+
+
}
Body::Struct(_, ref mut fields) => {
for field in fields {
field.attrs.rename_by_rule(attrs.rename_all());
}
}
}
@@ -81,63 +89,125 @@ impl<'a> Container<'a> {
check::check(cx, &item);
item
}
}
impl<'a> Body<'a> {
pub fn all_fields(&'a self) -> Box<Iterator<Item = &'a Field<'a>> + 'a> {
match *self {
- Body::Enum(ref variants) => {
+ Body::Enum(_, ref variants) => {
Box::new(variants.iter().flat_map(|variant| variant.fields.iter()))
}
Body::Struct(_, ref fields) => Box::new(fields.iter()),
}
}
pub fn has_getter(&self) -> bool {
self.all_fields().any(|f| f.attrs.getter().is_some())
}
}
-fn enum_from_ast<'a>(cx: &Ctxt, variants: &'a [syn::Variant]) -> Vec<Variant<'a>> {
- variants
+impl Repr {
+ /// Gives the int type to use for the `repr(int)` enum layout
+ pub fn get_stable_rust_enum_layout(&self) -> Option<&'static str> {
+ if self.c_repr || self.other_repr {
+ None
+ } else {
+ self.int_repr
+ }
+ }
+
+ /// Gives the int type to use for the `repr(C, int)` enum layout
+ pub fn get_stable_c_enum_layout(&self) -> Option<&'static str> {
+ if !self.c_repr && self.other_repr {
+ None
+ } else {
+ self.int_repr
+ }
+ }
+}
+
+fn enum_from_ast<'a>(cx: &Ctxt, item: &'a syn::DeriveInput, variants: &'a [syn::Variant]) -> Body<'a> {
+ let variants = variants
.iter()
.map(
|variant| {
- let (style, fields) = struct_from_ast(cx, &variant.data);
+ let attrs = attr::Variant::from_ast(cx, variant);
+ let (style, fields) = struct_from_ast(cx, &variant.data, Some(&attrs));
Variant {
ident: variant.ident.clone(),
- attrs: attr::Variant::from_ast(cx, variant),
+ attrs: attrs,
style: style,
fields: fields,
}
},
)
- .collect()
+ .collect();
+
+ // Compute repr info for enum optimizations
+ static INT_TYPES: [&'static str; 12] = [
+ "u8", "u16", "u32", "u64", "u128", "usize",
+ "i8", "i16", "i32", "i64", "i128", "isize",
+ ];
+
+ let mut int_repr = None;
+ let mut c_repr = false;
+ let mut other_repr = false;
+
+ for attr in &item.attrs {
+ if let syn::MetaItem::List(ref ident, ref vals) = attr.value {
+ if *ident == "repr" {
+ // has_repr = true;
+ for repr in vals {
+ if let syn::NestedMetaItem::MetaItem(syn::MetaItem::Word(ref repr)) = *repr {
+ if repr == "C" {
+ c_repr = true;
+ } else if let Some(int_type) = INT_TYPES.iter().cloned().find(|int_type| repr == int_type) {
+ if int_repr.is_some() {
+ // This shouldn't happen, but we shouldn't crash if we see it.
+ // So just treat the enum as having a mysterious other repr,
+ // which makes us discard any attempt to optimize based on layout.
+ other_repr = true;
+ }
+ int_repr = Some(int_type);
+ } else {
+ other_repr = true;
+ }
+ } else {
+ panic!("impossible repr? {:?}", repr);
+ }
+ }
+ }
+ }
+ }
+
+ let repr = Repr { int_repr, c_repr, other_repr };
+
+ Body::Enum(repr, variants)
}
-fn struct_from_ast<'a>(cx: &Ctxt, data: &'a syn::VariantData) -> (Style, Vec<Field<'a>>) {
+fn struct_from_ast<'a>(cx: &Ctxt, data: &'a syn::VariantData, attrs: Option<&attr::Variant>) -> (Style, Vec<Field<'a>>) {
match *data {
- syn::VariantData::Struct(ref fields) => (Style::Struct, fields_from_ast(cx, fields)),
+ syn::VariantData::Struct(ref fields) => (Style::Struct, fields_from_ast(cx, fields, attrs)),
syn::VariantData::Tuple(ref fields) if fields.len() == 1 => {
- (Style::Newtype, fields_from_ast(cx, fields))
+ (Style::Newtype, fields_from_ast(cx, fields, attrs))
}
- syn::VariantData::Tuple(ref fields) => (Style::Tuple, fields_from_ast(cx, fields)),
+ syn::VariantData::Tuple(ref fields) => (Style::Tuple, fields_from_ast(cx, fields, attrs)),
syn::VariantData::Unit => (Style::Unit, Vec::new()),
}
}
-fn fields_from_ast<'a>(cx: &Ctxt, fields: &'a [syn::Field]) -> Vec<Field<'a>> {
+fn fields_from_ast<'a>(cx: &Ctxt, fields: &'a [syn::Field], attrs: Option<&attr::Variant>) -> Vec<Field<'a>> {
fields
.iter()
.enumerate()
.map(
|(i, field)| {
Field {
ident: field.ident.clone(),
- attrs: attr::Field::from_ast(cx, i, field),
+ attrs: attr::Field::from_ast(cx, i, field, attrs),
ty: &field.ty,
}
},
)
.collect()
}
--- a/third_party/rust/serde_derive_internals/src/attr.rs
+++ b/third_party/rust/serde_derive_internals/src/attr.rs
@@ -505,26 +505,32 @@ fn decide_identifier(
pub struct Variant {
name: Name,
ser_renamed: bool,
de_renamed: bool,
rename_all: RenameRule,
skip_deserializing: bool,
skip_serializing: bool,
other: bool,
+ serialize_with: Option<syn::Path>,
+ deserialize_with: Option<syn::Path>,
+ borrow: Option<syn::MetaItem>,
}
impl Variant {
pub fn from_ast(cx: &Ctxt, variant: &syn::Variant) -> Self {
let mut ser_name = Attr::none(cx, "rename");
let mut de_name = Attr::none(cx, "rename");
let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
let mut rename_all = Attr::none(cx, "rename_all");
let mut other = BoolAttr::none(cx, "other");
+ let mut serialize_with = Attr::none(cx, "serialize_with");
+ let mut deserialize_with = Attr::none(cx, "deserialize_with");
+ let mut borrow = Attr::none(cx, "borrow");
for meta_items in variant.attrs.iter().filter_map(get_serde_meta_items) {
for meta_item in meta_items {
match meta_item {
// Parse `#[serde(rename = "foo")]`
MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
ser_name.set(s.clone());
@@ -564,16 +570,54 @@ impl Variant {
skip_serializing.set_true();
}
// Parse `#[serde(other)]`
MetaItem(Word(ref name)) if name == "other" => {
other.set_true();
}
+ // Parse `#[serde(with = "...")]`
+ MetaItem(NameValue(ref name, ref lit)) if name == "with" => {
+ if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+ let mut ser_path = path.clone();
+ ser_path.segments.push("serialize".into());
+ serialize_with.set(ser_path);
+ let mut de_path = path;
+ de_path.segments.push("deserialize".into());
+ deserialize_with.set(de_path);
+ }
+ }
+
+ // Parse `#[serde(serialize_with = "...")]`
+ MetaItem(NameValue(ref name, ref lit)) if name == "serialize_with" => {
+ if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+ serialize_with.set(path);
+ }
+ }
+
+ // Parse `#[serde(deserialize_with = "...")]`
+ MetaItem(NameValue(ref name, ref lit)) if name == "deserialize_with" => {
+ if let Ok(path) = parse_lit_into_path(cx, name.as_ref(), lit) {
+ deserialize_with.set(path);
+ }
+ }
+
+ // Defer `#[serde(borrow)]` and `#[serde(borrow = "'a + 'b")]`
+ MetaItem(ref mi) if mi.name() == "borrow" => {
+ match variant.data {
+ syn::VariantData::Tuple(ref fields) if fields.len() == 1 => {
+ borrow.set(mi.clone());
+ }
+ _ => {
+ cx.error("#[serde(borrow)] may only be used on newtype variants");
+ }
+ }
+ }
+
MetaItem(ref meta_item) => {
cx.error(format!("unknown serde variant attribute `{}`", meta_item.name()));
}
Literal(_) => {
cx.error("unexpected literal in serde variant attribute");
}
}
@@ -590,16 +634,19 @@ impl Variant {
deserialize: de_name.unwrap_or_else(|| variant.ident.to_string()),
},
ser_renamed: ser_renamed,
de_renamed: de_renamed,
rename_all: rename_all.get().unwrap_or(RenameRule::None),
skip_deserializing: skip_deserializing.get(),
skip_serializing: skip_serializing.get(),
other: other.get(),
+ serialize_with: serialize_with.get(),
+ deserialize_with: deserialize_with.get(),
+ borrow: borrow.get(),
}
}
pub fn name(&self) -> &Name {
&self.name
}
pub fn rename_by_rule(&mut self, rule: &RenameRule) {
@@ -621,16 +668,24 @@ impl Variant {
pub fn skip_serializing(&self) -> bool {
self.skip_serializing
}
pub fn other(&self) -> bool {
self.other
}
+
+ pub fn serialize_with(&self) -> Option<&syn::Path> {
+ self.serialize_with.as_ref()
+ }
+
+ pub fn deserialize_with(&self) -> Option<&syn::Path> {
+ self.deserialize_with.as_ref()
+ }
}
/// Represents field attribute information
#[derive(Debug)]
pub struct Field {
name: Name,
ser_renamed: bool,
de_renamed: bool,
@@ -654,17 +709,17 @@ pub enum Default {
/// The default is given by `std::default::Default::default()`.
Default,
/// The default is given by this function.
Path(syn::Path),
}
impl Field {
/// Extract out the `#[serde(...)]` attributes from a struct field.
- pub fn from_ast(cx: &Ctxt, index: usize, field: &syn::Field) -> Self {
+ pub fn from_ast(cx: &Ctxt, index: usize, field: &syn::Field, attrs: Option<&Variant>) -> Self {
let mut ser_name = Attr::none(cx, "rename");
let mut de_name = Attr::none(cx, "rename");
let mut skip_serializing = BoolAttr::none(cx, "skip_serializing");
let mut skip_deserializing = BoolAttr::none(cx, "skip_deserializing");
let mut skip_serializing_if = Attr::none(cx, "skip_serializing_if");
let mut default = Attr::none(cx, "default");
let mut serialize_with = Attr::none(cx, "serialize_with");
let mut deserialize_with = Attr::none(cx, "deserialize_with");
@@ -673,17 +728,23 @@ impl Field {
let mut borrowed_lifetimes = Attr::none(cx, "borrow");
let mut getter = Attr::none(cx, "getter");
let ident = match field.ident {
Some(ref ident) => ident.to_string(),
None => index.to_string(),
};
- for meta_items in field.attrs.iter().filter_map(get_serde_meta_items) {
+ let variant_borrow = attrs
+ .map(|variant| &variant.borrow)
+ .unwrap_or(&None)
+ .as_ref()
+ .map(|borrow| vec![MetaItem(borrow.clone())]);
+
+ for meta_items in field.attrs.iter().filter_map(get_serde_meta_items).chain(variant_borrow) {
for meta_item in meta_items {
match meta_item {
// Parse `#[serde(rename = "foo")]`
MetaItem(NameValue(ref name, ref lit)) if name == "rename" => {
if let Ok(s) = get_string_from_lit(cx, name.as_ref(), name.as_ref(), lit) {
ser_name.set(s.clone());
de_name.set(s);
}
--- a/third_party/rust/serde_derive_internals/src/case.rs
+++ b/third_party/rust/serde_derive_internals/src/case.rs
@@ -1,17 +1,20 @@
// 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.
+// See https://users.rust-lang.org/t/psa-dealing-with-warning-unused-import-std-ascii-asciiext-in-today-s-nightly/13726
+#[allow(unused_imports)]
use std::ascii::AsciiExt;
+
use std::str::FromStr;
use self::RenameRule::*;
#[derive(Debug, PartialEq)]
pub enum RenameRule {
/// Don't apply a default rename rule.
None,
@@ -22,16 +25,18 @@ pub enum RenameRule {
/// Rename direct children to "camelCase" style.
CamelCase,
/// Rename direct children to "snake_case" style, as commonly used for fields.
SnakeCase,
/// Rename direct children to "SCREAMING_SNAKE_CASE" style, as commonly used for constants.
ScreamingSnakeCase,
/// Rename direct children to "kebab-case" style.
KebabCase,
+ /// Rename direct children to "SCREAMING-KEBAB-CASE" style.
+ ScreamingKebabCase
}
impl RenameRule {
pub fn apply_to_variant(&self, variant: &str) -> String {
match *self {
None | PascalCase => variant.to_owned(),
LowerCase => variant.to_ascii_lowercase(),
CamelCase => variant[..1].to_ascii_lowercase() + &variant[1..],
@@ -42,16 +47,17 @@ impl RenameRule {
snake.push('_');
}
snake.push(ch.to_ascii_lowercase());
}
snake
}
ScreamingSnakeCase => SnakeCase.apply_to_variant(variant).to_ascii_uppercase(),
KebabCase => SnakeCase.apply_to_variant(variant).replace('_', "-"),
+ ScreamingKebabCase => ScreamingSnakeCase.apply_to_variant(variant).replace('_', "-")
}
}
pub fn apply_to_field(&self, field: &str) -> String {
match *self {
None | LowerCase | SnakeCase => field.to_owned(),
PascalCase => {
let mut pascal = String::new();
@@ -69,64 +75,68 @@ impl RenameRule {
pascal
}
CamelCase => {
let pascal = PascalCase.apply_to_field(field);
pascal[..1].to_ascii_lowercase() + &pascal[1..]
}
ScreamingSnakeCase => field.to_ascii_uppercase(),
KebabCase => field.replace('_', "-"),
+ ScreamingKebabCase => ScreamingSnakeCase.apply_to_field(field).replace('_', "-")
}
}
}
impl FromStr for RenameRule {
type Err = ();
fn from_str(rename_all_str: &str) -> Result<Self, Self::Err> {
match rename_all_str {
"lowercase" => Ok(LowerCase),
"PascalCase" => Ok(PascalCase),
"camelCase" => Ok(CamelCase),
"snake_case" => Ok(SnakeCase),
"SCREAMING_SNAKE_CASE" => Ok(ScreamingSnakeCase),
"kebab-case" => Ok(KebabCase),
+ "SCREAMING-KEBAB-CASE" => Ok(ScreamingKebabCase),
_ => Err(()),
}
}
}
#[test]
fn rename_variants() {
- for &(original, lower, camel, snake, screaming, kebab) in
+ for &(original, lower, camel, snake, screaming, kebab, screaming_kebab) in
&[
- ("Outcome", "outcome", "outcome", "outcome", "OUTCOME", "outcome"),
- ("VeryTasty", "verytasty", "veryTasty", "very_tasty", "VERY_TASTY", "very-tasty"),
- ("A", "a", "a", "a", "A", "a"),
- ("Z42", "z42", "z42", "z42", "Z42", "z42"),
+ ("Outcome", "outcome", "outcome", "outcome", "OUTCOME", "outcome", "OUTCOME"),
+ ("VeryTasty", "verytasty", "veryTasty", "very_tasty", "VERY_TASTY", "very-tasty", "VERY-TASTY"),
+ ("A", "a", "a", "a", "A", "a", "A"),
+ ("Z42", "z42", "z42", "z42", "Z42", "z42", "Z42"),
] {
assert_eq!(None.apply_to_variant(original), original);
assert_eq!(LowerCase.apply_to_variant(original), lower);
assert_eq!(PascalCase.apply_to_variant(original), original);
assert_eq!(CamelCase.apply_to_variant(original), camel);
assert_eq!(SnakeCase.apply_to_variant(original), snake);
assert_eq!(ScreamingSnakeCase.apply_to_variant(original), screaming);
assert_eq!(KebabCase.apply_to_variant(original), kebab);
+ assert_eq!(ScreamingKebabCase.apply_to_variant(original), screaming_kebab);
}
}
#[test]
fn rename_fields() {
- for &(original, pascal, camel, screaming, kebab) in
+ for &(original, pascal, camel, screaming, kebab, screaming_kebab) in
&[
- ("outcome", "Outcome", "outcome", "OUTCOME", "outcome"),
- ("very_tasty", "VeryTasty", "veryTasty", "VERY_TASTY", "very-tasty"),
- ("a", "A", "a", "A", "a"),
- ("z42", "Z42", "z42", "Z42", "z42"),
+ ("outcome", "Outcome", "outcome", "OUTCOME", "outcome", "OUTCOME"),
+ ("very_tasty", "VeryTasty", "veryTasty", "VERY_TASTY", "very-tasty", "VERY-TASTY"),
+ ("a", "A", "a", "A", "a", "A"),
+ ("z42", "Z42", "z42", "Z42", "z42", "Z42"),
] {
assert_eq!(None.apply_to_field(original), original);
assert_eq!(PascalCase.apply_to_field(original), pascal);
assert_eq!(CamelCase.apply_to_field(original), camel);
assert_eq!(SnakeCase.apply_to_field(original), original);
assert_eq!(ScreamingSnakeCase.apply_to_field(original), screaming);
assert_eq!(KebabCase.apply_to_field(original), kebab);
+ assert_eq!(ScreamingKebabCase.apply_to_field(original), screaming_kebab);
}
}
--- a/third_party/rust/serde_derive_internals/src/check.rs
+++ b/third_party/rust/serde_derive_internals/src/check.rs
@@ -10,23 +10,24 @@ use ast::{Body, Container, Style};
use attr::Identifier;
use Ctxt;
/// Cross-cutting checks that require looking at more than a single attrs
/// object. Simpler checks should happen when parsing and building the attrs.
pub fn check(cx: &Ctxt, cont: &Container) {
check_getter(cx, cont);
check_identifier(cx, cont);
+ check_variant_skip_attrs(cx, cont);
}
/// Getters are only allowed inside structs (not enums) with the `remote`
/// attribute.
fn check_getter(cx: &Ctxt, cont: &Container) {
match cont.body {
- Body::Enum(_) => {
+ Body::Enum(_, _) => {
if cont.body.has_getter() {
cx.error("#[serde(getter = \"...\")] is not allowed in an enum");
}
}
Body::Struct(_, _) => {
if cont.body.has_getter() && cont.attrs.remote().is_none() {
cx.error(
"#[serde(getter = \"...\")] can only be used in structs \
@@ -40,17 +41,17 @@ fn check_getter(cx: &Ctxt, cont: &Contai
/// The `other` attribute must be used at most once and it must be the last
/// variant of an enum that has the `field_identifier` attribute.
///
/// Inside a `variant_identifier` all variants must be unit variants. Inside a
/// `field_identifier` all but possibly one variant must be unit variants. The
/// last variant may be a newtype variant which is an implicit "other" case.
fn check_identifier(cx: &Ctxt, cont: &Container) {
let variants = match cont.body {
- Body::Enum(ref variants) => variants,
+ Body::Enum(_, ref variants) => variants,
Body::Struct(_, _) => {
return;
}
};
for (i, variant) in variants.iter().enumerate() {
match (variant.style, cont.attrs.identifier(), variant.attrs.other()) {
// The `other` attribute may only be used in a field_identifier.
@@ -89,8 +90,63 @@ fn check_identifier(cx: &Ctxt, cont: &Co
}
(_, Identifier::Variant, false) => {
cx.error("variant_identifier may only contain unit variants");
}
}
}
}
+
+/// Skip-(de)serializing attributes are not allowed on variants marked
+/// (de)serialize_with.
+fn check_variant_skip_attrs(cx: &Ctxt, cont: &Container) {
+ let variants = match cont.body {
+ Body::Enum(_, ref variants) => variants,
+ Body::Struct(_, _) => {
+ return;
+ }
+ };
+
+ for variant in variants.iter() {
+ if variant.attrs.serialize_with().is_some() {
+ if variant.attrs.skip_serializing() {
+ cx.error(format!("variant `{}` cannot have both #[serde(serialize_with)] and \
+ #[serde(skip_serializing)]", variant.ident));
+ }
+
+ for (i, field) in variant.fields.iter().enumerate() {
+ let ident = field.ident.as_ref().map_or_else(|| format!("{}", i),
+ |ident| format!("`{}`", ident));
+
+ if field.attrs.skip_serializing() {
+ cx.error(format!("variant `{}` cannot have both #[serde(serialize_with)] and \
+ a field {} marked with #[serde(skip_serializing)]",
+ variant.ident, ident));
+ }
+
+ if field.attrs.skip_serializing_if().is_some() {
+ cx.error(format!("variant `{}` cannot have both #[serde(serialize_with)] and \
+ a field {} marked with #[serde(skip_serializing_if)]",
+ variant.ident, ident));
+ }
+ }
+ }
+
+ if variant.attrs.deserialize_with().is_some() {
+ if variant.attrs.skip_deserializing() {
+ cx.error(format!("variant `{}` cannot have both #[serde(deserialize_with)] and \
+ #[serde(skip_deserializing)]", variant.ident));
+ }
+
+ for (i, field) in variant.fields.iter().enumerate() {
+ if field.attrs.skip_deserializing() {
+ let ident = field.ident.as_ref().map_or_else(|| format!("{}", i),
+ |ident| format!("`{}`", ident));
+
+ cx.error(format!("variant `{}` cannot have both #[serde(deserialize_with)] \
+ and a field {} marked with #[serde(skip_deserializing)]",
+ variant.ident, ident));
+ }
+ }
+ }
+ }
+}
--- a/third_party/rust/serde_derive_internals/src/lib.rs
+++ b/third_party/rust/serde_derive_internals/src/lib.rs
@@ -1,17 +1,17 @@
// 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(html_root_url = "https://docs.rs/serde_derive_internals/0.15.1")]
+#![doc(html_root_url = "https://docs.rs/serde_derive_internals/0.17.0")]
extern crate syn;
#[macro_use]
extern crate synom;
pub mod ast;
pub mod attr;
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/.cargo-checksum.json
+++ /dev/null
@@ -1,1 +0,0 @@
-{"files":{".travis.yml":"91edce5ea2a1956399db4b17f580c8b7995af3aa9801c4314865f560c55d6d09","Cargo.toml":"bc42bda24309b1a1d289458aad00fc1e1b354586c5e7f69ab0c83a16b66d4b61","README.md":"ecca7edfce86fe7b219535e3c14721d1de838de7035de077a4d497959260bccc","benches/bench.rs":"54cf4879d36ba2a9f3423af91bb93227b70849200e5bf74e384a166d6aa09893","lib.rs":"517f626b3d4649ae03cee12d6dd26d4baf8a6e1fac9bf410796f08a3e784007f"},"package":"872c0ff227000041c520cca51e883b858d388ab0ecf646bab76f065cebaec025"}
\ No newline at end of file
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/.travis.yml
+++ /dev/null
@@ -1,14 +0,0 @@
-language: rust
-rust:
- - nightly
- - beta
- - stable
-script: |
- cargo build --verbose &&
- cargo build --all-features --verbose &&
- cargo test --verbose &&
- cargo test --all-features --verbose &&
- ([ $TRAVIS_RUST_VERSION != nightly ] || cargo test --verbose --no-default-features) &&
- ([ $TRAVIS_RUST_VERSION != nightly ] || cargo bench --verbose bench)
-notifications:
- webhooks: http://build.servo.org:54856/travis
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/Cargo.toml
+++ /dev/null
@@ -1,35 +0,0 @@
-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
-#
-# When uploading crates to the registry Cargo will automatically
-# "normalize" Cargo.toml files for maximal compatibility
-# with all versions of Cargo and also rewrite `path` dependencies
-# to registry (e.g. crates.io) dependencies
-#
-# If you believe there's an error in this file please file an
-# issue against the rust-lang/cargo repository. If you're
-# editing this file be aware that the upstream Cargo.toml
-# will likely look very different (and much more reasonable)
-
-[package]
-name = "smallvec"
-version = "0.5.0"
-authors = ["Simon Sapin <simon.sapin@exyr.org>"]
-description = "'Small vector' optimization: store up to a small number of items on the stack"
-documentation = "http://doc.servo.org/smallvec/"
-readme = "README.md"
-keywords = ["small", "vec", "vector", "stack", "no_std"]
-license = "MPL-2.0"
-repository = "https://github.com/servo/rust-smallvec"
-
-[lib]
-name = "smallvec"
-path = "lib.rs"
-[dependencies.serde]
-version = "1"
-optional = true
-[dev-dependencies.bincode]
-version = "0.8"
-
-[features]
-default = ["std"]
-std = []
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/README.md
+++ /dev/null
@@ -1,6 +0,0 @@
-rust-smallvec
-=============
-
-[Documentation](http://docs.rs/smallvec/)
-
-"Small vector" optimization for Rust: store up to a small number of items on the stack
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/benches/bench.rs
+++ /dev/null
@@ -1,111 +0,0 @@
-#![feature(test)]
-
-extern crate smallvec;
-extern crate test;
-
-use smallvec::SmallVec;
-use self::test::Bencher;
-
-#[bench]
-fn bench_push(b: &mut Bencher) {
- #[inline(never)]
- fn push_noinline(vec: &mut SmallVec<[u64; 16]>, x: u64) {
- vec.push(x)
- }
-
- b.iter(|| {
- let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
- for x in 0..100 {
- push_noinline(&mut vec, x);
- }
- vec
- });
-}
-
-#[bench]
-fn bench_insert(b: &mut Bencher) {
- #[inline(never)]
- fn insert_noinline(vec: &mut SmallVec<[u64; 16]>, x: u64) {
- vec.insert(0, x)
- }
-
- b.iter(|| {
- let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
- for x in 0..100 {
- insert_noinline(&mut vec, x);
- }
- vec
- });
-}
-
-#[bench]
-fn bench_insert_many(b: &mut Bencher) {
- #[inline(never)]
- fn insert_many_noinline<I: IntoIterator<Item=u64>>(
- vec: &mut SmallVec<[u64; 16]>, index: usize, iterable: I) {
- vec.insert_many(index, iterable)
- }
-
- b.iter(|| {
- let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
- insert_many_noinline(&mut vec, 0, 0..100);
- insert_many_noinline(&mut vec, 0, 0..100);
- vec
- });
-}
-
-#[bench]
-fn bench_extend(b: &mut Bencher) {
- b.iter(|| {
- let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
- vec.extend(0..100);
- vec
- });
-}
-
-#[bench]
-fn bench_from_slice(b: &mut Bencher) {
- let v: Vec<u64> = (0..100).collect();
- b.iter(|| {
- let vec: SmallVec<[u64; 16]> = SmallVec::from_slice(&v);
- vec
- });
-}
-
-#[bench]
-fn bench_extend_from_slice(b: &mut Bencher) {
- let v: Vec<u64> = (0..100).collect();
- b.iter(|| {
- let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
- vec.extend_from_slice(&v);
- vec
- });
-}
-
-#[bench]
-fn bench_insert_from_slice(b: &mut Bencher) {
- let v: Vec<u64> = (0..100).collect();
- b.iter(|| {
- let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
- vec.insert_from_slice(0, &v);
- vec.insert_from_slice(0, &v);
- vec
- });
-}
-
-#[bench]
-fn bench_pushpop(b: &mut Bencher) {
- #[inline(never)]
- fn pushpop_noinline(vec: &mut SmallVec<[u64; 16]>, x: u64) {
- vec.push(x);
- vec.pop();
- }
-
- b.iter(|| {
- let mut vec: SmallVec<[u64; 16]> = SmallVec::new();
- for x in 0..100 {
- pushpop_noinline(&mut vec, x);
- }
- vec
- });
-}
deleted file mode 100644
--- a/third_party/rust/smallvec-0.5.0/lib.rs
+++ /dev/null
@@ -1,1723 +0,0 @@
-/* This Source Code Form is subject to the terms of the Mozilla Public
- * License, v. 2.0. If a copy of the MPL was not distributed with this
- * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
-
-//! Small vectors in various sizes. These store a certain number of elements inline, and fall back
-//! to the heap for larger allocations. This can be a useful optimization for improving cache
-//! locality and reducing allocator traffic for workloads that fit within the inline buffer.
-//!
-//! ## no_std support
-//!
-//! By default, `smallvec` depends on `libstd`. However, it can be configured to use the unstable
-//! `liballoc` API instead, for use on platforms that have `liballoc` but not `libstd`. This
-//! configuration is currently unstable and is not guaranteed to work on all versions of Rust.
-//!
-//! To depend on `smallvec` without `libstd`, use `default-features = false` in the `smallvec`
-//! section of Cargo.toml to disable its `"std"` feature.
-
-#![cfg_attr(not(feature = "std"), no_std)]
-#![cfg_attr(not(feature = "std"), feature(alloc))]
-
-
-#[cfg(not(feature = "std"))]
-#[cfg_attr(test, macro_use)]
-extern crate alloc;
-
-#[cfg(not(feature = "std"))]
-use alloc::Vec;
-
-#[cfg(feature = "serde")]
-extern crate serde;
-
-#[cfg(not(feature = "std"))]
-mod std {
- pub use core::*;
-}
-
-use std::borrow::{Borrow, BorrowMut};
-use std::cmp;
-use std::fmt;
-use std::hash::{Hash, Hasher};
-use std::iter::{IntoIterator, FromIterator};
-use std::mem;
-use std::ops;
-use std::ptr;
-use std::slice;
-#[cfg(feature = "std")]
-use std::io;
-#[cfg(feature = "serde")]
-use serde::ser::{Serialize, Serializer, SerializeSeq};
-#[cfg(feature = "serde")]
-use serde::de::{Deserialize, Deserializer, SeqAccess, Visitor};
-#[cfg(feature = "serde")]
-use std::marker::PhantomData;
-
-use SmallVecData::{Inline, Heap};
-
-/// Common operations implemented by both `Vec` and `SmallVec`.
-///
-/// This can be used to write generic code that works with both `Vec` and `SmallVec`.
-///
-/// ## Example
-///
-/// ```rust
-/// use smallvec::{VecLike, SmallVec8};
-///
-/// fn initialize<V: VecLike<u8>>(v: &mut V) {
-/// for i in 0..5 {
-/// v.push(i);
-/// }
-/// }
-///
-/// let mut vec = Vec::new();
-/// initialize(&mut vec);
-///
-/// let mut small_vec = SmallVec8::new();
-/// initialize(&mut small_vec);
-/// ```
-pub trait VecLike<T>:
- ops::Index<usize, Output=T> +
- ops::IndexMut<usize> +
- ops::Index<ops::Range<usize>, Output=[T]> +
- ops::IndexMut<ops::Range<usize>> +
- ops::Index<ops::RangeFrom<usize>, Output=[T]> +
- ops::IndexMut<ops::RangeFrom<usize>> +
- ops::Index<ops::RangeTo<usize>, Output=[T]> +
- ops::IndexMut<ops::RangeTo<usize>> +
- ops::Index<ops::RangeFull, Output=[T]> +
- ops::IndexMut<ops::RangeFull> +
- ops::DerefMut<Target = [T]> +
- Extend<T> {
-
- /// Append an element to the vector.
- fn push(&mut self, value: T);
-}
-
-impl<T> VecLike<T> for Vec<T> {
- #[inline]
- fn push(&mut self, value: T) {
- Vec::push(self, value);
- }
-}
-
-/// Trait to be implemented by a collection that can be extended from a slice
-///
-/// ## Example
-///
-/// ```rust
-/// use smallvec::{ExtendFromSlice, SmallVec8};
-///
-/// fn initialize<V: ExtendFromSlice<u8>>(v: &mut V) {
-/// v.extend_from_slice(b"Test!");
-/// }
-///
-/// let mut vec = Vec::new();
-/// initialize(&mut vec);
-/// assert_eq!(&vec, b"Test!");
-///
-/// let mut small_vec = SmallVec8::new();
-/// initialize(&mut small_vec);
-/// assert_eq!(&small_vec as &[_], b"Test!");
-/// ```
-pub trait ExtendFromSlice<T>: VecLike<T> {
- /// Extends a collection from a slice of its element type
- fn extend_from_slice(&mut self, other: &[T]);
-}
-
-impl<T: Clone> ExtendFromSlice<T> for Vec<T> {
- fn extend_from_slice(&mut self, other: &[T]) {
- Vec::extend_from_slice(self, other)
- }
-}
-
-unsafe fn deallocate<T>(ptr: *mut T, capacity: usize) {
- let _vec: Vec<T> = Vec::from_raw_parts(ptr, 0, capacity);
- // Let it drop.
-}
-
-pub struct Drain<'a, T: 'a> {
- iter: slice::IterMut<'a,T>,
-}
-
-impl<'a, T: 'a> Iterator for Drain<'a,T> {
- type Item = T;
-
- #[inline]
- fn next(&mut self) -> Option<T> {
- match self.iter.next() {
- None => None,
- Some(reference) => {
- unsafe {
- Some(ptr::read(reference))
- }
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- self.iter.size_hint()
- }
-}
-
-impl<'a, T: 'a> DoubleEndedIterator for Drain<'a, T> {
- #[inline]
- fn next_back(&mut self) -> Option<T> {
- match self.iter.next_back() {
- None => None,
- Some(reference) => {
- unsafe {
- Some(ptr::read(reference))
- }
- }
- }
- }
-}
-
-impl<'a, T> ExactSizeIterator for Drain<'a, T> { }
-
-impl<'a, T: 'a> Drop for Drain<'a,T> {
- fn drop(&mut self) {
- // Destroy the remaining elements.
- for _ in self.by_ref() {}
- }
-}
-
-enum SmallVecData<A: Array> {
- Inline { array: A },
- Heap { ptr: *mut A::Item, capacity: usize },
-}
-
-impl<A: Array> SmallVecData<A> {
- fn ptr_mut(&mut self) -> *mut A::Item {
- match *self {
- Inline { ref mut array } => array.ptr_mut(),
- Heap { ptr, .. } => ptr,
- }
- }
-}
-
-unsafe impl<A: Array + Send> Send for SmallVecData<A> {}
-unsafe impl<A: Array + Sync> Sync for SmallVecData<A> {}
-
-impl<A: Array> Drop for SmallVecData<A> {
- fn drop(&mut self) {
- unsafe {
- match *self {
- ref mut inline @ Inline { .. } => {
- // Inhibit the array destructor.
- ptr::write(inline, Heap {
- ptr: ptr::null_mut(),
- capacity: 0,
- });
- }
- Heap { ptr, capacity } => deallocate(ptr, capacity),
- }
- }
- }
-}
-
-/// A `Vec`-like container that can store a small number of elements inline.
-///
-/// `SmallVec` acts like a vector, but can store a limited amount of data inline within the
-/// `Smallvec` struct rather than in a separate allocation. If the data exceeds this limit, the
-/// `SmallVec` will "spill" its data onto the heap, allocating a new buffer to hold it.
-///
-/// The amount of data that a `SmallVec` can store inline depends on its backing store. The backing
-/// store can be any type that implements the `Array` trait; usually it is a small fixed-sized
-/// array. For example a `SmallVec<[u64; 8]>` can hold up to eight 64-bit integers inline.
-///
-/// Type aliases like `SmallVec8<T>` are provided as convenient shorthand for types like
-/// `SmallVec<[T; 8]>`.
-///
-/// ## Example
-///
-/// ```rust
-/// use smallvec::SmallVec;
-/// let mut v = SmallVec::<[u8; 4]>::new(); // initialize an empty vector
-///
-/// use smallvec::SmallVec4;
-/// let mut v: SmallVec4<u8> = SmallVec::new(); // alternate way to write the above
-///
-/// // SmallVec4 can hold up to 4 items without spilling onto the heap.
-/// v.extend(0..4);
-/// assert_eq!(v.len(), 4);
-/// assert!(!v.spilled());
-///
-/// // Pushing another element will force the buffer to spill:
-/// v.push(4);
-/// assert_eq!(v.len(), 5);
-/// assert!(v.spilled());
-/// ```
-pub struct SmallVec<A: Array> {
- len: usize,
- data: SmallVecData<A>,
-}
-
-impl<A: Array> SmallVec<A> {
- /// Construct an empty vector
- #[inline]
- pub fn new() -> SmallVec<A> {
- unsafe {
- SmallVec {
- len: 0,
- data: Inline { array: mem::uninitialized() },
- }
- }
- }
-
- /// Construct an empty vector with enough capacity pre-allocated to store at least `n`
- /// elements.
- ///
- /// Will create a heap allocation only if `n` is larger than the inline capacity.
- ///
- /// ```
- /// # use smallvec::SmallVec;
- ///
- /// let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(100);
- ///
- /// assert!(v.is_empty());
- /// assert!(v.capacity() >= 100);
- /// ```
- #[inline]
- pub fn with_capacity(n: usize) -> Self {
- let mut v = SmallVec::new();
- v.reserve_exact(n);
- v
- }
-
- /// Construct a new `SmallVec` from a `Vec<A::Item>` without copying
- /// elements.
- ///
- /// ```rust
- /// use smallvec::SmallVec;
- ///
- /// let vec = vec![1, 2, 3, 4, 5];
- /// let small_vec: SmallVec<[_; 3]> = SmallVec::from_vec(vec);
- ///
- /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
- /// ```
- #[inline]
- pub fn from_vec(mut vec: Vec<A::Item>) -> SmallVec<A> {
- let (ptr, cap, len) = (vec.as_mut_ptr(), vec.capacity(), vec.len());
- mem::forget(vec);
-
- SmallVec {
- len: len,
- data: SmallVecData::Heap {
- ptr: ptr,
- capacity: cap
- }
- }
- }
-
- /// Constructs a new `SmallVec` on the stack from an `A` without
- /// copying elements.
- ///
- /// ```rust
- /// use smallvec::SmallVec;
- ///
- /// let buf = [1, 2, 3, 4, 5];
- /// let small_vec: SmallVec<_> = SmallVec::from_buf(buf);
- ///
- /// assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
- /// ```
- #[inline]
- pub fn from_buf(buf: A) -> SmallVec<A> {
- SmallVec {
- len: A::size(),
- data: SmallVecData::Inline { array: buf },
- }
- }
-
- /// Sets the length of a vector.
- ///
- /// This will explicitly set the size of the vector, without actually
- /// modifying its buffers, so it is up to the caller to ensure that the
- /// vector is actually the specified size.
- pub unsafe fn set_len(&mut self, new_len: usize) {
- self.len = new_len
- }
-
- /// The maximum number of elements this vector can hold inline
- #[inline]
- pub fn inline_size(&self) -> usize {
- A::size()
- }
-
- /// The number of elements stored in the vector
- #[inline]
- pub fn len(&self) -> usize {
- self.len
- }
-
- /// Returns `true` if the vector is empty
- #[inline]
- pub fn is_empty(&self) -> bool {
- self.len == 0
- }
-
- /// The number of items the vector can hold without reallocating
- #[inline]
- pub fn capacity(&self) -> usize {
- match self.data {
- Inline { .. } => A::size(),
- Heap { capacity, .. } => capacity,
- }
- }
-
- /// Returns `true` if the data has spilled into a separate heap-allocated buffer.
- #[inline]
- pub fn spilled(&self) -> bool {
- match self.data {
- Inline { .. } => false,
- Heap { .. } => true,
- }
- }
-
- /// Empty the vector and return an iterator over its former contents.
- pub fn drain(&mut self) -> Drain<A::Item> {
- unsafe {
- let current_len = self.len();
- self.set_len(0);
-
- let ptr = self.data.ptr_mut();
-
- let slice = slice::from_raw_parts_mut(ptr, current_len);
-
- Drain {
- iter: slice.iter_mut(),
- }
- }
- }
-
- /// Append an item to the vector.
- #[inline]
- pub fn push(&mut self, value: A::Item) {
- let cap = self.capacity();
- if self.len == cap {
- self.grow(cmp::max(cap * 2, 1))
- }
- unsafe {
- let end = self.as_mut_ptr().offset(self.len as isize);
- ptr::write(end, value);
- let len = self.len;
- self.set_len(len + 1)
- }
- }
-
- /// Append elements from an iterator.
- ///
- /// This function is deprecated; it has been replaced by `Extend::extend`.
- #[deprecated(note = "Use `extend` instead")]
- pub fn push_all_move<V: IntoIterator<Item=A::Item>>(&mut self, other: V) {
- self.extend(other)
- }
-
- /// Remove an item from the end of the vector and return it, or None if empty.
- #[inline]
- pub fn pop(&mut self) -> Option<A::Item> {
- if self.len == 0 {
- return None
- }
- let last_index = self.len - 1;
- if (last_index as isize) < 0 {
- panic!("overflow")
- }
- unsafe {
- let end_ptr = self.as_ptr().offset(last_index as isize);
- let value = ptr::read(end_ptr);
- self.set_len(last_index);
- Some(value)
- }
- }
-
- /// Re-allocate to set the capacity to `new_cap`.
- ///
- /// Panics if `new_cap` is less than the vector's length.
- pub fn grow(&mut self, new_cap: usize) {
- assert!(new_cap >= self.len);
- let mut vec: Vec<A::Item> = Vec::with_capacity(new_cap);
- let new_alloc = vec.as_mut_ptr();
- unsafe {
- mem::forget(vec);
- ptr::copy_nonoverlapping(self.as_ptr(), new_alloc, self.len);
-
- match self.data {
- Inline { .. } => {}
- Heap { ptr, capacity } => deallocate(ptr, capacity),
- }
- ptr::write(&mut self.data, Heap {
- ptr: new_alloc,
- capacity: new_cap,
- });
- }
- }
-
- /// Reserve capacity for `additional` more elements to be inserted.
- ///
- /// May reserve more space to avoid frequent reallocations.
- ///
- /// If the new capacity would overflow `usize` then it will be set to `usize::max_value()`
- /// instead. (This means that inserting `additional` new elements is not guaranteed to be
- /// possible after calling this function.)
- pub fn reserve(&mut self, additional: usize) {
- let len = self.len();
- if self.capacity() - len < additional {
- match len.checked_add(additional).and_then(usize::checked_next_power_of_two) {
- Some(cap) => self.grow(cap),
- None => self.grow(usize::max_value()),
- }
- }
- }
-
- /// Reserve the minumum capacity for `additional` more elements to be inserted.
- ///
- /// Panics if the new capacity overflows `usize`.
- pub fn reserve_exact(&mut self, additional: usize) {
- let len = self.len();
- if self.capacity() - len < additional {
- match len.checked_add(additional) {
- Some(cap) => self.grow(cap),
- None => panic!("reserve_exact overflow"),
- }
- }
- }
-
- /// Shrink the capacity of the vector as much as possible.
- ///
- /// When possible, this will move data from an external heap buffer to the vector's inline
- /// storage.
- pub fn shrink_to_fit(&mut self) {
- let len = self.len;
- if self.inline_size() >= len {
- unsafe {
- let (ptr, capacity) = match self.data {
- Inline { .. } => return,
- Heap { ptr, capacity } => (ptr, capacity),
- };
- ptr::write(&mut self.data, Inline { array: mem::uninitialized() });
- ptr::copy_nonoverlapping(ptr, self.as_mut_ptr(), len);
- deallocate(ptr, capacity);
- }
- } else if self.capacity() > len {
- self.grow(len);
- }
- }
-
- /// Shorten the vector, keeping the first `len` elements and dropping the rest.
- ///
- /// If `len` is greater than or equal to the vector's current length, this has no
- /// effect.
- ///
- /// This does not re-allocate. If you want the vector's capacity to shrink, call
- /// `shrink_to_fit` after truncating.
- pub fn truncate(&mut self, len: usize) {
- let end_ptr = self.as_ptr();
- while len < self.len {
- unsafe {
- let last_index = self.len - 1;
- self.set_len(last_index);
- ptr::read(end_ptr.offset(last_index as isize));
- }
- }
- }
-
- /// Extracts a slice containing the entire vector.
- ///
- /// Equivalent to `&mut s[..]`.
- pub fn as_slice(&self) -> &[A::Item] {
- self
- }
-
- /// Extracts a mutable slice of the entire vector.
- ///
- /// Equivalent to `&mut s[..]`.
- pub fn as_mut_slice(&mut self) -> &mut [A::Item] {
- self
- }
-
- /// Remove the element at position `index`, replacing it with the last element.
- ///
- /// This does not preserve ordering, but is O(1).
- ///
- /// Panics if `index` is out of bounds.
- #[inline]
- pub fn swap_remove(&mut self, index: usize) -> A::Item {
- let len = self.len;
- self.swap(len - 1, index);
- self.pop().unwrap()
- }
-
- /// Remove all elements from the vector.
- #[inline]
- pub fn clear(&mut self) {
- self.truncate(0);
- }
-
- /// Remove and return the element at position `index`, shifting all elements after it to the
- /// left.
- ///
- /// Panics if `index` is out of bounds.
- pub fn remove(&mut self, index: usize) -> A::Item {
- let len = self.len();
-
- assert!(index < len);
-
- unsafe {
- let ptr = self.as_mut_ptr().offset(index as isize);
- let item = ptr::read(ptr);
- ptr::copy(ptr.offset(1), ptr, len - index - 1);
- self.set_len(len - 1);
- item
- }
- }
-
- /// Insert an element at position `index`, shifting all elements after it to the right.
- ///
- /// Panics if `index` is out of bounds.
- pub fn insert(&mut self, index: usize, element: A::Item) {
- self.reserve(1);
-
- let len = self.len;
- assert!(index <= len);
-
- unsafe {
- let ptr = self.as_mut_ptr().offset(index as isize);
- ptr::copy(ptr, ptr.offset(1), len - index);
- ptr::write(ptr, element);
- self.set_len(len + 1);
- }
- }
-
- pub fn insert_many<I: IntoIterator<Item=A::Item>>(&mut self, index: usize, iterable: I) {
- let iter = iterable.into_iter();
- let (lower_size_bound, _) = iter.size_hint();
- assert!(lower_size_bound <= std::isize::MAX as usize); // Ensure offset is indexable
- assert!(index + lower_size_bound >= index); // Protect against overflow
- self.reserve(lower_size_bound);
-
- unsafe {
- let old_len = self.len;
- assert!(index <= old_len);
- let ptr = self.as_mut_ptr().offset(index as isize);
- ptr::copy(ptr, ptr.offset(lower_size_bound as isize), old_len - index);
- for (off, element) in iter.enumerate() {
- if off < lower_size_bound {
- ptr::write(ptr.offset(off as isize), element);
- self.len = self.len + 1;
- } else {
- // Iterator provided more elements than the hint.
- assert!(index + off >= index); // Protect against overflow.
- self.insert(index + off, element);
- }
- }
- let num_added = self.len - old_len;
- if num_added < lower_size_bound {
- // Iterator provided fewer elements than the hint
- ptr::copy(ptr.offset(lower_size_bound as isize), ptr.offset(num_added as isize), old_len - index);
- }
- }
- }
-
- /// Convert a SmallVec to a Vec, without reallocating if the SmallVec has already spilled onto
- /// the heap.
- pub fn into_vec(self) -> Vec<A::Item> {
- match self.data {
- Inline { .. } => self.into_iter().collect(),
- Heap { ptr, capacity } => unsafe {
- let v = Vec::from_raw_parts(ptr, self.len, capacity);
- mem::forget(self);
- v
- }
- }
- }
-
- /// Retains only the elements specified by the predicate.
- ///
- /// In other words, remove all elements `e` such that `f(&e)` returns `false`.
- /// This method operates in place and preserves the order of the retained
- /// elements.
- pub fn retain<F: FnMut(&A::Item) -> bool>(&mut self, mut f: F) {
- let mut del = 0;
- let len = self.len;
- for i in 0..len {
- if !f(&self[i]) {
- del += 1;
- } else if del > 0 {
- self.swap(i - del, i);
- }
- }
- self.truncate(len - del);
- }
-}
-
-impl<A: Array> SmallVec<A> where A::Item: Copy {
- pub fn from_slice(slice: &[A::Item]) -> Self {
- let mut vec = Self::new();
- vec.extend_from_slice(slice);
- vec
- }
-
- pub fn insert_from_slice(&mut self, index: usize, slice: &[A::Item]) {
- self.reserve(slice.len());
-
- let len = self.len;
- assert!(index <= len);
-
- unsafe {
- let slice_ptr = slice.as_ptr();
- let ptr = self.as_mut_ptr().offset(index as isize);
- ptr::copy(ptr, ptr.offset(slice.len() as isize), len - index);
- ptr::copy(slice_ptr, ptr, slice.len());
- self.set_len(len + slice.len());
- }
- }
-
- #[inline]
- pub fn extend_from_slice(&mut self, slice: &[A::Item]) {
- let len = self.len();
- self.insert_from_slice(len, slice);
- }
-}
-
-impl<A: Array> ops::Deref for SmallVec<A> {
- type Target = [A::Item];
- #[inline]
- fn deref(&self) -> &[A::Item] {
- let ptr: *const _ = match self.data {
- Inline { ref array } => array.ptr(),
- Heap { ptr, .. } => ptr,
- };
- unsafe {
- slice::from_raw_parts(ptr, self.len)
- }
- }
-}
-
-impl<A: Array> ops::DerefMut for SmallVec<A> {
- #[inline]
- fn deref_mut(&mut self) -> &mut [A::Item] {
- let ptr = self.data.ptr_mut();
- unsafe {
- slice::from_raw_parts_mut(ptr, self.len)
- }
- }
-}
-
-impl<A: Array> AsRef<[A::Item]> for SmallVec<A> {
- #[inline]
- fn as_ref(&self) -> &[A::Item] {
- self
- }
-}
-
-impl<A: Array> AsMut<[A::Item]> for SmallVec<A> {
- #[inline]
- fn as_mut(&mut self) -> &mut [A::Item] {
- self
- }
-}
-
-impl<A: Array> Borrow<[A::Item]> for SmallVec<A> {
- #[inline]
- fn borrow(&self) -> &[A::Item] {
- self
- }
-}
-
-impl<A: Array> BorrowMut<[A::Item]> for SmallVec<A> {
- #[inline]
- fn borrow_mut(&mut self) -> &mut [A::Item] {
- self
- }
-}
-
-#[cfg(feature = "std")]
-impl<A: Array<Item = u8>> io::Write for SmallVec<A> {
- #[inline]
- fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
- self.extend_from_slice(buf);
- Ok(buf.len())
- }
-
- #[inline]
- fn write_all(&mut self, buf: &[u8]) -> io::Result<()> {
- self.extend_from_slice(buf);
- Ok(())
- }
-
- #[inline]
- fn flush(&mut self) -> io::Result<()> {
- Ok(())
- }
-}
-
-#[cfg(feature = "serde")]
-impl<A: Array> Serialize for SmallVec<A> where A::Item: Serialize {
- fn serialize<S: Serializer>(&self, serializer: S) -> Result<S::Ok, S::Error> {
- let mut state = serializer.serialize_seq(Some(self.len()))?;
- for item in self {
- state.serialize_element(&item)?;
- }
- state.end()
- }
-}
-
-#[cfg(feature = "serde")]
-impl<'de, A: Array> Deserialize<'de> for SmallVec<A> where A::Item: Deserialize<'de> {
- fn deserialize<D: Deserializer<'de>>(deserializer: D) -> Result<Self, D::Error> {
- deserializer.deserialize_seq(SmallVecVisitor{phantom: PhantomData})
- }
-}
-
-#[cfg(feature = "serde")]
-struct SmallVecVisitor<A> {
- phantom: PhantomData<A>
-}
-
-#[cfg(feature = "serde")]
-impl<'de, A: Array> Visitor<'de> for SmallVecVisitor<A>
-where A::Item: Deserialize<'de>,
-{
- type Value = SmallVec<A>;
-
- fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
- formatter.write_str("a sequence")
- }
-
- fn visit_seq<B>(self, mut seq: B) -> Result<Self::Value, B::Error>
- where
- B: SeqAccess<'de>,
- {
- let mut values = SmallVec::new();
-
- while let Some(value) = seq.next_element()? {
- values.push(value);
- }
-
- Ok(values)
- }
-}
-
-impl<'a, A: Array> From<&'a [A::Item]> for SmallVec<A> where A::Item: Clone {
- #[inline]
- fn from(slice: &'a [A::Item]) -> SmallVec<A> {
- slice.into_iter().cloned().collect()
- }
-}
-
-impl<A: Array> From<Vec<A::Item>> for SmallVec<A> {
- #[inline]
- fn from(vec: Vec<A::Item>) -> SmallVec<A> {
- SmallVec::from_vec(vec)
- }
-}
-
-impl<A: Array> From<A> for SmallVec<A> {
- #[inline]
- fn from(array: A) -> SmallVec<A> {
- SmallVec::from_buf(array)
- }
-}
-
-macro_rules! impl_index {
- ($index_type: ty, $output_type: ty) => {
- impl<A: Array> ops::Index<$index_type> for SmallVec<A> {
- type Output = $output_type;
- #[inline]
- fn index(&self, index: $index_type) -> &$output_type {
- &(&**self)[index]
- }
- }
-
- impl<A: Array> ops::IndexMut<$index_type> for SmallVec<A> {
- #[inline]
- fn index_mut(&mut self, index: $index_type) -> &mut $output_type {
- &mut (&mut **self)[index]
- }
- }
- }
-}
-
-impl_index!(usize, A::Item);
-impl_index!(ops::Range<usize>, [A::Item]);
-impl_index!(ops::RangeFrom<usize>, [A::Item]);
-impl_index!(ops::RangeTo<usize>, [A::Item]);
-impl_index!(ops::RangeFull, [A::Item]);
-
-impl<A: Array> ExtendFromSlice<A::Item> for SmallVec<A> where A::Item: Copy {
- fn extend_from_slice(&mut self, other: &[A::Item]) {
- SmallVec::extend_from_slice(self, other)
- }
-}
-
-impl<A: Array> VecLike<A::Item> for SmallVec<A> {
- #[inline]
- fn push(&mut self, value: A::Item) {
- SmallVec::push(self, value);
- }
-}
-
-impl<A: Array> FromIterator<A::Item> for SmallVec<A> {
- fn from_iter<I: IntoIterator<Item=A::Item>>(iterable: I) -> SmallVec<A> {
- let mut v = SmallVec::new();
- v.extend(iterable);
- v
- }
-}
-
-impl<A: Array> Extend<A::Item> for SmallVec<A> {
- fn extend<I: IntoIterator<Item=A::Item>>(&mut self, iterable: I) {
- let iter = iterable.into_iter();
- let (lower_size_bound, _) = iter.size_hint();
-
- let target_len = self.len + lower_size_bound;
-
- if target_len > self.capacity() {
- self.grow(target_len);
- }
-
- for elem in iter {
- self.push(elem);
- }
- }
-}
-
-impl<A: Array> fmt::Debug for SmallVec<A> where A::Item: fmt::Debug {
- fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
- write!(f, "{:?}", &**self)
- }
-}
-
-impl<A: Array> Default for SmallVec<A> {
- #[inline]
- fn default() -> SmallVec<A> {
- SmallVec::new()
- }
-}
-
-impl<A: Array> Drop for SmallVec<A> {
- fn drop(&mut self) {
- // Note on panic safety: dropping an element may panic,
- // but the inner SmallVecData destructor will still run
- unsafe {
- let ptr = self.as_ptr();
- for i in 0 .. self.len {
- ptr::read(ptr.offset(i as isize));
- }
- }
- }
-}
-
-impl<A: Array> Clone for SmallVec<A> where A::Item: Clone {
- fn clone(&self) -> SmallVec<A> {
- let mut new_vector = SmallVec::new();
- for element in self.iter() {
- new_vector.push((*element).clone())
- }
- new_vector
- }
-}
-
-impl<A: Array, B: Array> PartialEq<SmallVec<B>> for SmallVec<A>
- where A::Item: PartialEq<B::Item> {
- #[inline]
- fn eq(&self, other: &SmallVec<B>) -> bool { self[..] == other[..] }
- #[inline]
- fn ne(&self, other: &SmallVec<B>) -> bool { self[..] != other[..] }
-}
-
-impl<A: Array> Eq for SmallVec<A> where A::Item: Eq {}
-
-impl<A: Array> PartialOrd for SmallVec<A> where A::Item: PartialOrd {
- #[inline]
- fn partial_cmp(&self, other: &SmallVec<A>) -> Option<cmp::Ordering> {
- PartialOrd::partial_cmp(&**self, &**other)
- }
-}
-
-impl<A: Array> Ord for SmallVec<A> where A::Item: Ord {
- #[inline]
- fn cmp(&self, other: &SmallVec<A>) -> cmp::Ordering {
- Ord::cmp(&**self, &**other)
- }
-}
-
-impl<A: Array> Hash for SmallVec<A> where A::Item: Hash {
- fn hash<H: Hasher>(&self, state: &mut H) {
- (**self).hash(state)
- }
-}
-
-unsafe impl<A: Array> Send for SmallVec<A> where A::Item: Send {}
-
-pub struct IntoIter<A: Array> {
- data: SmallVecData<A>,
- current: usize,
- end: usize,
-}
-
-impl<A: Array> Drop for IntoIter<A> {
- fn drop(&mut self) {
- for _ in self { }
- }
-}
-
-impl<A: Array> Iterator for IntoIter<A> {
- type Item = A::Item;
-
- #[inline]
- fn next(&mut self) -> Option<A::Item> {
- if self.current == self.end {
- None
- }
- else {
- unsafe {
- let current = self.current as isize;
- self.current += 1;
- Some(ptr::read(self.data.ptr_mut().offset(current)))
- }
- }
- }
-
- #[inline]
- fn size_hint(&self) -> (usize, Option<usize>) {
- let size = self.end - self.current;
- (size, Some(size))
- }
-}
-
-impl<A: Array> DoubleEndedIterator for IntoIter<A> {
- #[inline]
- fn next_back(&mut self) -> Option<A::Item> {
- if self.current == self.end {
- None
- }
- else {
- unsafe {
- self.end -= 1;
- Some(ptr::read(self.data.ptr_mut().offset(self.end as isize)))
- }
- }
- }
-}
-
-impl<A: Array> ExactSizeIterator for IntoIter<A> { }
-
-impl<A: Array> IntoIterator for SmallVec<A> {
- type IntoIter = IntoIter<A>;
- type Item = A::Item;
- fn into_iter(mut self) -> Self::IntoIter {
- let len = self.len();
- unsafe {
- // Only grab the `data` field, the `IntoIter` type handles dropping of the elements
- let data = ptr::read(&mut self.data);
- mem::forget(self);
- IntoIter {
- data: data,
- current: 0,
- end: len,
- }
- }
- }
-}
-
-impl<'a, A: Array> IntoIterator for &'a SmallVec<A> {
- type IntoIter = slice::Iter<'a, A::Item>;
- type Item = &'a A::Item;
- fn into_iter(self) -> Self::IntoIter {
- self.iter()
- }
-}
-
-impl<'a, A: Array> IntoIterator for &'a mut SmallVec<A> {
- type IntoIter = slice::IterMut<'a, A::Item>;
- type Item = &'a mut A::Item;
- fn into_iter(self) -> Self::IntoIter {
- self.iter_mut()
- }
-}
-
-// TODO: Remove these and its users.
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec1<T> = SmallVec<[T; 1]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec2<T> = SmallVec<[T; 2]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec4<T> = SmallVec<[T; 4]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec8<T> = SmallVec<[T; 8]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec16<T> = SmallVec<[T; 16]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec24<T> = SmallVec<[T; 24]>;
-
-/// Deprecated alias to ease transition from an earlier version.
-#[deprecated]
-pub type SmallVec32<T> = SmallVec<[T; 32]>;
-
-/// Types that can be used as the backing store for a SmallVec
-pub unsafe trait Array {
- type Item;
- fn size() -> usize;
- fn ptr(&self) -> *const Self::Item;
- fn ptr_mut(&mut self) -> *mut Self::Item;
-}
-
-macro_rules! impl_array(
- ($($size:expr),+) => {
- $(
- unsafe impl<T> Array for [T; $size] {
- type Item = T;
- fn size() -> usize { $size }
- fn ptr(&self) -> *const T { &self[0] }
- fn ptr_mut(&mut self) -> *mut T { &mut self[0] }
- }
- )+
- }
-);
-
-impl_array!(1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 20, 24, 32, 36,
- 0x40, 0x80, 0x100, 0x200, 0x400, 0x800, 0x1000, 0x2000, 0x4000, 0x8000,
- 0x10000, 0x20000, 0x40000, 0x80000, 0x100000);
-
-#[cfg(test)]
-pub mod tests {
- use SmallVec;
-
- use std::iter::FromIterator;
-
- #[cfg(feature = "std")]
- use std::borrow::ToOwned;
- #[cfg(not(feature = "std"))]
- use alloc::borrow::ToOwned;
- #[cfg(feature = "std")]
- use std::rc::Rc;
- #[cfg(not(feature = "std"))]
- use alloc::rc::Rc;
- #[cfg(not(feature = "std"))]
- use alloc::boxed::Box;
- #[cfg(not(feature = "std"))]
- use alloc::vec::Vec;
-
- // We heap allocate all these strings so that double frees will show up under valgrind.
-
- #[test]
- pub fn test_inline() {
- let mut v = SmallVec::<[_; 16]>::new();
- v.push("hello".to_owned());
- v.push("there".to_owned());
- assert_eq!(&*v, &[
- "hello".to_owned(),
- "there".to_owned(),
- ][..]);
- }
-
- #[test]
- pub fn test_spill() {
- let mut v = SmallVec::<[_; 2]>::new();
- v.push("hello".to_owned());
- assert_eq!(v[0], "hello");
- v.push("there".to_owned());
- v.push("burma".to_owned());
- assert_eq!(v[0], "hello");
- v.push("shave".to_owned());
- assert_eq!(&*v, &[
- "hello".to_owned(),
- "there".to_owned(),
- "burma".to_owned(),
- "shave".to_owned(),
- ][..]);
- }
-
- #[test]
- pub fn test_double_spill() {
- let mut v = SmallVec::<[_; 2]>::new();
- v.push("hello".to_owned());
- v.push("there".to_owned());
- v.push("burma".to_owned());
- v.push("shave".to_owned());
- v.push("hello".to_owned());
- v.push("there".to_owned());
- v.push("burma".to_owned());
- v.push("shave".to_owned());
- assert_eq!(&*v, &[
- "hello".to_owned(),
- "there".to_owned(),
- "burma".to_owned(),
- "shave".to_owned(),
- "hello".to_owned(),
- "there".to_owned(),
- "burma".to_owned(),
- "shave".to_owned(),
- ][..]);
- }
-
- /// https://github.com/servo/rust-smallvec/issues/4
- #[test]
- fn issue_4() {
- SmallVec::<[Box<u32>; 2]>::new();
- }
-
- /// https://github.com/servo/rust-smallvec/issues/5
- #[test]
- fn issue_5() {
- assert!(Some(SmallVec::<[&u32; 2]>::new()).is_some());
- }
-
- #[test]
- fn test_with_capacity() {
- let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(1);
- assert!(v.is_empty());
- assert!(!v.spilled());
- assert_eq!(v.capacity(), 3);
-
- let v: SmallVec<[u8; 3]> = SmallVec::with_capacity(10);
- assert!(v.is_empty());
- assert!(v.spilled());
- assert_eq!(v.capacity(), 10);
- }
-
- #[test]
- fn drain() {
- let mut v: SmallVec<[u8; 2]> = SmallVec::new();
- v.push(3);
- assert_eq!(v.drain().collect::<Vec<_>>(), &[3]);
-
- // spilling the vec
- v.push(3);
- v.push(4);
- v.push(5);
- assert_eq!(v.drain().collect::<Vec<_>>(), &[3, 4, 5]);
- }
-
- #[test]
- fn drain_rev() {
- let mut v: SmallVec<[u8; 2]> = SmallVec::new();
- v.push(3);
- assert_eq!(v.drain().rev().collect::<Vec<_>>(), &[3]);
-
- // spilling the vec
- v.push(3);
- v.push(4);
- v.push(5);
- assert_eq!(v.drain().rev().collect::<Vec<_>>(), &[5, 4, 3]);
- }
-
- #[test]
- fn into_iter() {
- let mut v: SmallVec<[u8; 2]> = SmallVec::new();
- v.push(3);
- assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3]);
-
- // spilling the vec
- let mut v: SmallVec<[u8; 2]> = SmallVec::new();
- v.push(3);
- v.push(4);
- v.push(5);
- assert_eq!(v.into_iter().collect::<Vec<_>>(), &[3, 4, 5]);
- }
-
- #[test]
- fn into_iter_rev() {
- let mut v: SmallVec<[u8; 2]> = SmallVec::new();
- v.push(3);
- assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[3]);
-
- // spilling the vec
- let mut v: SmallVec<[u8; 2]> = SmallVec::new();
- v.push(3);
- v.push(4);
- v.push(5);
- assert_eq!(v.into_iter().rev().collect::<Vec<_>>(), &[5, 4, 3]);
- }
-
- #[test]
- fn into_iter_drop() {
- use std::cell::Cell;
-
- struct DropCounter<'a>(&'a Cell<i32>);
-
- impl<'a> Drop for DropCounter<'a> {
- fn drop(&mut self) {
- self.0.set(self.0.get() + 1);
- }
- }
-
- {
- let cell = Cell::new(0);
- let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
- v.push(DropCounter(&cell));
- v.into_iter();
- assert_eq!(cell.get(), 1);
- }
-
- {
- let cell = Cell::new(0);
- let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
- v.push(DropCounter(&cell));
- v.push(DropCounter(&cell));
- assert!(v.into_iter().next().is_some());
- assert_eq!(cell.get(), 2);
- }
-
- {
- let cell = Cell::new(0);
- let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
- v.push(DropCounter(&cell));
- v.push(DropCounter(&cell));
- v.push(DropCounter(&cell));
- assert!(v.into_iter().next().is_some());
- assert_eq!(cell.get(), 3);
- }
- {
- let cell = Cell::new(0);
- let mut v: SmallVec<[DropCounter; 2]> = SmallVec::new();
- v.push(DropCounter(&cell));
- v.push(DropCounter(&cell));
- v.push(DropCounter(&cell));
- {
- let mut it = v.into_iter();
- assert!(it.next().is_some());
- assert!(it.next_back().is_some());
- }
- assert_eq!(cell.get(), 3);
- }
- }
-
- #[test]
- fn test_capacity() {
- let mut v: SmallVec<[u8; 2]> = SmallVec::new();
- v.reserve(1);
- assert_eq!(v.capacity(), 2);
- assert!(!v.spilled());
-
- v.reserve_exact(0x100);
- assert!(v.capacity() >= 0x100);
-
- v.push(0);
- v.push(1);
- v.push(2);
- v.push(3);
-
- v.shrink_to_fit();
- assert!(v.capacity() < 0x100);
- }
-
- #[test]
- fn test_truncate() {
- let mut v: SmallVec<[Box<u8>; 8]> = SmallVec::new();
-
- for x in 0..8 {
- v.push(Box::new(x));
- }
- v.truncate(4);
-
- assert_eq!(v.len(), 4);
- assert!(!v.spilled());
-
- assert_eq!(*v.swap_remove(1), 1);
- assert_eq!(*v.remove(1), 3);
- v.insert(1, Box::new(3));
-
- assert_eq!(&v.iter().map(|v| **v).collect::<Vec<_>>(), &[0, 3, 2]);
- }
-
- #[test]
- fn test_insert_many() {
- let mut v: SmallVec<[u8; 8]> = SmallVec::new();
- for x in 0..4 {
- v.push(x);
- }
- assert_eq!(v.len(), 4);
- v.insert_many(1, [5, 6].iter().cloned());
- assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
- }
-
- struct MockHintIter<T: Iterator>{x: T, hint: usize}
- impl<T: Iterator> Iterator for MockHintIter<T> {
- type Item = T::Item;
- fn next(&mut self) -> Option<Self::Item> {self.x.next()}
- fn size_hint(&self) -> (usize, Option<usize>) {(self.hint, None)}
- }
-
- #[test]
- fn test_insert_many_short_hint() {
- let mut v: SmallVec<[u8; 8]> = SmallVec::new();
- for x in 0..4 {
- v.push(x);
- }
- assert_eq!(v.len(), 4);
- v.insert_many(1, MockHintIter{x: [5, 6].iter().cloned(), hint: 5});
- assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
- }
-
- #[test]
- fn test_insert_many_long_hint() {
- let mut v: SmallVec<[u8; 8]> = SmallVec::new();
- for x in 0..4 {
- v.push(x);
- }
- assert_eq!(v.len(), 4);
- v.insert_many(1, MockHintIter{x: [5, 6].iter().cloned(), hint: 1});
- assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
- }
-
- #[test]
- #[should_panic]
- fn test_invalid_grow() {
- let mut v: SmallVec<[u8; 8]> = SmallVec::new();
- v.extend(0..8);
- v.grow(5);
- }
-
- #[test]
- fn test_insert_from_slice() {
- let mut v: SmallVec<[u8; 8]> = SmallVec::new();
- for x in 0..4 {
- v.push(x);
- }
- assert_eq!(v.len(), 4);
- v.insert_from_slice(1, &[5, 6]);
- assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 5, 6, 1, 2, 3]);
- }
-
- #[test]
- fn test_extend_from_slice() {
- let mut v: SmallVec<[u8; 8]> = SmallVec::new();
- for x in 0..4 {
- v.push(x);
- }
- assert_eq!(v.len(), 4);
- v.extend_from_slice(&[5, 6]);
- assert_eq!(&v.iter().map(|v| *v).collect::<Vec<_>>(), &[0, 1, 2, 3, 5, 6]);
- }
-
- #[test]
- #[should_panic]
- fn test_drop_panic_smallvec() {
- // This test should only panic once, and not double panic,
- // which would mean a double drop
- struct DropPanic;
-
- impl Drop for DropPanic {
- fn drop(&mut self) {
- panic!("drop");
- }
- }
-
- let mut v = SmallVec::<[_; 1]>::new();
- v.push(DropPanic);
- }
-
- #[test]
- fn test_eq() {
- let mut a: SmallVec<[u32; 2]> = SmallVec::new();
- let mut b: SmallVec<[u32; 2]> = SmallVec::new();
- let mut c: SmallVec<[u32; 2]> = SmallVec::new();
- // a = [1, 2]
- a.push(1);
- a.push(2);
- // b = [1, 2]
- b.push(1);
- b.push(2);
- // c = [3, 4]
- c.push(3);
- c.push(4);
-
- assert!(a == b);
- assert!(a != c);
- }
-
- #[test]
- fn test_ord() {
- let mut a: SmallVec<[u32; 2]> = SmallVec::new();
- let mut b: SmallVec<[u32; 2]> = SmallVec::new();
- let mut c: SmallVec<[u32; 2]> = SmallVec::new();
- // a = [1]
- a.push(1);
- // b = [1, 1]
- b.push(1);
- b.push(1);
- // c = [1, 2]
- c.push(1);
- c.push(2);
-
- assert!(a < b);
- assert!(b > a);
- assert!(b < c);
- assert!(c > b);
- }
-
- #[cfg(feature = "std")]
- #[test]
- fn test_hash() {
- use std::hash::Hash;
- use std::collections::hash_map::DefaultHasher;
-
- {
- let mut a: SmallVec<[u32; 2]> = SmallVec::new();
- let b = [1, 2];
- a.extend(b.iter().cloned());
- let mut hasher = DefaultHasher::new();
- assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher));
- }
- {
- let mut a: SmallVec<[u32; 2]> = SmallVec::new();
- let b = [1, 2, 11, 12];
- a.extend(b.iter().cloned());
- let mut hasher = DefaultHasher::new();
- assert_eq!(a.hash(&mut hasher), b.hash(&mut hasher));
- }
- }
-
- #[test]
- fn test_as_ref() {
- let mut a: SmallVec<[u32; 2]> = SmallVec::new();
- a.push(1);
- assert_eq!(a.as_ref(), [1]);
- a.push(2);
- assert_eq!(a.as_ref(), [1, 2]);
- a.push(3);
- assert_eq!(a.as_ref(), [1, 2, 3]);
- }
-
- #[test]
- fn test_as_mut() {
- let mut a: SmallVec<[u32; 2]> = SmallVec::new();
- a.push(1);
- assert_eq!(a.as_mut(), [1]);
- a.push(2);
- assert_eq!(a.as_mut(), [1, 2]);
- a.push(3);
- assert_eq!(a.as_mut(), [1, 2, 3]);
- a.as_mut()[1] = 4;
- assert_eq!(a.as_mut(), [1, 4, 3]);
- }
-
- #[test]
- fn test_borrow() {
- use std::borrow::Borrow;
-
- let mut a: SmallVec<[u32; 2]> = SmallVec::new();
- a.push(1);
- assert_eq!(a.borrow(), [1]);
- a.push(2);
- assert_eq!(a.borrow(), [1, 2]);
- a.push(3);
- assert_eq!(a.borrow(), [1, 2, 3]);
- }
-
- #[test]
- fn test_borrow_mut() {
- use std::borrow::BorrowMut;
-
- let mut a: SmallVec<[u32; 2]> = SmallVec::new();
- a.push(1);
- assert_eq!(a.borrow_mut(), [1]);
- a.push(2);
- assert_eq!(a.borrow_mut(), [1, 2]);
- a.push(3);
- assert_eq!(a.borrow_mut(), [1, 2, 3]);
- BorrowMut::<[u32]>::borrow_mut(&mut a)[1] = 4;
- assert_eq!(a.borrow_mut(), [1, 4, 3]);
- }
-
- #[test]
- fn test_from() {
- assert_eq!(&SmallVec::<[u32; 2]>::from(&[1][..])[..], [1]);
- assert_eq!(&SmallVec::<[u32; 2]>::from(&[1, 2, 3][..])[..], [1, 2, 3]);
-
- let vec = vec![];
- let small_vec: SmallVec<[u8; 3]> = SmallVec::from(vec);
- assert_eq!(&*small_vec, &[]);
- drop(small_vec);
-
- let vec = vec![1, 2, 3, 4, 5];
- let small_vec: SmallVec<[u8; 3]> = SmallVec::from(vec);
- assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
- drop(small_vec);
-
- let vec = vec![1, 2, 3, 4, 5];
- let small_vec: SmallVec<[u8; 1]> = SmallVec::from(vec);
- assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
- drop(small_vec);
-
- let array = [1];
- let small_vec: SmallVec<[u8; 1]> = SmallVec::from(array);
- assert_eq!(&*small_vec, &[1]);
- drop(small_vec);
-
- let array = [99; 128];
- let small_vec: SmallVec<[u8; 128]> = SmallVec::from(array);
- assert_eq!(&*small_vec, vec![99u8; 128].as_slice());
- drop(small_vec);
- }
-
- #[test]
- fn test_from_slice() {
- assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1][..])[..], [1]);
- assert_eq!(&SmallVec::<[u32; 2]>::from_slice(&[1, 2, 3][..])[..], [1, 2, 3]);
- }
-
- #[test]
- fn test_exact_size_iterator() {
- let mut vec = SmallVec::<[u32; 2]>::from(&[1, 2, 3][..]);
- assert_eq!(vec.clone().into_iter().len(), 3);
- assert_eq!(vec.drain().len(), 3);
- }
-
- #[test]
- fn veclike_deref_slice() {
- use super::VecLike;
-
- fn test<T: VecLike<i32>>(vec: &mut T) {
- assert!(!vec.is_empty());
- assert_eq!(vec.len(), 3);
-
- vec.sort();
- assert_eq!(&vec[..], [1, 2, 3]);
- }
-
- let mut vec = SmallVec::<[i32; 2]>::from(&[3, 1, 2][..]);
- test(&mut vec);
- }
-
- #[test]
- fn shrink_to_fit_unspill() {
- let mut vec = SmallVec::<[u8; 2]>::from_iter(0..3);
- vec.pop();
- assert!(vec.spilled());
- vec.shrink_to_fit();
- assert!(!vec.spilled(), "shrink_to_fit will un-spill if possible");
- }
-
- #[test]
- fn test_into_vec() {
- let vec = SmallVec::<[u8; 2]>::from_iter(0..2);
- assert_eq!(vec.into_vec(), vec![0, 1]);
-
- let vec = SmallVec::<[u8; 2]>::from_iter(0..3);
- assert_eq!(vec.into_vec(), vec![0, 1, 2]);
- }
-
- #[test]
- fn test_from_vec() {
- let vec = vec![];
- let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
- assert_eq!(&*small_vec, &[]);
- drop(small_vec);
-
- let vec = vec![];
- let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec);
- assert_eq!(&*small_vec, &[]);
- drop(small_vec);
-
- let vec = vec![1];
- let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
- assert_eq!(&*small_vec, &[1]);
- drop(small_vec);
-
- let vec = vec![1, 2, 3];
- let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
- assert_eq!(&*small_vec, &[1, 2, 3]);
- drop(small_vec);
-
- let vec = vec![1, 2, 3, 4, 5];
- let small_vec: SmallVec<[u8; 3]> = SmallVec::from_vec(vec);
- assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
- drop(small_vec);
-
- let vec = vec![1, 2, 3, 4, 5];
- let small_vec: SmallVec<[u8; 1]> = SmallVec::from_vec(vec);
- assert_eq!(&*small_vec, &[1, 2, 3, 4, 5]);
- drop(small_vec);
- }
-
- #[test]
- fn test_retain() {
- // Test inline data storate
- let mut sv: SmallVec<[i32; 5]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]);
- sv.retain(|&i| i != 3);
- assert_eq!(sv.pop(), Some(4));
- assert_eq!(sv.pop(), Some(2));
- assert_eq!(sv.pop(), Some(1));
- assert_eq!(sv.pop(), None);
-
- // Test spilled data storage
- let mut sv: SmallVec<[i32; 3]> = SmallVec::from_slice(&[1, 2, 3, 3, 4]);
- sv.retain(|&i| i != 3);
- assert_eq!(sv.pop(), Some(4));
- assert_eq!(sv.pop(), Some(2));
- assert_eq!(sv.pop(), Some(1));
- assert_eq!(sv.pop(), None);
-
- // Test that drop implementations are called for inline.
- let one = Rc::new(1);
- let mut sv: SmallVec<[Rc<i32>; 3]> = SmallVec::new();
- sv.push(Rc::clone(&one));
- assert_eq!(Rc::strong_count(&one), 2);
- sv.retain(|_| false);
- assert_eq!(Rc::strong_count(&one), 1);
-
- // Test that drop implementations are called for spilled data.
- let mut sv: SmallVec<[Rc<i32>; 1]> = SmallVec::new();
- sv.push(Rc::clone(&one));
- sv.push(Rc::new(2));
- assert_eq!(Rc::strong_count(&one), 2);
- sv.retain(|_| false);
- assert_eq!(Rc::strong_count(&one), 1);
- }
-
- #[cfg(feature = "std")]
- #[test]
- fn test_write() {
- use io::Write;
-
- let data = [1, 2, 3, 4, 5];
-
- let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new();
- let len = small_vec.write(&data[..]).unwrap();
- assert_eq!(len, 5);
- assert_eq!(small_vec.as_ref(), data.as_ref());
-
- let mut small_vec: SmallVec<[u8; 2]> = SmallVec::new();
- small_vec.write_all(&data[..]).unwrap();
- assert_eq!(small_vec.as_ref(), data.as_ref());
- }
-
- #[cfg(feature = "serde")]
- extern crate bincode;
-
- #[cfg(feature = "serde")]
- #[test]
- fn test_serde() {
- use self::bincode::{serialize, deserialize, Bounded};
- let mut small_vec: SmallVec<[i32; 2]> = SmallVec::new();
- small_vec.push(1);
- let encoded = serialize(&small_vec, Bounded(100)).unwrap();
- let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
- assert_eq!(small_vec, decoded);
- small_vec.push(2);
- // Spill the vec
- small_vec.push(3);
- small_vec.push(4);
- // Check again after spilling.
- let encoded = serialize(&small_vec, Bounded(100)).unwrap();
- let decoded: SmallVec<[i32; 2]> = deserialize(&encoded).unwrap();
- assert_eq!(small_vec, decoded);
- }
-}
--- a/toolkit/library/gtest/rust/Cargo.lock
+++ b/toolkit/library/gtest/rust/Cargo.lock
@@ -8,32 +8,21 @@ dependencies = [
[[package]]
name = "ansi_term"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "app_units"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "app_units"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "arrayvec"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -62,18 +51,18 @@ dependencies = [
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cubeb-core 0.1.0",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "audioipc-client"
version = "0.1.0"
dependencies = [
"audioipc 0.1.0",
"cubeb-backend 0.2.0",
@@ -106,26 +95,26 @@ source = "registry+https://github.com/ru
[[package]]
name = "bincode"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "bincode"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "bindgen"
version = "0.31.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -399,18 +388,18 @@ dependencies = [
name = "dwrote"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -451,33 +440,22 @@ dependencies = [
[[package]]
name = "error-chain"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "euclid"
-version = "0.15.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "euclid"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "fallible"
version = "0.0.1"
dependencies = [
"hashglobe 0.1.0",
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -629,24 +607,16 @@ source = "registry+https://github.com/ru
[[package]]
name = "hashglobe"
version = "0.1.0"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "heapsize"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "ident_case"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "idna"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1017,21 +987,21 @@ dependencies = [
[[package]]
name = "pkg-config"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "plane-split"
-version = "0.6.0"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1124,21 +1094,16 @@ version = "0.0.1"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"nserror 0.1.0",
"nsstring 0.1.0",
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "rustc-serialize"
-version = "0.3.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
name = "same-file"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1175,36 +1140,36 @@ dependencies = [
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "1.0.23"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
dependencies = [
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "serde_derive"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "1.0.23"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive_internals 0.17.0 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive_internals"
-version = "0.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "0.17.0"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
dependencies = [
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "servo_arc"
version = "0.0.1"
@@ -1230,21 +1195,16 @@ source = "registry+https://github.com/ru
[[package]]
name = "smallbitvec"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "smallvec"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "stable_deref_trait"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1491,72 +1451,73 @@ source = "registry+https://github.com/ru
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "webrender"
-version = "0.55.0"
+version = "0.56.1"
dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "plane-split 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "plane-split 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_api 0.55.0",
+ "webrender_api 0.56.1",
]
[[package]]
name = "webrender_api"
-version = "0.55.0"
+version = "0.56.1"
dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "webrender_bindings"
version = "0.1.0"
dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender 0.55.0",
+ "webrender 0.56.1",
]
[[package]]
name = "which"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1587,17 +1548,16 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
-"checksum app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ed0a4de09a3b8449515e649f3bb84f72ea15fc2d10639beb0776a09b7d308074"
"checksum app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29069a9b483f7780aebb55dafb360c6225eefdc1f98c8d336a65148fd10c37b1"
"checksum arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0ef4a9820019a0c91d918918c93dc71d469f581a49b47ddc1d285d4270bbe2"
"checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
"checksum bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3fb369af639822830328794eba2501b3479652fcd021b2aeb1ed4984202afd"
"checksum bindgen 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57253399c086f4f29e57ffd3b5cdbc23a806a00292619351aa4cfa39cb49d4ea"
@@ -1628,31 +1588,29 @@ dependencies = [
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "068d4026697c1a18f0b0bb8cfcad1b0c151b90d8edb9bf4c235ad68128920d1d"
"checksum dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a207eb7b40e25d1d28dc679f451d321fb6954b73ceaa47986702575865469461"
"checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
"checksum encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93ec52324ca72f423237a413ca0e1c60654c8b3d0934fcd5fd888508dfcc4ba7"
"checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9"
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
-"checksum euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ed7d77e46f6600f490463ad7b6349c3ebb2d2319af56e679e279e4c66495d9"
"checksum euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "926c639bfdff1f3063f76bb66245f6d2b691aa20fdbaabecc38b2947a13a4eba"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0"
"checksum freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7"
"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
"checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
"checksum gl_generator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "75d69f914b49d9ff32fdf394cbd798f8c716d74fd19f9cc29da3e99797b2a78d"
"checksum gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "dff613336334932baaa2759d001f14e06ea1a08a247c05962d1423aa0e89ee99"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
-"checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4"
"checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum khronos_api 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d867c645cfeb8a7fec503731679eac03ac11b7105aa5a71cb8f8ee5271636add"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
@@ -1680,40 +1638,38 @@ dependencies = [
"checksum parking_lot_core 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6c677d78851950b3aec390e681a411f78cc250cba277d4f578758a377f727970"
"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
"checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
"checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
-"checksum plane-split 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e57800a97ca52c556db6b6184a3201f05366ad5e11876f7d17e234589ca2fa26"
+"checksum plane-split 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2adb8d1523b2ddcd98275613e9bc04eef75b47a39e252e63733a3218ae3c1b7"
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
"checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
"checksum rayon-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c21a92a5dca958fb030787c1158446c6deb7f976399b72fa8074603f169e2a"
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
-"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
"checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
"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 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4"
-"checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3"
-"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
+"checksum serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
+"checksum serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
+"checksum serde_derive_internals 0.17.0 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
"checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0"
"checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
"checksum smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "79b776f00dfe01df905fa3b2eaa1659522e99e3fc4a7b1334171622205c4bdcf"
-"checksum smallvec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "872c0ff227000041c520cca51e883b858d388ab0ecf646bab76f065cebaec025"
"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27e31aa4b09b9f4cb12dff3c30ba503e17b1a624413d764d32dab76e3920e5bc"
"checksum synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf318c34a2f8381a4f3d4db2c91b45bca2b1cd8cbe56caced900647be164800c"
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
"checksum thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8df7875b676fddfadffd96deea3b1124e5ede707d4884248931077518cf1f773"
--- a/toolkit/library/rust/Cargo.lock
+++ b/toolkit/library/rust/Cargo.lock
@@ -8,32 +8,21 @@ dependencies = [
[[package]]
name = "ansi_term"
version = "0.10.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "app_units"
-version = "0.5.6"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "app_units"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "arrayvec"
version = "0.4.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"nodrop 0.1.12 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -62,18 +51,18 @@ dependencies = [
"bytes 0.4.5 (registry+https://github.com/rust-lang/crates.io-index)",
"cubeb-core 0.1.0",
"error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"memmap 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)",
"mio 0.6.9 (registry+https://github.com/rust-lang/crates.io-index)",
"mio-uds 0.6.4 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "audioipc-client"
version = "0.1.0"
dependencies = [
"audioipc 0.1.0",
"cubeb-backend 0.2.0",
@@ -106,26 +95,26 @@ source = "registry+https://github.com/ru
[[package]]
name = "bincode"
version = "0.8.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "bincode"
version = "0.9.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "bindgen"
version = "0.31.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"cexpr 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -399,18 +388,18 @@ dependencies = [
name = "dwrote"
version = "0.4.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)",
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "either"
version = "1.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -451,33 +440,22 @@ dependencies = [
[[package]]
name = "error-chain"
version = "0.10.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "euclid"
-version = "0.15.5"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)",
- "log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
- "num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
-name = "euclid"
version = "0.16.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "fallible"
version = "0.0.1"
dependencies = [
"hashglobe 0.1.0",
"smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -628,24 +606,16 @@ source = "registry+https://github.com/ru
[[package]]
name = "hashglobe"
version = "0.1.0"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "heapsize"
-version = "0.4.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-dependencies = [
- "kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
-]
-
-[[package]]
name = "ident_case"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "idna"
version = "0.1.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1005,21 +975,21 @@ dependencies = [
[[package]]
name = "pkg-config"
version = "0.3.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "plane-split"
-version = "0.6.0"
+version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "precomputed-hash"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1112,21 +1082,16 @@ version = "0.0.1"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
"nserror 0.1.0",
"nsstring 0.1.0",
"url 1.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
-name = "rustc-serialize"
-version = "0.3.24"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
name = "same-file"
version = "0.1.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
@@ -1163,36 +1128,36 @@ dependencies = [
[[package]]
name = "semver-parser"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "serde"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "1.0.23"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
dependencies = [
- "serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
]
[[package]]
name = "serde_derive"
-version = "1.0.8"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "1.0.23"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
dependencies = [
"quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde_derive_internals 0.17.0 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "serde_derive_internals"
-version = "0.15.1"
-source = "registry+https://github.com/rust-lang/crates.io-index"
+version = "0.17.0"
+source = "git+https://github.com/gankro/serde?branch=deserialize_from_enums3#fc6117367ef974fb2d3b2017c21c375d34823415"
dependencies = [
"syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)",
"synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "servo_arc"
version = "0.0.1"
@@ -1222,21 +1187,16 @@ source = "registry+https://github.com/ru
[[package]]
name = "smallbitvec"
version = "1.0.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "smallvec"
-version = "0.5.0"
-source = "registry+https://github.com/rust-lang/crates.io-index"
-
-[[package]]
-name = "smallvec"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
[[package]]
name = "stable_deref_trait"
version = "1.0.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
@@ -1503,72 +1463,73 @@ source = "registry+https://github.com/ru
dependencies = [
"kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)",
"same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)",
"winapi 0.2.8 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "webrender"
-version = "0.55.0"
+version = "0.56.1"
dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"core-text 8.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"lazy_static 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"num-traits 0.1.41 (registry+https://github.com/rust-lang/crates.io-index)",
- "plane-split 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "plane-split 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
- "smallvec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender_api 0.55.0",
+ "webrender_api 0.56.1",
]
[[package]]
name = "webrender_api"
-version = "0.55.0"
+version = "0.56.1"
dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)",
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
"byteorder 1.2.1 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
- "serde 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
+ "serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)",
"time 0.1.38 (registry+https://github.com/rust-lang/crates.io-index)",
]
[[package]]
name = "webrender_bindings"
version = "0.1.0"
dependencies = [
- "app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)",
+ "app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)",
"core-foundation 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)",
"core-graphics 0.12.3 (registry+https://github.com/rust-lang/crates.io-index)",
"dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)",
+ "euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)",
"foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)",
"gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)",
"log 0.3.8 (registry+https://github.com/rust-lang/crates.io-index)",
"rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)",
"thread_profiler 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)",
- "webrender 0.55.0",
+ "webrender 0.56.1",
]
[[package]]
name = "which"
version = "1.0.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"libc 0.2.33 (registry+https://github.com/rust-lang/crates.io-index)",
@@ -1599,17 +1560,16 @@ version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
dependencies = [
"bitflags 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)",
]
[metadata]
"checksum aho-corasick 0.6.3 (registry+https://github.com/rust-lang/crates.io-index)" = "500909c4f87a9e52355b26626d890833e9e1d53ac566db76c36faa984b889699"
"checksum ansi_term 0.10.2 (registry+https://github.com/rust-lang/crates.io-index)" = "6b3568b48b7cefa6b8ce125f9bb4989e52fbcc29ebea88df04cc7c5f12f70455"
-"checksum app_units 0.5.6 (registry+https://github.com/rust-lang/crates.io-index)" = "ed0a4de09a3b8449515e649f3bb84f72ea15fc2d10639beb0776a09b7d308074"
"checksum app_units 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29069a9b483f7780aebb55dafb360c6225eefdc1f98c8d336a65148fd10c37b1"
"checksum arrayvec 0.4.6 (registry+https://github.com/rust-lang/crates.io-index)" = "2f0ef4a9820019a0c91d918918c93dc71d469f581a49b47ddc1d285d4270bbe2"
"checksum atomic_refcell 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
"checksum atty 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "d912da0db7fa85514874458ca3651fe2cddace8d0b0505571dbdcd41ab490159"
"checksum binary-space-partition 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "88ceb0d16c4fd0e42876e298d7d3ce3780dd9ebdcbe4199816a32c77e08597ff"
"checksum bincode 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e103c8b299b28a9c6990458b7013dc4a8356a9b854c51b9883241f5866fac36e"
"checksum bincode 0.9.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9d3fb369af639822830328794eba2501b3479652fcd021b2aeb1ed4984202afd"
"checksum bindgen 0.31.3 (registry+https://github.com/rust-lang/crates.io-index)" = "57253399c086f4f29e57ffd3b5cdbc23a806a00292619351aa4cfa39cb49d4ea"
@@ -1640,31 +1600,29 @@ dependencies = [
"checksum dtoa 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "09c3753c3db574d215cba4ea76018483895d7bff25a31b49ba45db21c48e50ab"
"checksum dtoa-short 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "068d4026697c1a18f0b0bb8cfcad1b0c151b90d8edb9bf4c235ad68128920d1d"
"checksum dwrote 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "a207eb7b40e25d1d28dc679f451d321fb6954b73ceaa47986702575865469461"
"checksum either 1.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "18785c1ba806c258137c937e44ada9ee7e69a37e3c72077542cd2f069d78562a"
"checksum encoding_c 0.8.0 (registry+https://github.com/rust-lang/crates.io-index)" = "93ec52324ca72f423237a413ca0e1c60654c8b3d0934fcd5fd888508dfcc4ba7"
"checksum encoding_rs 0.7.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f5215aabf22b83153be3ee44dfe3f940214541b2ce13d419c55e7a115c8c51a9"
"checksum env_logger 0.4.3 (registry+https://github.com/rust-lang/crates.io-index)" = "3ddf21e73e016298f5cb37d6ef8e8da8e39f91f9ec8b0df44b7deb16a9f8cd5b"
"checksum error-chain 0.10.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d9435d864e017c3c6afeac1654189b06cdb491cf2ff73dbf0d73b0f292f42ff8"
-"checksum euclid 0.15.5 (registry+https://github.com/rust-lang/crates.io-index)" = "f5ed7d77e46f6600f490463ad7b6349c3ebb2d2319af56e679e279e4c66495d9"
"checksum euclid 0.16.0 (registry+https://github.com/rust-lang/crates.io-index)" = "926c639bfdff1f3063f76bb66245f6d2b691aa20fdbaabecc38b2947a13a4eba"
"checksum fnv 1.0.5 (registry+https://github.com/rust-lang/crates.io-index)" = "6cc484842f1e2884faf56f529f960cc12ad8c71ce96cc7abba0a067c98fee344"
"checksum foreign-types 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5ebc04f19019fff1f2d627b5581574ead502f80c48c88900575a46e0840fe5d0"
"checksum freetype 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "398b8a11884898184d55aca9806f002b3cf68f0e860e0cbb4586f834ee39b0e7"
"checksum fs2 0.4.2 (registry+https://github.com/rust-lang/crates.io-index)" = "9ab76cfd2aaa59b7bf6688ad9ba15bbae64bff97f04ea02144cfd3443e5c2866"
"checksum fuchsia-zircon 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "f6c0581a4e363262e52b87f59ee2afe3415361c6ec35e665924eb08afe8ff159"
"checksum fuchsia-zircon-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "43f3795b4bae048dc6123a6b972cadde2e676f9ded08aef6bb77f5f157684a82"
"checksum futures 0.1.13 (registry+https://github.com/rust-lang/crates.io-index)" = "55f0008e13fc853f79ea8fc86e931486860d4c4c156cdffb59fa5f7fa833660a"
"checksum fxhash 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "c31b6d751ae2c7f11320402d34e41349dd1016f8d5d45e48c4312bc8625af50c"
"checksum gdi32-sys 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "0912515a8ff24ba900422ecda800b52f4016a56251922d397c576bf92c690518"
"checksum gl_generator 0.6.1 (registry+https://github.com/rust-lang/crates.io-index)" = "75d69f914b49d9ff32fdf394cbd798f8c716d74fd19f9cc29da3e99797b2a78d"
"checksum gleam 0.4.15 (registry+https://github.com/rust-lang/crates.io-index)" = "dff613336334932baaa2759d001f14e06ea1a08a247c05962d1423aa0e89ee99"
"checksum glob 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "8be18de09a56b60ed0edf84bc9df007e30040691af7acd1c41874faac5895bfb"
-"checksum heapsize 0.4.0 (registry+https://github.com/rust-lang/crates.io-index)" = "4c7593b1522161003928c959c20a2ca421c68e940d63d75573316a009e48a6d4"
"checksum ident_case 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "3c9826188e666f2ed92071d2dadef6edc430b11b158b5b2b3f4babbcc891eaaa"
"checksum idna 0.1.4 (registry+https://github.com/rust-lang/crates.io-index)" = "014b298351066f1512874135335d62a789ffe78a9974f94b43ed5621951eaf7d"
"checksum iovec 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "29d062ee61fccdf25be172e70f34c9f6efc597e1fb8f6526e8437b2046ab26be"
"checksum itertools 0.5.10 (registry+https://github.com/rust-lang/crates.io-index)" = "4833d6978da405305126af4ac88569b5d71ff758581ce5a987dbfa3755f694fc"
"checksum itoa 0.3.1 (registry+https://github.com/rust-lang/crates.io-index)" = "eb2f404fbc66fd9aac13e998248505e7ecb2ad8e44ab6388684c5fb11c6c251c"
"checksum kernel32-sys 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "7507624b29483431c0ba2d82aece8ca6cdba9382bff4ddd0f7490560c056098d"
"checksum khronos_api 2.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d867c645cfeb8a7fec503731679eac03ac11b7105aa5a71cb8f8ee5271636add"
"checksum lazy_static 0.2.11 (registry+https://github.com/rust-lang/crates.io-index)" = "76f033c7ad61445c5b347c7382dd1237847eb1bce590fe50365dcb33d546be73"
@@ -1692,40 +1650,38 @@ dependencies = [
"checksum parking_lot_core 0.2.7 (registry+https://github.com/rust-lang/crates.io-index)" = "6c677d78851950b3aec390e681a411f78cc250cba277d4f578758a377f727970"
"checksum peeking_take_while 0.1.2 (registry+https://github.com/rust-lang/crates.io-index)" = "19b17cddbe7ec3f8bc800887bab5e717348c95ea2ca0b1bf0837fb964dc67099"
"checksum percent-encoding 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "de154f638187706bde41d9b4738748933d64e6b37bdbffc0b47a97d16a6ae356"
"checksum phf 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "cb325642290f28ee14d8c6201159949a872f220c62af6e110a56ea914fbe42fc"
"checksum phf_codegen 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "d62594c0bb54c464f633175d502038177e90309daf2e0158be42ed5f023ce88f"
"checksum phf_generator 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "6b07ffcc532ccc85e3afc45865469bf5d9e4ef5bfcf9622e3cfe80c2d275ec03"
"checksum phf_shared 0.7.21 (registry+https://github.com/rust-lang/crates.io-index)" = "07e24b0ca9643bdecd0632f2b3da6b1b89bbb0030e0b992afc1113b23a7bc2f2"
"checksum pkg-config 0.3.9 (registry+https://github.com/rust-lang/crates.io-index)" = "3a8b4c6b8165cd1a1cd4b9b120978131389f64bdaf456435caa41e630edba903"
-"checksum plane-split 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e57800a97ca52c556db6b6184a3201f05366ad5e11876f7d17e234589ca2fa26"
+"checksum plane-split 0.7.0 (registry+https://github.com/rust-lang/crates.io-index)" = "d2adb8d1523b2ddcd98275613e9bc04eef75b47a39e252e63733a3218ae3c1b7"
"checksum precomputed-hash 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "925383efa346730478fb4838dbe9137d2a47675ad789c546d150a6e1dd4ab31c"
"checksum procedural-masquerade 0.1.1 (registry+https://github.com/rust-lang/crates.io-index)" = "9f566249236c6ca4340f7ca78968271f0ed2b0f234007a61b66f9ecd0af09260"
"checksum quote 0.3.15 (registry+https://github.com/rust-lang/crates.io-index)" = "7a6e920b65c65f10b2ae65c831a81a073a89edd28c7cce89475bff467ab4167a"
"checksum rand 0.3.18 (registry+https://github.com/rust-lang/crates.io-index)" = "6475140dfd8655aeb72e1fd4b7a1cc1c202be65d71669476e392fe62532b9edd"
"checksum rayon 0.8.2 (registry+https://github.com/rust-lang/crates.io-index)" = "b614fe08b6665cb9a231d07ac1364b0ef3cb3698f1239ee0c4c3a88a524f54c8"
"checksum rayon-core 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "e2c21a92a5dca958fb030787c1158446c6deb7f976399b72fa8074603f169e2a"
"checksum redox_syscall 0.1.32 (registry+https://github.com/rust-lang/crates.io-index)" = "ab105df655884ede59d45b7070c8a65002d921461ee813a024558ca16030eea0"
"checksum regex 0.2.2 (registry+https://github.com/rust-lang/crates.io-index)" = "1731164734096285ec2a5ec7fea5248ae2f5485b3feeb0115af4fda2183b2d1b"
"checksum regex-syntax 0.4.1 (registry+https://github.com/rust-lang/crates.io-index)" = "ad890a5eef7953f55427c50575c680c42841653abd2b028b68cd223d157f62db"
"checksum runloop 0.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "5d79b4b604167921892e84afbbaad9d5ad74e091bf6c511d9dbfb0593f09fabd"
-"checksum rustc-serialize 0.3.24 (registry+https://github.com/rust-lang/crates.io-index)" = "dcf128d1287d2ea9d80910b5f1120d0b8eede3fbf1abe91c40d39ea7d51e6fda"
"checksum same-file 0.1.3 (registry+https://github.com/rust-lang/crates.io-index)" = "d931a44fdaa43b8637009e7632a02adc4f2b2e0733c08caa4cf00e8da4a117a7"
"checksum scopeguard 0.3.2 (registry+https://github.com/rust-lang/crates.io-index)" = "c79eb2c3ac4bc2507cda80e7f3ac5b88bd8eae4c0914d5663e6a8933994be918"
"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 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "c2f530d36fb84ec48fb7146936881f026cdbf4892028835fd9398475f82c1bb4"
-"checksum serde_derive 1.0.8 (registry+https://github.com/rust-lang/crates.io-index)" = "10552fad5500771f3902d0c5ba187c5881942b811b7ba0d8fbbfbf84d80806d3"
-"checksum serde_derive_internals 0.15.1 (registry+https://github.com/rust-lang/crates.io-index)" = "37aee4e0da52d801acfbc0cc219eb1eda7142112339726e427926a6f6ee65d3a"
+"checksum serde 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
+"checksum serde_derive 1.0.23 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
+"checksum serde_derive_internals 0.17.0 (git+https://github.com/gankro/serde?branch=deserialize_from_enums3)" = "<none>"
"checksum simd 0.2.0 (registry+https://github.com/rust-lang/crates.io-index)" = "7a94d14a2ae1f1f110937de5fb69e494372560181c7e1739a097fcc2cee37ba0"
"checksum siphasher 0.2.1 (registry+https://github.com/rust-lang/crates.io-index)" = "2ffc669b726f2bc9a3bcff66e5e23b56ba6bf70e22a34c3d7b6d0b3450b65b84"
"checksum slab 0.3.0 (registry+https://github.com/rust-lang/crates.io-index)" = "17b4fcaed89ab08ef143da37bc52adbcc04d4a69014f4c1208d6b51f0c47bc23"
"checksum smallbitvec 1.0.6 (registry+https://github.com/rust-lang/crates.io-index)" = "79b776f00dfe01df905fa3b2eaa1659522e99e3fc4a7b1334171622205c4bdcf"
-"checksum smallvec 0.5.0 (registry+https://github.com/rust-lang/crates.io-index)" = "872c0ff227000041c520cca51e883b858d388ab0ecf646bab76f065cebaec025"
"checksum smallvec 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "44db0ecb22921ef790d17ae13a3f6d15784183ff5f2a01aa32098c7498d2b4b9"
"checksum stable_deref_trait 1.0.0 (registry+https://github.com/rust-lang/crates.io-index)" = "15132e0e364248108c5e2c02e3ab539be8d6f5d52a01ca9bbf27ed657316f02b"
"checksum strsim 0.6.0 (registry+https://github.com/rust-lang/crates.io-index)" = "b4d15c810519a91cf877e7e36e63fe068815c678181439f2f29e2562147c3694"
"checksum syn 0.11.11 (registry+https://github.com/rust-lang/crates.io-index)" = "d3b891b9015c88c576343b9b3e41c2c11a51c219ef067b264bd9c8aa9b441dad"
"checksum synom 0.11.2 (registry+https://github.com/rust-lang/crates.io-index)" = "27e31aa4b09b9f4cb12dff3c30ba503e17b1a624413d764d32dab76e3920e5bc"
"checksum synstructure 0.5.2 (registry+https://github.com/rust-lang/crates.io-index)" = "cf318c34a2f8381a4f3d4db2c91b45bca2b1cd8cbe56caced900647be164800c"
"checksum textwrap 0.9.0 (registry+https://github.com/rust-lang/crates.io-index)" = "c0b59b6b4b44d867f1370ef1bd91bfb262bf07bf0ae65c202ea2fbc16153b693"
"checksum thread-id 3.1.0 (registry+https://github.com/rust-lang/crates.io-index)" = "8df7875b676fddfadffd96deea3b1124e5ede707d4884248931077518cf1f773"