<commit_before>macro_rules! common_impls {
    ($id:ident, $desc:literal) => {
        impl ::std::convert::From<$id> for ::std::string::String {
            fn from(id: $id) -> Self {
                id.full_id
            }
        }

        impl ::std::convert::TryFrom<&str> for $id {
            type Error = crate::error::Error;

            fn try_from(s: &str) -> Result<Self, Self::Error> {
                Self::try_from(::std::borrow::Cow::Borrowed(s))
            }
        }

        impl ::std::convert::TryFrom<String> for $id {
            type Error = crate::error::Error;

            fn try_from(s: String) -> Result<Self, Self::Error> {
                Self::try_from(::std::borrow::Cow::Owned(s))
            }
        }

        impl ::std::convert::AsRef<str> for $id {
            fn as_ref(&self) -> &str {
                &self.full_id
            }
        }

        impl ::std::fmt::Display for $id {
            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                write!(f, "{}", self.full_id)
            }
        }

        impl ::std::cmp::PartialEq for $id {
            fn eq(&self, other: &Self) -> bool {
                self.full_id == other.full_id
            }
        }

        impl ::std::cmp::Eq for $id {}

        impl ::std::cmp::PartialOrd for $id {
            fn partial_cmp(&self, other: &Self) -> Option<::std::cmp::Ordering> {
                <::std::string::String as ::std::cmp::PartialOrd>::partial_cmp(
                    &self.full_id,
                    &other.full_id,
                )
            }
        }

        impl ::std::cmp::Ord for $id {
            fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
                <::std::string::String as ::std::cmp::Ord>::cmp(&self.full_id, &other.full_id)
            }
        }

        impl ::std::hash::Hash for $id {
            fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
                self.full_id.hash(state);
            }
        }

        impl ::serde::Serialize for $id {
            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
            where
                S: ::serde::Serializer,
            {
                serializer.serialize_str(&self.full_id)
            }
        }

        impl<'de> ::serde::Deserialize<'de> for $id {
            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
            where
                D: ::serde::Deserializer<'de>,
            {
                crate::deserialize_id(deserializer, $desc)
            }
        }

        impl ::std::cmp::PartialEq<str> for $id {
            fn eq(&self, other: &str) -> bool {
                self.full_id == other
            }
        }

        impl ::std::cmp::PartialEq<$id> for str {
            fn eq(&self, other: &$id) -> bool {
                self == other.full_id
            }
        }

        impl ::std::cmp::PartialEq<::std::string::String> for $id {
            fn eq(&self, other: &::std::string::String) -> bool {
                &self.full_id == other
            }
        }

        impl ::std::cmp::PartialEq<$id> for ::string::String {
            fn eq(&self, other: &$id) -> bool {
                self == &other.full_id
            }
        }
    };
}
<commit_msg>Fix `String` path in macros.rs<commit_after>macro_rules! common_impls {
    ($id:ident, $desc:literal) => {
        impl ::std::convert::From<$id> for ::std::string::String {
            fn from(id: $id) -> Self {
                id.full_id
            }
        }

        impl ::std::convert::TryFrom<&str> for $id {
            type Error = crate::error::Error;

            fn try_from(s: &str) -> Result<Self, Self::Error> {
                Self::try_from(::std::borrow::Cow::Borrowed(s))
            }
        }

        impl ::std::convert::TryFrom<String> for $id {
            type Error = crate::error::Error;

            fn try_from(s: String) -> Result<Self, Self::Error> {
                Self::try_from(::std::borrow::Cow::Owned(s))
            }
        }

        impl ::std::convert::AsRef<str> for $id {
            fn as_ref(&self) -> &str {
                &self.full_id
            }
        }

        impl ::std::fmt::Display for $id {
            fn fmt(&self, f: &mut ::std::fmt::Formatter<'_>) -> ::std::fmt::Result {
                write!(f, "{}", self.full_id)
            }
        }

        impl ::std::cmp::PartialEq for $id {
            fn eq(&self, other: &Self) -> bool {
                self.full_id == other.full_id
            }
        }

        impl ::std::cmp::Eq for $id {}

        impl ::std::cmp::PartialOrd for $id {
            fn partial_cmp(&self, other: &Self) -> Option<::std::cmp::Ordering> {
                <::std::string::String as ::std::cmp::PartialOrd>::partial_cmp(
                    &self.full_id,
                    &other.full_id,
                )
            }
        }

        impl ::std::cmp::Ord for $id {
            fn cmp(&self, other: &Self) -> ::std::cmp::Ordering {
                <::std::string::String as ::std::cmp::Ord>::cmp(&self.full_id, &other.full_id)
            }
        }

        impl ::std::hash::Hash for $id {
            fn hash<H: ::std::hash::Hasher>(&self, state: &mut H) {
                self.full_id.hash(state);
            }
        }

        impl ::serde::Serialize for $id {
            fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
            where
                S: ::serde::Serializer,
            {
                serializer.serialize_str(&self.full_id)
            }
        }

        impl<'de> ::serde::Deserialize<'de> for $id {
            fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
            where
                D: ::serde::Deserializer<'de>,
            {
                crate::deserialize_id(deserializer, $desc)
            }
        }

        impl ::std::cmp::PartialEq<str> for $id {
            fn eq(&self, other: &str) -> bool {
                self.full_id == other
            }
        }

        impl ::std::cmp::PartialEq<$id> for str {
            fn eq(&self, other: &$id) -> bool {
                self == other.full_id
            }
        }

        impl ::std::cmp::PartialEq<::std::string::String> for $id {
            fn eq(&self, other: &::std::string::String) -> bool {
                &self.full_id == other
            }
        }

        impl ::std::cmp::PartialEq<$id> for ::std::string::String {
            fn eq(&self, other: &$id) -> bool {
                self == &other.full_id
            }
        }
    };
}
<|endoftext|>


<commit_before>#![allow(unknown_lints)] // older rustc doesn't know `unused_macros`
#![allow(unused_macros)]

macro_rules! forward_val_val_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to val-ref
                $imp::$method(self, &other)
            }
        }
    }
}

macro_rules! forward_val_val_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to val-ref, with the larger capacity as val
                if self.data.capacity() >= other.data.capacity() {
                    $imp::$method(self, &other)
                } else {
                    $imp::$method(other, &self)
                }
            }
        }
    }
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<$res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to ref-ref
                $imp::$method(self, &other)
            }
        }
    }
}

macro_rules! forward_ref_val_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<$res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // reverse, forward to val-ref
                $imp::$method(other, self)
            }
        }
    }
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<&'a $res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to ref-ref
                $imp::$method(&self, other)
            }
        }
    }
}

macro_rules! forward_ref_ref_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to val-ref
                $imp::$method(self.clone(), other)
            }
        }
    }
}

macro_rules! forward_ref_ref_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to val-ref, choosing the larger to clone
                if self.data.len() >= other.data.len() {
                    $imp::$method(self.clone(), other)
                } else {
                    $imp::$method(other.clone(), self)
                }
            }
        }
    }
}

macro_rules! forward_val_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            #[inline]
            fn $method(&mut self, other: $res) {
                self.$method(&other);
            }
        }
    }
}
macro_rules! forward_val_assign_scalar {
    (impl $imp:ident for $res:ty, $scalar:ty, $method:ident) => {
        impl $imp<$res> for $scalar {
            #[inline]
            fn $method(&mut self, other: $res) {
                self.$method(&other);
            }
        }
    }
}

macro_rules! forward_scalar_val_val_binop_commutative {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method: ident) => {
        impl $imp<$res> for $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                $imp::$method(other, self)
            }
        }
    }
}

macro_rules! forward_scalar_val_ref_binop {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        impl<'a> $imp<&'a $scalar> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$scalar) -> $res {
                $imp::$method(self, *other)
            }
        }

        impl<'a> $imp<$res> for &'a $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                $imp::$method(*self, other)
            }
        }
    }
}

macro_rules! forward_scalar_ref_val_binop {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        impl<'a> $imp<$scalar> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $scalar) -> $res {
                $imp::$method(self.clone(), other)
            }
        }

        impl<'a> $imp<&'a $res> for $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                $imp::$method(self, other.clone())
            }
        }
    }
}

macro_rules! forward_scalar_ref_ref_binop {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $scalar> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$scalar) -> $res {
                $imp::$method(self.clone(), *other)
            }
        }

        impl<'a, 'b> $imp<&'a $res> for &'b $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                $imp::$method(*self, other.clone())
            }
        }
    }
}

macro_rules! promote_scalars {
    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
        $(
            forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);

            impl $imp<$scalar> for $res {
                type Output = $res;

                #[inline]
                fn $method(self, other: $scalar) -> $res {
                    $imp::$method(self, other as $promo)
                }
            }

            impl $imp<$res> for $scalar {
                type Output = $res;

                #[inline]
                fn $method(self, other: $res) -> $res {
                    $imp::$method(self as $promo, other)
                }
            }
        )*
    }
}
macro_rules! promote_scalars_assign {
    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
        $(
            impl $imp<$scalar> for $res {
                #[inline]
                fn $method(&mut self, other: $scalar) {
                    self.$method(other as $promo);
                }
            }
        )*
    }
}

macro_rules! promote_unsigned_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars!(impl $imp<u32> for $res, $method, u8, u16);
        promote_scalars!(impl $imp<UsizePromotion> for $res, $method, usize);
    }
}

macro_rules! promote_unsigned_scalars_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars_assign!(impl $imp<u32> for $res, $method, u8, u16);
        promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, usize);
    }
}

macro_rules! promote_signed_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars!(impl $imp<i32> for $res, $method, i8, i16);
        promote_scalars!(impl $imp<IsizePromotion> for $res, $method, isize);
    }
}

// Forward everything to ref-ref, when reusing storage is not helpful
macro_rules! forward_all_binop_to_ref_ref {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop!(impl $imp for $res, $method);
        forward_val_ref_binop!(impl $imp for $res, $method);
        forward_ref_val_binop!(impl $imp for $res, $method);
    };
}

// Forward everything to val-ref, so LHS storage can be reused
macro_rules! forward_all_binop_to_val_ref {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop!(impl $imp for $res, $method);
        forward_ref_val_binop!(impl $imp for $res, $method);
        forward_ref_ref_binop!(impl $imp for $res, $method);
    };
}

// Forward everything to val-ref, commutatively, so either LHS or RHS storage can be reused
macro_rules! forward_all_binop_to_val_ref_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop_commutative!(impl $imp for $res, $method);
        forward_ref_val_binop_commutative!(impl $imp for $res, $method);
        forward_ref_ref_binop_commutative!(impl $imp for $res, $method);
    };
}

macro_rules! forward_all_scalar_binop_to_val_val {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        forward_scalar_val_ref_binop!(impl $imp<$scalar> for $res, $method);
        forward_scalar_ref_val_binop!(impl $imp<$scalar> for $res, $method);
        forward_scalar_ref_ref_binop!(impl $imp<$scalar> for $res, $method);
    }
}

macro_rules! forward_all_scalar_binop_to_val_val_commutative {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
        forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
    }
}

macro_rules! promote_all_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_unsigned_scalars!(impl $imp for $res, $method);
        promote_signed_scalars!(impl $imp for $res, $method);
    }
}

macro_rules! impl_sum_iter_type {
    ($res:ty) => {
        impl<T> Sum<T> for $res
        where
            $res: Add<T, Output=Self>
        {
            fn sum<I>(iter: I) -> Self
            where
                I: Iterator<Item = T>
            {
                iter.fold(Zero::zero(), <$res>::add)
            }
        }
    };
}

macro_rules! impl_product_iter_type {
    ($res:ty) => {
        impl<T> Product<T> for $res
        where
            $res: Mul<T, Output=Self>
        {
            fn product<I>(iter: I) -> Self
            where
                I: Iterator<Item = T>
            {
                iter.fold(One::one(), <$res>::mul)
            }
        }
    };
}
<commit_msg>rust-1.15: avoid Self in constraint<commit_after>#![allow(unknown_lints)] // older rustc doesn't know `unused_macros`
#![allow(unused_macros)]

macro_rules! forward_val_val_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to val-ref
                $imp::$method(self, &other)
            }
        }
    }
}

macro_rules! forward_val_val_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to val-ref, with the larger capacity as val
                if self.data.capacity() >= other.data.capacity() {
                    $imp::$method(self, &other)
                } else {
                    $imp::$method(other, &self)
                }
            }
        }
    }
}

macro_rules! forward_ref_val_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<$res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // forward to ref-ref
                $imp::$method(self, &other)
            }
        }
    }
}

macro_rules! forward_ref_val_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<$res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                // reverse, forward to val-ref
                $imp::$method(other, self)
            }
        }
    }
}

macro_rules! forward_val_ref_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a> $imp<&'a $res> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to ref-ref
                $imp::$method(&self, other)
            }
        }
    }
}

macro_rules! forward_ref_ref_binop {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to val-ref
                $imp::$method(self.clone(), other)
            }
        }
    }
}

macro_rules! forward_ref_ref_binop_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $res> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                // forward to val-ref, choosing the larger to clone
                if self.data.len() >= other.data.len() {
                    $imp::$method(self.clone(), other)
                } else {
                    $imp::$method(other.clone(), self)
                }
            }
        }
    }
}

macro_rules! forward_val_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        impl $imp<$res> for $res {
            #[inline]
            fn $method(&mut self, other: $res) {
                self.$method(&other);
            }
        }
    }
}
macro_rules! forward_val_assign_scalar {
    (impl $imp:ident for $res:ty, $scalar:ty, $method:ident) => {
        impl $imp<$res> for $scalar {
            #[inline]
            fn $method(&mut self, other: $res) {
                self.$method(&other);
            }
        }
    }
}

macro_rules! forward_scalar_val_val_binop_commutative {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method: ident) => {
        impl $imp<$res> for $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                $imp::$method(other, self)
            }
        }
    }
}

macro_rules! forward_scalar_val_ref_binop {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        impl<'a> $imp<&'a $scalar> for $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$scalar) -> $res {
                $imp::$method(self, *other)
            }
        }

        impl<'a> $imp<$res> for &'a $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: $res) -> $res {
                $imp::$method(*self, other)
            }
        }
    }
}

macro_rules! forward_scalar_ref_val_binop {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        impl<'a> $imp<$scalar> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: $scalar) -> $res {
                $imp::$method(self.clone(), other)
            }
        }

        impl<'a> $imp<&'a $res> for $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                $imp::$method(self, other.clone())
            }
        }
    }
}

macro_rules! forward_scalar_ref_ref_binop {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        impl<'a, 'b> $imp<&'b $scalar> for &'a $res {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$scalar) -> $res {
                $imp::$method(self.clone(), *other)
            }
        }

        impl<'a, 'b> $imp<&'a $res> for &'b $scalar {
            type Output = $res;

            #[inline]
            fn $method(self, other: &$res) -> $res {
                $imp::$method(*self, other.clone())
            }
        }
    }
}

macro_rules! promote_scalars {
    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
        $(
            forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);

            impl $imp<$scalar> for $res {
                type Output = $res;

                #[inline]
                fn $method(self, other: $scalar) -> $res {
                    $imp::$method(self, other as $promo)
                }
            }

            impl $imp<$res> for $scalar {
                type Output = $res;

                #[inline]
                fn $method(self, other: $res) -> $res {
                    $imp::$method(self as $promo, other)
                }
            }
        )*
    }
}
macro_rules! promote_scalars_assign {
    (impl $imp:ident<$promo:ty> for $res:ty, $method:ident, $( $scalar:ty ),*) => {
        $(
            impl $imp<$scalar> for $res {
                #[inline]
                fn $method(&mut self, other: $scalar) {
                    self.$method(other as $promo);
                }
            }
        )*
    }
}

macro_rules! promote_unsigned_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars!(impl $imp<u32> for $res, $method, u8, u16);
        promote_scalars!(impl $imp<UsizePromotion> for $res, $method, usize);
    }
}

macro_rules! promote_unsigned_scalars_assign {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars_assign!(impl $imp<u32> for $res, $method, u8, u16);
        promote_scalars_assign!(impl $imp<UsizePromotion> for $res, $method, usize);
    }
}

macro_rules! promote_signed_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_scalars!(impl $imp<i32> for $res, $method, i8, i16);
        promote_scalars!(impl $imp<IsizePromotion> for $res, $method, isize);
    }
}

// Forward everything to ref-ref, when reusing storage is not helpful
macro_rules! forward_all_binop_to_ref_ref {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop!(impl $imp for $res, $method);
        forward_val_ref_binop!(impl $imp for $res, $method);
        forward_ref_val_binop!(impl $imp for $res, $method);
    };
}

// Forward everything to val-ref, so LHS storage can be reused
macro_rules! forward_all_binop_to_val_ref {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop!(impl $imp for $res, $method);
        forward_ref_val_binop!(impl $imp for $res, $method);
        forward_ref_ref_binop!(impl $imp for $res, $method);
    };
}

// Forward everything to val-ref, commutatively, so either LHS or RHS storage can be reused
macro_rules! forward_all_binop_to_val_ref_commutative {
    (impl $imp:ident for $res:ty, $method:ident) => {
        forward_val_val_binop_commutative!(impl $imp for $res, $method);
        forward_ref_val_binop_commutative!(impl $imp for $res, $method);
        forward_ref_ref_binop_commutative!(impl $imp for $res, $method);
    };
}

macro_rules! forward_all_scalar_binop_to_val_val {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        forward_scalar_val_ref_binop!(impl $imp<$scalar> for $res, $method);
        forward_scalar_ref_val_binop!(impl $imp<$scalar> for $res, $method);
        forward_scalar_ref_ref_binop!(impl $imp<$scalar> for $res, $method);
    }
}

macro_rules! forward_all_scalar_binop_to_val_val_commutative {
    (impl $imp:ident<$scalar:ty> for $res:ty, $method:ident) => {
        forward_scalar_val_val_binop_commutative!(impl $imp<$scalar> for $res, $method);
        forward_all_scalar_binop_to_val_val!(impl $imp<$scalar> for $res, $method);
    }
}

macro_rules! promote_all_scalars {
    (impl $imp:ident for $res:ty, $method:ident) => {
        promote_unsigned_scalars!(impl $imp for $res, $method);
        promote_signed_scalars!(impl $imp for $res, $method);
    }
}

macro_rules! impl_sum_iter_type {
    ($res:ty) => {
        impl<T> Sum<T> for $res
        where
            $res: Add<T, Output=$res>
        {
            fn sum<I>(iter: I) -> Self
            where
                I: Iterator<Item = T>
            {
                iter.fold(Zero::zero(), <$res>::add)
            }
        }
    };
}

macro_rules! impl_product_iter_type {
    ($res:ty) => {
        impl<T> Product<T> for $res
        where
            $res: Mul<T, Output=$res>
        {
            fn product<I>(iter: I) -> Self
            where
                I: Iterator<Item = T>
            {
                iter.fold(One::one(), <$res>::mul)
            }
        }
    };
}
<|endoftext|>


<commit_before>/// Macro that generates a `struct` implementation of a specified trait.
///
/// This macro generates a `struct` that implements the traits `Clone`, `Debug`
/// and `Default`. Create instances of the mock object by calling the `struct`'s
/// `default()` method.
///
/// The `struct` has a field for each method of the `trait`, which manages their
/// respective method's behaviour and call expectations. For example, if one
/// defines a mock like so:
///
/// ```
/// # #[macro_use] extern crate double;
///
/// mock_trait!(
///     MockTaskManager,
///     max_threads(()) -> u32,
///     set_max_threads(u32) -> ()
/// );
///
/// # fn main() { }
/// ```
///
/// Then the following code is generated:
///
/// ```
/// #[derive(Debug, Clone)]
/// struct MockTaskManager {
///     max_threads: double::Mock<(), u32>,
///     set_max_threads: double::Mock<(u32), ()>,
/// }
///
/// impl Default for MockTaskManager {
///     fn default() -> Self {
///         MockTaskManager {
///             max_threads: double::Mock::default(),
///             set_max_threads: double::Mock::default(),
///         }
///     }
/// }
/// ```
///
/// Note that just defining this macro is not enough. This macro is used to
/// generate the necessary boilerplate, but the generated struct *does not*
/// implement the desired `trait`. To do that, use `double`'s `mock_method`
/// macro.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate double;
///
/// trait TaskManager {
///    fn max_threads(&self) -> u32;
///    fn set_max_threads(&mut self, max_threads: u32);
/// }
///
/// mock_trait!(
///     MockTaskManager,
///     max_threads(()) -> u32,
///     set_max_threads(u32) -> ()
/// );
///
/// # fn main() {
/// let mock = MockTaskManager::default();
/// mock.max_threads.return_value(42u32);
/// assert_eq!(42, mock.max_threads.call(()));
/// mock.set_max_threads.call(9001u32);
/// assert!(mock.set_max_threads.called_with(9001u32));
/// # }
/// ```
#[macro_export]
macro_rules! mock_trait {
    ($mock_name:ident $(, $method:ident($($arg_type:ty),* ) -> $retval:ty )* ) => (
        #[derive(Debug, Clone)]
        struct $mock_name {
            $(
                $method: double::Mock<(($($arg_type),*)), $retval>
            ),*
        }

        impl Default for $mock_name {
            fn default() -> Self {
                $mock_name {
                    $(
                        $method: double::Mock::default()
                    ),*
                }
            }
        }
    );
}

/// Macro that generates a mock implementation of a `trait` method.
///
/// This should be used to implement a `trait` on a mock type generated by
/// `double`'s `mock_trait` macro. If one has generated a mock `struct` using
/// `mock_trait`, then the actual *implementation* of the desired trait can be
/// auto-generated using `mock_method`, like so:
///
/// ```
/// # #[macro_use] extern crate double;
///
/// trait TaskManager {
///    fn max_threads(&self) -> u32;
///    fn set_max_threads(&mut self, max_threads: u32);
/// }
///
/// mock_trait!(
///     MockTaskManager,
///     max_threads(()) -> u32,
///     set_max_threads(u32) -> ()
/// );
///
/// // Actually implement the trait that should be mocked
/// impl TaskManager for MockTaskManager {
///     mock_method!(max_threads(&self) -> u32);
///     mock_method!(set_max_threads(&mut self, max_threads: u32));
/// }
///
/// # fn main() {
/// let mut mock = MockTaskManager::default();
/// mock.max_threads.return_value(42u32);
/// assert_eq!(42, mock.max_threads());
/// assert!(mock.max_threads.called_with(()));
/// mock.set_max_threads(9001u32);
/// assert!(mock.set_max_threads.called_with(9001u32));
/// # }
/// ```
///
/// There are many different variants of `mock_method`. In total there are 16
/// variants, each of which provides a combination of the following:
///
/// 1. const method (`&self`) or mutable method (`&mut self`)
/// 2. return value (`fn foo(&self) -> bool`) / no return value (`fn foo(&self)`)
/// 3. type parameters (`fn foo<T: Eq>(&self, a: &T)`) / no type parameters (`fn foo(&self, a: &str)`)
/// 4. custom method body or automatically generated method body
///
/// (1) allows both constant and mutable methods can be mocked, like in the
/// `MockTaskManager` example above.
///
/// (2) is for convenience. It means one doesn't have to specify `-> ()`
/// explicitly for mocked methods that don't return values. This can also be
/// shown in the `MockTaskManager` example. Notice how the return type is not
/// specified when generating the `set_max_threads()` method.
///
/// (3) allows one to generate mock methods which take some generic type
/// parameters. For example, suppose one had a `Comparator` trait that was
/// responsible for comparing any two values in the system. It might look
/// something like this:
///
/// ```
/// trait Comparator {
///    fn is_equal<T: Eq>(&self, a: &T, b: &T) -> bool;
/// }
/// ```
///
/// TODO
///
/// ```
/// # #[macro_use] extern crate double;
/// trait Comparator {
///    fn is_equal<T: Eq>(&self, a: &T, b: &T) -> bool;
/// }
///
/// mock_trait!(
///     MockComparator,
///     is_equal((String, String)) -> bool
/// );
///
/// impl Comparator for MockComparator {
///     mock_method!(is_equal<(T: Eq)>(&self, a: &T, b: &T) -> bool);
/// }
/// # fn main() {
/// // TODO
/// # }
/// ```
///
/// (4) TODO.
///
/// TODO: str / string
///
/// For detailed instructions and examples on how to use the different variants
/// of this macro, take a look at the
/// [**GitHub repo**](https://github.com/DonaldWhyte/double)).
#[macro_export]
macro_rules! mock_method {
    // immutable, no return value, no type parameter, no body
    ( $method:ident(&self $(,$arg_name:ident: $arg_type:ty)*)) => (
        fn $method(&self $(,$arg_name: $arg_type)*) {
            self.$method.call(($($arg_name),*))
        }
    );
    // immutable, no return value, no type parameter, body
    ( $method:ident(&self $(,$arg_name:ident: $arg_type:ty)*), $sel:ident, $body:tt ) => (
        fn $method(&$sel $(,$arg_name: $arg_type)*) $body
    );
    // immutable, no return value, type parameter, no body
    ( $method:ident<($($type_params: tt)*)>(&self $(,$arg_name:ident: $arg_type:ty)*) ) => (
            fn $method<$($type_params)*>(&$sel $(,$arg_name: $arg_type)*) {
                self.$method.call(($($arg_name),*))
            }
    );
    // immutable, no return value, type parameter, body
    ( $method:ident<($($type_params: tt)*)>(&self $(,$arg_name:ident: $arg_type:ty)*),
        $sel:ident, $body:tt) => (
            fn $method<$($type_params)*>(&$sel $(,$arg_name: $arg_type)*) $body
    );
    // immutable, return value, no type parameter, no body
    ( $method:ident(&self $(,$arg_name:ident: $arg_type:ty)*) -> $retval:ty ) => (
        fn $method(&self $(,$arg_name: $arg_type)*) -> $retval {
            self.$method.call(($($arg_name),*))
        }
    );
    // immutable, return value, no type parameter, body
    ( $method:ident(&self $(,$arg_name:ident: $arg_type:ty)*) -> $retval:ty, $sel:ident, $body:tt ) => (
        fn $method(&$sel $(,$arg_name: $arg_type)*) -> $retval $body
    );
    // immutable, return value, type parameter, no body
    ( $method:ident<($($type_params: tt)*)>(&self $(,$arg_name:ident: $arg_type:ty)*)
        -> $retval:ty ) => (
            fn $method<$($type_params)*>(&self $(,$arg_name: $arg_type)*) -> $retval {
                self.$method.call(($($arg_name),*))
            }
    );
    // immutable, return value, type parameter, body
    ( $method:ident<($($type_params: tt)*)>(&self $(,$arg_name:ident: $arg_type:ty)*)
        -> $retval:ty, $sel:ident, $body:tt ) => (
            fn $method<$($type_params)*>(&$sel $(,$arg_name: $arg_type)*) -> $retval $body
    );
    // mutable, no return value, no type parameter, no body
    ( $method:ident(&mut self $(,$arg_name:ident: $arg_type:ty)*)) => (
        fn $method(&mut self $(,$arg_name: $arg_type),*) {
            self.$method.call(($($arg_name),*))
        }
    );
    // mutable, no return value, no type parameter, body
    ( $method:ident(&mut self $(,$arg_name:ident: $arg_type:ty)*), $sel:ident, $body:tt ) => (
        fn $method(&mut $sel $(,$arg_name: $arg_type)*) $body
    );
    // mutable, no return value, type parameter, no body
    ( $method:ident<($($type_params: tt)*)>(&mut self $(,$arg_name:ident: $arg_type:ty)*) ) => (
            fn $method<$($type_params)*>(&mut $sel $(,$arg_name: $arg_type)*) {
                self.$method.call(($($arg_name),*))
            }
    );
    // mutable, no return value, type parameter, body
    ( $method:ident<($($type_params: tt)*)>(&mut self $(,$arg_name:ident: $arg_type:ty)*),
        $sel:ident, $body:tt) => (
            fn $method<$($type_params)*>(&mut $sel $(,$arg_name: $arg_type)*) $body
    );
    // mutable, return value, no type parameter, no body
    ( $method:ident(&mut self $(,$arg_name:ident: $arg_type:ty)*) -> $retval:ty ) => (
        fn $method(&mut self $(,$arg_name: $arg_type),*) -> $retval {
            self.$method.call(($($arg_name),*))
        }
    );
    // mutable, return value, no type parameter, body
    ( $method:ident(&mut self $(,$arg_name:ident: $arg_type:ty)*) -> $retval:ty, $sel:ident, $body:tt ) => (
        fn $method(&mut $sel $(,$arg_name: $arg_type)*) -> $retval $body
    );
    // mutable, return value, type parameter, no body
    ( $method:ident<($($type_params: tt)*)>(&mut self $(,$arg_name:ident: $arg_type:ty)*)
        -> $retval:ty ) => (
            fn $method<$($type_params)*>(&mut self $(,$arg_name: $arg_type)*) -> $retval {
                self.$method.call(($($arg_name),*))
            }
    );
    // mutable, return value, type parameter, body
    ( $method:ident<($($type_params: tt)*)>(&mut self $(,$arg_name:ident: $arg_type:ty)*)
        -> $retval:ty, $sel:ident, $body:tt ) => (
            fn $method<$($type_params)*>(&mut $sel $(,$arg_name: $arg_type)*) -> $retval $body
    );
}
<commit_msg>Always clone input arguments in case they're references<commit_after>/// Macro that generates a `struct` implementation of a specified trait.
///
/// This macro generates a `struct` that implements the traits `Clone`, `Debug`
/// and `Default`. Create instances of the mock object by calling the `struct`'s
/// `default()` method.
///
/// The `struct` has a field for each method of the `trait`, which manages their
/// respective method's behaviour and call expectations. For example, if one
/// defines a mock like so:
///
/// ```
/// # #[macro_use] extern crate double;
///
/// mock_trait!(
///     MockTaskManager,
///     max_threads(()) -> u32,
///     set_max_threads(u32) -> ()
/// );
///
/// # fn main() { }
/// ```
///
/// Then the following code is generated:
///
/// ```
/// #[derive(Debug, Clone)]
/// struct MockTaskManager {
///     max_threads: double::Mock<(), u32>,
///     set_max_threads: double::Mock<(u32), ()>,
/// }
///
/// impl Default for MockTaskManager {
///     fn default() -> Self {
///         MockTaskManager {
///             max_threads: double::Mock::default(),
///             set_max_threads: double::Mock::default(),
///         }
///     }
/// }
/// ```
///
/// Note that just defining this macro is not enough. This macro is used to
/// generate the necessary boilerplate, but the generated struct *does not*
/// implement the desired `trait`. To do that, use `double`'s `mock_method`
/// macro.
///
/// # Examples
///
/// ```
/// # #[macro_use] extern crate double;
///
/// trait TaskManager {
///    fn max_threads(&self) -> u32;
///    fn set_max_threads(&mut self, max_threads: u32);
/// }
///
/// mock_trait!(
///     MockTaskManager,
///     max_threads(()) -> u32,
///     set_max_threads(u32) -> ()
/// );
///
/// # fn main() {
/// let mock = MockTaskManager::default();
/// mock.max_threads.return_value(42u32);
/// assert_eq!(42, mock.max_threads.call(()));
/// mock.set_max_threads.call(9001u32);
/// assert!(mock.set_max_threads.called_with(9001u32));
/// # }
/// ```
#[macro_export]
macro_rules! mock_trait {
    ($mock_name:ident $(, $method:ident($($arg_type:ty),* ) -> $retval:ty )* ) => (
        #[derive(Debug, Clone)]
        struct $mock_name {
            $(
                $method: double::Mock<(($($arg_type),*)), $retval>
            ),*
        }

        impl Default for $mock_name {
            fn default() -> Self {
                $mock_name {
                    $(
                        $method: double::Mock::default()
                    ),*
                }
            }
        }
    );
}

/// Macro that generates a mock implementation of a `trait` method.
///
/// This should be used to implement a `trait` on a mock type generated by
/// `double`'s `mock_trait` macro. If one has generated a mock `struct` using
/// `mock_trait`, then the actual *implementation* of the desired trait can be
/// auto-generated using `mock_method`, like so:
///
/// ```
/// # #[macro_use] extern crate double;
///
/// trait TaskManager {
///    fn max_threads(&self) -> u32;
///    fn set_max_threads(&mut self, max_threads: u32);
/// }
///
/// mock_trait!(
///     MockTaskManager,
///     max_threads(()) -> u32,
///     set_max_threads(u32) -> ()
/// );
///
/// // Actually implement the trait that should be mocked
/// impl TaskManager for MockTaskManager {
///     mock_method!(max_threads(&self) -> u32);
///     mock_method!(set_max_threads(&mut self, max_threads: u32));
/// }
///
/// # fn main() {
/// let mut mock = MockTaskManager::default();
/// mock.max_threads.return_value(42u32);
/// assert_eq!(42, mock.max_threads());
/// assert!(mock.max_threads.called_with(()));
/// mock.set_max_threads(9001u32);
/// assert!(mock.set_max_threads.called_with(9001u32));
/// # }
/// ```
///
/// There are many different variants of `mock_method`. In total there are 16
/// variants, each of which provides a combination of the following:
///
/// 1. const method (`&self`) or mutable method (`&mut self`)
/// 2. return value (`fn foo(&self) -> bool`) / no return value (`fn foo(&self)`)
/// 3. type parameters (`fn foo<T: Eq>(&self, a: &T)`) / no type parameters (`fn foo(&self, a: &str)`)
/// 4. custom method body or automatically generated method body
///
/// (1) allows both constant and mutable methods can be mocked, like in the
/// `MockTaskManager` example above.
///
/// (2) is for convenience. It means one doesn't have to specify `-> ()`
/// explicitly for mocked methods that don't return values. This can also be
/// shown in the `MockTaskManager` example. Notice how the return type is not
/// specified when generating the `set_max_threads()` method.
///
/// (3) allows one to generate mock methods which take some generic type
/// parameters. For example, suppose one had a `Comparator` trait that was
/// responsible for comparing any two values in the system. It might look
/// something like this:
///
/// ```
/// trait Comparator {
///    fn is_equal<T: Eq>(&self, a: &T, b: &T) -> bool;
/// }
/// ```
///
/// TODO
///
/// ```
/// # #[macro_use] extern crate double;
/// trait Comparator {
///    fn is_equal<T: Eq>(&self, a: &T, b: &T) -> bool;
/// }
///
/// mock_trait!(
///     MockComparator,
///     is_equal((String, String)) -> bool
/// );
///
/// impl Comparator for MockComparator {
///     mock_method!(is_equal<(T: Eq)>(&self, a: &T, b: &T) -> bool);
/// }
/// # fn main() {
/// // TODO
/// # }
/// ```
///
/// (4) TODO.
///
/// TODO: str / string
///
/// For detailed instructions and examples on how to use the different variants
/// of this macro, take a look at the
/// [**GitHub repo**](https://github.com/DonaldWhyte/double)).
#[macro_export]
macro_rules! mock_method {
    // immutable, no return value, no type parameter, no body
    ( $method:ident(&self $(,$arg_name:ident: $arg_type:ty)*)) => (
        fn $method(&self $(,$arg_name: $arg_type)*) {
            self.$method.call(($($arg_name.clone()),*))
        }
    );
    // immutable, no return value, no type parameter, body
    ( $method:ident(&self $(,$arg_name:ident: $arg_type:ty)*), $sel:ident, $body:tt ) => (
        fn $method(&$sel $(,$arg_name: $arg_type)*) $body
    );
    // immutable, no return value, type parameter, no body
    ( $method:ident<($($type_params: tt)*)>(&self $(,$arg_name:ident: $arg_type:ty)*) ) => (
            fn $method<$($type_params)*>(&$sel $(,$arg_name: $arg_type)*) {
                self.$method.call(($($arg_name.clone()),*))
            }
    );
    // immutable, no return value, type parameter, body
    ( $method:ident<($($type_params: tt)*)>(&self $(,$arg_name:ident: $arg_type:ty)*),
        $sel:ident, $body:tt) => (
            fn $method<$($type_params)*>(&$sel $(,$arg_name: $arg_type)*) $body
    );
    // immutable, return value, no type parameter, no body
    ( $method:ident(&self $(,$arg_name:ident: $arg_type:ty)*) -> $retval:ty ) => (
        fn $method(&self $(,$arg_name: $arg_type)*) -> $retval {
            self.$method.call(($($arg_name.clone()),*))
        }
    );
    // immutable, return value, no type parameter, body
    ( $method:ident(&self $(,$arg_name:ident: $arg_type:ty)*) -> $retval:ty, $sel:ident, $body:tt ) => (
        fn $method(&$sel $(,$arg_name: $arg_type)*) -> $retval $body
    );
    // immutable, return value, type parameter, no body
    ( $method:ident<($($type_params: tt)*)>(&self $(,$arg_name:ident: $arg_type:ty)*)
        -> $retval:ty ) => (
            fn $method<$($type_params)*>(&self $(,$arg_name: $arg_type)*) -> $retval {
                self.$method.call(($($arg_name.clone()),*))
            }
    );
    // immutable, return value, type parameter, body
    ( $method:ident<($($type_params: tt)*)>(&self $(,$arg_name:ident: $arg_type:ty)*)
        -> $retval:ty, $sel:ident, $body:tt ) => (
            fn $method<$($type_params)*>(&$sel $(,$arg_name: $arg_type)*) -> $retval $body
    );
    // mutable, no return value, no type parameter, no body
    ( $method:ident(&mut self $(,$arg_name:ident: $arg_type:ty)*)) => (
        fn $method(&mut self $(,$arg_name: $arg_type),*) {
            self.$method.call(($($arg_name.clone()),*))
        }
    );
    // mutable, no return value, no type parameter, body
    ( $method:ident(&mut self $(,$arg_name:ident: $arg_type:ty)*), $sel:ident, $body:tt ) => (
        fn $method(&mut $sel $(,$arg_name: $arg_type)*) $body
    );
    // mutable, no return value, type parameter, no body
    ( $method:ident<($($type_params: tt)*)>(&mut self $(,$arg_name:ident: $arg_type:ty)*) ) => (
            fn $method<$($type_params)*>(&mut $sel $(,$arg_name: $arg_type)*) {
                self.$method.call(($($arg_name.clone()),*))
            }
    );
    // mutable, no return value, type parameter, body
    ( $method:ident<($($type_params: tt)*)>(&mut self $(,$arg_name:ident: $arg_type:ty)*),
        $sel:ident, $body:tt) => (
            fn $method<$($type_params)*>(&mut $sel $(,$arg_name: $arg_type)*) $body
    );
    // mutable, return value, no type parameter, no body
    ( $method:ident(&mut self $(,$arg_name:ident: $arg_type:ty)*) -> $retval:ty ) => (
        fn $method(&mut self $(,$arg_name: $arg_type),*) -> $retval {
            self.$method.call(($($arg_name.clone()),*))
        }
    );
    // mutable, return value, no type parameter, body
    ( $method:ident(&mut self $(,$arg_name:ident: $arg_type:ty)*) -> $retval:ty, $sel:ident, $body:tt ) => (
        fn $method(&mut $sel $(,$arg_name: $arg_type)*) -> $retval $body
    );
    // mutable, return value, type parameter, no body
    ( $method:ident<($($type_params: tt)*)>(&mut self $(,$arg_name:ident: $arg_type:ty)*)
        -> $retval:ty ) => (
            fn $method<$($type_params)*>(&mut self $(,$arg_name: $arg_type)*) -> $retval {
                self.$method.call(($($arg_name.clone()),*))
            }
    );
    // mutable, return value, type parameter, body
    ( $method:ident<($($type_params: tt)*)>(&mut self $(,$arg_name:ident: $arg_type:ty)*)
        -> $retval:ty, $sel:ident, $body:tt ) => (
            fn $method<$($type_params)*>(&mut $sel $(,$arg_name: $arg_type)*) -> $retval $body
    );
}
<|endoftext|>


<commit_before>/// Gets the offset of a field. Used by container_of!
macro_rules! offset_of(
    ($ty:ty, $field:ident) => {
        &(*(0 as *const $ty)).$field as *const _ as usize
    }
);

/// Gets the parent struct from a pointer.
/// VERY unsafe. The parent struct _must_ be repr(C), and the
/// type passed to this macro _must_ match the type of the parent.
macro_rules! container_of (
    ($ptr: expr, $container: ty, $field: ident) => {
        ($ptr as *mut u8).offset(-(offset_of!($container, $field) as isize)) as *mut $container
    }
);

/// Iterates over a wl_list.
///
/// # Safety
/// It is not safe to delete an element while iterating over the list,
/// so don't do it!
macro_rules! wl_list_for_each {
    ($ptr: expr, $field: ident, ($pos: ident : $container: ty) => $body: block) => {
        let mut $pos: *mut $container;
        $pos = container_of!($ptr.next, $container, $field);
        loop {
            if &(*$pos).$field as *const _ == &$ptr as *const _ {
                break
            }
            { $body }
            $pos = container_of!((*$pos).$field.next, $container, $field);
        }
    }
}

/// Logs a message using wlroots' logging capability.
///
/// Example:
/// ```rust,no_run,ignore
/// #[macro_use]
/// use wlroots::log::{init_logging, L_DEBUG, L_ERROR};
///
/// // Call this once, at the beginning of your program.
/// init_logging(WLR_DEBUG, None);
///
/// wlr_log!(L_DEBUG, "Hello world");
/// wlr_log!(L_ERROR, "Could not {:#?} the {}", foo, bar);
/// ```
#[macro_export]
macro_rules! wlr_log {
    ($verb: expr, $($msg:tt)*) => {{
        /// Convert a literal string to a C string.
        /// Note: Does not check for internal nulls, nor does it do any conversions on
        /// the grapheme clustors. Just passes the bytes as is.
        /// So probably only works on ASCII.
        macro_rules! c_str {
            ($s:expr) => {
                concat!($s, "\0").as_ptr()
                    as *const $crate::wlroots_sys::libc::c_char
            }
        }
        use $crate::wlroots_sys::_wlr_log;
        use $crate::wlroots_sys::wlr_log_importance::*;
        use ::std::ffi::CString;
        unsafe {
            let fmt = CString::new(format!($($msg)*))
                .expect("Could not convert log message to C string");
            let raw = fmt.into_raw();
            _wlr_log($verb, c_str!("[%s:%lu] %s"),
                    c_str!(file!()), line!(), raw);
            // Deallocate string
            CString::from_raw(raw);
        }
    }}
}

/// Defines a new struct that contains a variable number of listeners that
/// will trigger unsafe user-defined callbacks.
///
/// The structure that is defined is repr(C), has one `data` field with the
/// given user type, and a field for each `$listener`.
///
/// Each `$listener` has a getter method that lets you get the pointer to the
/// listener. This method is unsafe, since it returns a raw pointer.
/// To use it correctly, you need to ensure that the data it refers to never
/// moves (e.g keep it in a box). The primary purpose of this method is to pass
/// the listener pointer to other methods to register it for a Wayland event.
/// **A listener can only be registered to one event at a time**.
///
/// Finally, it also takes in a body for each `$listener` that is called
/// every time the event that is later hooked up to it is fired.
/// This method is inherently unsafe, because the user data hasn't been cast
/// from the void pointer yet. It is the user's job to write this safely.
/// To highlight this fact, the body of the function must be prefixed with
/// `unsafe`.
///
/// # Example
/// ```rust,no_run,ignore
/// #[macro_use] extern crate wlroots;
/// extern crate wlroots_sys;
/// #[macro_use] extern crate wayland_sys;
/// extern crate libc;
///
/// use wlroots::InputDevice;
/// use wlroots_sys::wlr_input_device;
///
/// // Handles input addition and removal.
/// pub trait InputManagerHandler {
///     // Callback triggered when an input device is added.
///     fn input_added(&mut self, InputDevice);
/// }
///
/// wayland_listener!(
///     // The name of the structure that will be defined.
///     pub(crate) InputManager,
///     // The type that's stored in the `data` field.
///     // Note that we use a Box here to achieve dynamic dispatch,
///     // it's not required for this type to be in a box.
///     Box<InputManagerHandler>,
///     [
///         // Adds a new listener called `add_listener`.
///         // Adds an unsafe function called `add_notify` that is triggered
///         // whenever add_listener is activated from a Wayland event.
///         add_listener => add_notify: |this: &mut InputManager, data: *mut libc::c_void,| unsafe {
///             let ref mut manager = this.data;
///             // Call the method defined above, wrapping it in a safe interface.
///             // It is your job to ensure that the code in here doesn't trigger UB!
///             manager.input_added(InputDevice::from_ptr(data as *mut wlr_input_device))
///         };
///     ]
/// );
/// # fn main() {}
/// ```
///
/// # Unsafety
/// Note that the purpose of this macro is to make it easy to generate unsafe
/// boiler plate for using listeners with Rust data.
///
/// However, there are a few things this macro doesn't protect against.
///
/// First and foremost, the data cannot move. The listeners assume that the
/// structure will never move, so in order to defend against this the generated
/// `new` method returns a Box version. **Do not move out of the box**.
///
/// Second, this macro doesn't protect against the stored data being unsized.
/// Passing a pointer of unsized data to C is UB, don't do it.
macro_rules! wayland_listener {
    ($pub: vis $struct_name: ident, $data: ty, $([
        $($listener: ident => $listener_func: ident :
          |$($func_arg:ident: $func_type:ty,)*| unsafe $body: block;)*])+) => {
        #[repr(C)]
        $pub struct $struct_name {
            data: $data,
            $($($listener: $crate::wlroots_sys::wl_listener),*)*
        }

        impl $struct_name {
            pub(crate) fn new(data: $data) -> Box<$struct_name> {
                use $crate::wlroots_sys::server::WAYLAND_SERVER_HANDLE;
                Box::new($struct_name {
                    data,
                    $($($listener: unsafe {
                        // NOTE Rationale for zeroed memory:
                        // * Need to pass a pointer to wl_list_init
                        // * The list is initialized by Wayland, which doesn't "drop"
                        // * The listener is written to without dropping any of the data
                        let mut listener: $crate::wlroots_sys::wl_listener = ::std::mem::zeroed();
                        ffi_dispatch!(WAYLAND_SERVER_HANDLE,
                                      wl_list_init,
                                      &mut listener.link as *mut _ as _);
                        ::std::ptr::write(&mut listener.notify, Some($struct_name::$listener_func));
                        listener
                    }),*)*
                })
            }

            $($(pub(crate) unsafe extern "C" fn $listener(&mut self)
                                                   -> *mut $crate::wlroots_sys::wl_listener {
                &mut self.$listener as *mut _
            })*)*

            $($(pub(crate) unsafe extern "C" fn $listener_func(listener:
                                                        *mut $crate::wlroots_sys::wl_listener,
                                                        data: *mut $crate::libc::c_void) {
                let manager: &mut $struct_name = &mut (*container_of!(listener,
                                                                      $struct_name,
                                                                      $listener));
                $crate::utils::handle_unwind(
                    ::std::panic::catch_unwind(
                        ::std::panic::AssertUnwindSafe(|| {
                            (|$($func_arg: $func_type,)*| { $body })(manager, data)
                        })));
            })*)*
        }
    }
}

/// Used to indicate what data is global compositor data.
/// It will automatically implement the CompositorData trait for the struct,
/// and also add a method to `Compositor` to unwrap the data from the fat
/// pointer.
#[cfg(feature = "unstable")]
#[macro_export]
macro_rules! compositor_data {
    ($struct_name: ty) => {
        impl<'a>::std::convert::From<&'a mut $crate::compositor::Compositor> for &'a mut $struct_name {
            fn from(compositor: &'a mut $crate::compositor::Compositor) -> &'a mut $struct_name {
                &mut *compositor.data.downcast_mut::<$struct_name>()
                    .unwrap_or_else(|| {
                        wlr_log!(WLR_ERROR, "Could not cast compositor state to {:#?}",
                                 stringify!($struct_name));
                        panic!("Could not cast compositor state to correct value")
                    })
            }
        }
    }
}

/// A convenience macro designed for use with Handle types.
///
/// This allows you to avoid the rightward drift of death that is often found
/// with heavily nested callback systems.
///
/// Any `HandleResult`s are flattened and the first one encountered is immediately
/// returned before any of the `$body` code is executed.
///
/// Order of evaluation is from left to right. It is possible to refer to the previous
/// result, as commonly found in Lisp's `let*` macro.
///
/// An example of simple use:
///
/// ```rust,ignore
/// with_handles!([(compositor: {compositor}),
///    (output: {&mut result.output_handle})] => {
///    ...
/// })
/// ```
///
/// A more complex use:
///
/// ```rust,ignore
/// with_handles!([(shell: {shell_handle}),
///    // Notice how we use the previous result to get the surface.
///    (surface: {shell.surface_handle})] => {
///    ...
/// })
/// ```
///
#[cfg(feature = "unstable")]
#[macro_export]
macro_rules! with_handles {
    ([($handle_name: ident: $unhandle_name: block)] => $body: block) => {
        $unhandle_name.run(|$handle_name| {
            $body
        })
    };
    ([($handle_name1: ident: $unhandle_name1: block),
      ($handle_name2: ident: $unhandle_name2: block),
      $($rest: tt)*] => $body: block) => {
        $unhandle_name1.run(|$handle_name1| {
            with_handles!([($handle_name2: $unhandle_name2), $($rest)*] => $body)
        }).and_then(|n: $crate::HandleResult<_>| n)
    };
    ([($handle_name: ident: $unhandle_name: block), $($rest: tt)*] => $body: block) => {
        $unhandle_name.run(|$handle_name| {
            with_handles!([$($rest)*] => $body)
        }).and_then(|n: $crate::HandleResult<_>| n)
    };
}
<commit_msg>Don't show wayland listener struct docs<commit_after>/// Gets the offset of a field. Used by container_of!
macro_rules! offset_of(
    ($ty:ty, $field:ident) => {
        &(*(0 as *const $ty)).$field as *const _ as usize
    }
);

/// Gets the parent struct from a pointer.
/// VERY unsafe. The parent struct _must_ be repr(C), and the
/// type passed to this macro _must_ match the type of the parent.
macro_rules! container_of (
    ($ptr: expr, $container: ty, $field: ident) => {
        ($ptr as *mut u8).offset(-(offset_of!($container, $field) as isize)) as *mut $container
    }
);

/// Iterates over a wl_list.
///
/// # Safety
/// It is not safe to delete an element while iterating over the list,
/// so don't do it!
macro_rules! wl_list_for_each {
    ($ptr: expr, $field: ident, ($pos: ident : $container: ty) => $body: block) => {
        let mut $pos: *mut $container;
        $pos = container_of!($ptr.next, $container, $field);
        loop {
            if &(*$pos).$field as *const _ == &$ptr as *const _ {
                break
            }
            { $body }
            $pos = container_of!((*$pos).$field.next, $container, $field);
        }
    }
}

/// Logs a message using wlroots' logging capability.
///
/// Example:
/// ```rust,no_run,ignore
/// #[macro_use]
/// use wlroots::log::{init_logging, L_DEBUG, L_ERROR};
///
/// // Call this once, at the beginning of your program.
/// init_logging(WLR_DEBUG, None);
///
/// wlr_log!(L_DEBUG, "Hello world");
/// wlr_log!(L_ERROR, "Could not {:#?} the {}", foo, bar);
/// ```
#[macro_export]
macro_rules! wlr_log {
    ($verb: expr, $($msg:tt)*) => {{
        /// Convert a literal string to a C string.
        /// Note: Does not check for internal nulls, nor does it do any conversions on
        /// the grapheme clustors. Just passes the bytes as is.
        /// So probably only works on ASCII.
        macro_rules! c_str {
            ($s:expr) => {
                concat!($s, "\0").as_ptr()
                    as *const $crate::wlroots_sys::libc::c_char
            }
        }
        use $crate::wlroots_sys::_wlr_log;
        use $crate::wlroots_sys::wlr_log_importance::*;
        use ::std::ffi::CString;
        unsafe {
            let fmt = CString::new(format!($($msg)*))
                .expect("Could not convert log message to C string");
            let raw = fmt.into_raw();
            _wlr_log($verb, c_str!("[%s:%lu] %s"),
                    c_str!(file!()), line!(), raw);
            // Deallocate string
            CString::from_raw(raw);
        }
    }}
}

/// Defines a new struct that contains a variable number of listeners that
/// will trigger unsafe user-defined callbacks.
///
/// The structure that is defined is repr(C), has one `data` field with the
/// given user type, and a field for each `$listener`.
///
/// Each `$listener` has a getter method that lets you get the pointer to the
/// listener. This method is unsafe, since it returns a raw pointer.
/// To use it correctly, you need to ensure that the data it refers to never
/// moves (e.g keep it in a box). The primary purpose of this method is to pass
/// the listener pointer to other methods to register it for a Wayland event.
/// **A listener can only be registered to one event at a time**.
///
/// Finally, it also takes in a body for each `$listener` that is called
/// every time the event that is later hooked up to it is fired.
/// This method is inherently unsafe, because the user data hasn't been cast
/// from the void pointer yet. It is the user's job to write this safely.
/// To highlight this fact, the body of the function must be prefixed with
/// `unsafe`.
///
/// # Example
/// ```rust,no_run,ignore
/// #[macro_use] extern crate wlroots;
/// extern crate wlroots_sys;
/// #[macro_use] extern crate wayland_sys;
/// extern crate libc;
///
/// use wlroots::InputDevice;
/// use wlroots_sys::wlr_input_device;
///
/// // Handles input addition and removal.
/// pub trait InputManagerHandler {
///     // Callback triggered when an input device is added.
///     fn input_added(&mut self, InputDevice);
/// }
///
/// wayland_listener!(
///     // The name of the structure that will be defined.
///     pub(crate) InputManager,
///     // The type that's stored in the `data` field.
///     // Note that we use a Box here to achieve dynamic dispatch,
///     // it's not required for this type to be in a box.
///     Box<InputManagerHandler>,
///     [
///         // Adds a new listener called `add_listener`.
///         // Adds an unsafe function called `add_notify` that is triggered
///         // whenever add_listener is activated from a Wayland event.
///         add_listener => add_notify: |this: &mut InputManager, data: *mut libc::c_void,| unsafe {
///             let ref mut manager = this.data;
///             // Call the method defined above, wrapping it in a safe interface.
///             // It is your job to ensure that the code in here doesn't trigger UB!
///             manager.input_added(InputDevice::from_ptr(data as *mut wlr_input_device))
///         };
///     ]
/// );
/// # fn main() {}
/// ```
///
/// # Unsafety
/// Note that the purpose of this macro is to make it easy to generate unsafe
/// boiler plate for using listeners with Rust data.
///
/// However, there are a few things this macro doesn't protect against.
///
/// First and foremost, the data cannot move. The listeners assume that the
/// structure will never move, so in order to defend against this the generated
/// `new` method returns a Box version. **Do not move out of the box**.
///
/// Second, this macro doesn't protect against the stored data being unsized.
/// Passing a pointer of unsized data to C is UB, don't do it.
macro_rules! wayland_listener {
    ($pub: vis $struct_name: ident, $data: ty, $([
        $($listener: ident => $listener_func: ident :
          |$($func_arg:ident: $func_type:ty,)*| unsafe $body: block;)*])+) => {
        #[repr(C)]
        #[doc(hidden)]
        $pub struct $struct_name {
            data: $data,
            $($($listener: $crate::wlroots_sys::wl_listener),*)*
        }

        impl $struct_name {
            pub(crate) fn new(data: $data) -> Box<$struct_name> {
                use $crate::wlroots_sys::server::WAYLAND_SERVER_HANDLE;
                Box::new($struct_name {
                    data,
                    $($($listener: unsafe {
                        // NOTE Rationale for zeroed memory:
                        // * Need to pass a pointer to wl_list_init
                        // * The list is initialized by Wayland, which doesn't "drop"
                        // * The listener is written to without dropping any of the data
                        let mut listener: $crate::wlroots_sys::wl_listener = ::std::mem::zeroed();
                        ffi_dispatch!(WAYLAND_SERVER_HANDLE,
                                      wl_list_init,
                                      &mut listener.link as *mut _ as _);
                        ::std::ptr::write(&mut listener.notify, Some($struct_name::$listener_func));
                        listener
                    }),*)*
                })
            }

            $($(pub(crate) unsafe extern "C" fn $listener(&mut self)
                                                   -> *mut $crate::wlroots_sys::wl_listener {
                &mut self.$listener as *mut _
            })*)*

            $($(pub(crate) unsafe extern "C" fn $listener_func(listener:
                                                        *mut $crate::wlroots_sys::wl_listener,
                                                        data: *mut $crate::libc::c_void) {
                let manager: &mut $struct_name = &mut (*container_of!(listener,
                                                                      $struct_name,
                                                                      $listener));
                $crate::utils::handle_unwind(
                    ::std::panic::catch_unwind(
                        ::std::panic::AssertUnwindSafe(|| {
                            (|$($func_arg: $func_type,)*| { $body })(manager, data)
                        })));
            })*)*
        }
    }
}

/// Used to indicate what data is global compositor data.
/// It will automatically implement the CompositorData trait for the struct,
/// and also add a method to `Compositor` to unwrap the data from the fat
/// pointer.
#[cfg(feature = "unstable")]
#[macro_export]
macro_rules! compositor_data {
    ($struct_name: ty) => {
        impl<'a>::std::convert::From<&'a mut $crate::compositor::Compositor> for &'a mut $struct_name {
            fn from(compositor: &'a mut $crate::compositor::Compositor) -> &'a mut $struct_name {
                &mut *compositor.data.downcast_mut::<$struct_name>()
                    .unwrap_or_else(|| {
                        wlr_log!(WLR_ERROR, "Could not cast compositor state to {:#?}",
                                 stringify!($struct_name));
                        panic!("Could not cast compositor state to correct value")
                    })
            }
        }
    }
}

/// A convenience macro designed for use with Handle types.
///
/// This allows you to avoid the rightward drift of death that is often found
/// with heavily nested callback systems.
///
/// Any `HandleResult`s are flattened and the first one encountered is immediately
/// returned before any of the `$body` code is executed.
///
/// Order of evaluation is from left to right. It is possible to refer to the previous
/// result, as commonly found in Lisp's `let*` macro.
///
/// An example of simple use:
///
/// ```rust,ignore
/// with_handles!([(compositor: {compositor}),
///    (output: {&mut result.output_handle})] => {
///    ...
/// })
/// ```
///
/// A more complex use:
///
/// ```rust,ignore
/// with_handles!([(shell: {shell_handle}),
///    // Notice how we use the previous result to get the surface.
///    (surface: {shell.surface_handle})] => {
///    ...
/// })
/// ```
///
#[cfg(feature = "unstable")]
#[macro_export]
macro_rules! with_handles {
    ([($handle_name: ident: $unhandle_name: block)] => $body: block) => {
        $unhandle_name.run(|$handle_name| {
            $body
        })
    };
    ([($handle_name1: ident: $unhandle_name1: block),
      ($handle_name2: ident: $unhandle_name2: block),
      $($rest: tt)*] => $body: block) => {
        $unhandle_name1.run(|$handle_name1| {
            with_handles!([($handle_name2: $unhandle_name2), $($rest)*] => $body)
        }).and_then(|n: $crate::HandleResult<_>| n)
    };
    ([($handle_name: ident: $unhandle_name: block), $($rest: tt)*] => $body: block) => {
        $unhandle_name.run(|$handle_name| {
            with_handles!([$($rest)*] => $body)
        }).and_then(|n: $crate::HandleResult<_>| n)
    };
}
<|endoftext|>


<commit_before>pub struct Memory {
  addr:[u8; 0xffff]
}

impl Memory {
  pub fn new() -> Memory {
    Memory {
      addr: [0; 0xffff]
    }
  }

  pub fn store(&mut self, addr: usize, data: u8) -> Result<(), &'static str> {
    if addr > 0xffff {
      Err("memory address out of bounds")
    } else {
      self.addr[addr] = data;
      Ok(())
    }
  }

  pub fn load(&mut self, addr: usize) -> Result<u8, &'static str> {
    if addr > 0xffff {
      Err("memory address out of bounds")
    } else {
      Ok(self.addr[addr])
    }
  }
}

<commit_msg>Use const instead of hardcoded value<commit_after>pub struct Memory {
  addr:[u8; 0xffff]
}

const ADDRESSABLE_MEMORY: usize = 0xFFFF;

impl Memory {
  pub fn new() -> Memory {
    Memory {
      addr: [0; ADDRESSABLE_MEMORY]
    }
  }

  pub fn store(&mut self, addr: usize, data: u8) -> Result<(), &'static str> {
    if addr > ADDRESSABLE_MEMORY {
      Err("memory address out of bounds")
    } else {
      self.addr[addr] = data;
      Ok(())
    }
  }

  pub fn load(&mut self, addr: usize) -> Result<u8, &'static str> {
    if addr > ADDRESSABLE_MEMORY {
      Err("memory address out of bounds")
    } else {
      Ok(self.addr[addr])
    }
  }
}

<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use std::{env, mem, str};

use psl_lexer::request;
use publicsuffix::{List, Psl, Type};
use rspec::report::ExampleResult;

lazy_static::lazy_static! {
    static ref ROOT: String = env::var("CARGO_MANIFEST_DIR").unwrap();
    static ref LIST: List = {
        let path = Path::new(ROOT.as_str())
            .join("tests")
            .join("public_suffix_list.dat");
        let mut file = File::open(path).unwrap();
        let mut contents = String::new();
        file.read_to_string(&mut contents).unwrap();
        contents.parse().unwrap()
    };
}

#[test]
fn list_behaviour() {
    rspec::run(&rspec::describe("the official test", (), |ctx| {
        let tests = "https://raw.githubusercontent.com/publicsuffix/list/master/tests/tests.txt";
        let body = request(tests).unwrap_or_else(|_| {
            let path = Path::new(ROOT.as_str()).join("tests").join("tests.txt");
            let mut file = File::open(path).unwrap();
            let mut contents = String::new();
            file.read_to_string(&mut contents).unwrap();
            contents
        });

        let mut parse = false;

        for (i, line) in body.lines().enumerate() {
            match line {
                line if line.trim().is_empty() => {
                    parse = true;
                    continue;
                }
                line if line.starts_with("//") => {
                    continue;
                }
                line => {
                    if !parse {
                        continue;
                    }
                    let mut test = line.split_whitespace().peekable();
                    if test.peek().is_none() {
                        continue;
                    }
                    let input = match test.next() {
                        Some("null") => "",
                        Some(res) => res,
                        None => {
                            panic!(format!(
                                "line {} of the test file doesn't seem to be valid",
                                i
                            ));
                        }
                    };
                    if !expected_tld(input) {
                        continue;
                    }
                    let (expected_root, expected_suffix) = match test.next() {
                        Some("null") => (None, None),
                        Some(root) => {
                            let suffix = {
                                let parts: Vec<&str> = root.split('.').rev().collect();
                                (&parts[..parts.len() - 1])
                                    .iter()
                                    .rev()
                                    .map(|part| *part)
                                    .collect::<Vec<_>>()
                                    .join(".")
                            };
                            (Some(root.to_string()), Some(suffix.to_string()))
                        }
                        None => {
                            panic!(format!(
                                "line {} of the test file doesn't seem to be valid",
                                i
                            ));
                        }
                    };
                    let (found_root, found_suffix) =
                        if input.starts_with(".") || input.contains("..") {
                            (None, None)
                        } else {
                            LIST.domain(input.to_lowercase().as_bytes())
                                .map(|d| {
                                    let domain = str::from_utf8(d.as_bytes()).unwrap().to_string();
                                    let suffix =
                                        str::from_utf8(d.suffix().as_bytes()).unwrap().to_string();
                                    (Some(domain), Some(suffix))
                                })
                                .unwrap_or((None, None))
                        };
                    ctx.when(msg(format!("input is `{}`", input)), |ctx| {
                        let full_domain = expected_root.is_some();

                        ctx.it(msg(format!("means the root domain {}", val(&expected_root))), move |_| {
                            if expected_root == found_root {
                                ExampleResult::Success
                            } else {
                                let msg = format!("expected `{:?}` but found `{:?}` on line {} of `test_psl.txt`", expected_root, found_root, i+1);
                                ExampleResult::Failure(Some(msg))
                            }
                        });

                        if full_domain {
                            ctx.it(msg(format!("also means the suffix {}", val(&expected_suffix))), move |_| {
                                if expected_suffix == found_suffix {
                                    ExampleResult::Success
                                } else {
                                    let msg = format!("expected `{:?}` but found `{:?}` on line {} of `test_psl.txt`", expected_suffix, found_suffix, i+1);
                                    ExampleResult::Failure(Some(msg))
                                }
                            });
                        }
                    });
                }
            }
        }
    }));

    rspec::run(&rspec::describe("suffix tests", (), |ctx| {
        let extra = vec![
            (
                "gp-id-ter-acc-1.to.gp-kl-cas-11-ses001-ses-1.wdsl.5m.za",
                "za",
            ),
            ("yokohama.jp", "jp"),
            ("kobe.jp", "jp"),
            // tests support for `anycase` so that feature should be enabled for this test to pass
            ("foo.bar.platformsh.Site", "bar.platformsh.Site"),
            ("bar.platformsh.site", "bar.platformsh.site"),
            ("platform.sh", "sh"),
            ("sh", "sh"),
            (".", "."),
            ("example.com.", "com."),
            ("www.食狮.中国", "中国"),
            ("www.xn--85x722f.xn--55qx5d.cn", "xn--55qx5d.cn"),
            ("a.b.example.uk.com", "uk.com"),
            ("_tcp.example.com.", "com."),
        ];

        for (input, expected) in extra {
            if !expected_tld(input) {
                continue;
            }
            ctx.when(msg(format!("input is `{}`", input)), |ctx| {
                let expected_suffix = Some(expected);
                ctx.it(
                    msg(format!(
                        "means the suffix {}",
                        val(&expected_suffix.map(ToString::to_string))
                    )),
                    move |_| {
                        let suffix = LIST.suffix(input.as_bytes()).unwrap();
                        if suffix == expected {
                            ExampleResult::Success
                        } else {
                            let msg = format!(
                                "expected `{:?}` but found `{:?}`",
                                expected_suffix,
                                Some(str::from_utf8(suffix.as_bytes()).unwrap().to_string())
                            );
                            ExampleResult::Failure(Some(msg))
                        }
                    },
                );
            });
        }
    }));

    rspec::run(&rspec::describe("suffix type tests", (), |ctx| {
        let extra = vec![
            (
                "gp-id-ter-acc-1.to.gp-kl-cas-11-ses001-ses-1.wdsl.5m.za",
                false,
                None,
            ),
            ("yokohama.jp", true, Some(Type::Icann)),
            ("kobe.jp", true, Some(Type::Icann)),
            ("foo.bar.platformsh.site", true, Some(Type::Private)),
            ("bar.platformsh.site", true, Some(Type::Private)),
            ("platform.sh", true, Some(Type::Icann)),
            ("sh", true, Some(Type::Icann)),
            (".", false, None),
            ("example.gafregsrse", false, None),
            ("www.食狮.中国", true, Some(Type::Icann)),
            ("www.xn--85x722f.xn--55qx5d.cn", true, Some(Type::Icann)),
        ];

        for (input, known_suffix, typ) in extra {
            if !expected_tld(input) {
                continue;
            }
            ctx.when(msg(format!("input is `{}`", input)), |ctx| {
                ctx.it(
                    msg(format!(
                        "means known suffix {}",
                        val(&Some(known_suffix.to_string()))
                    )),
                    move |_| {
                        let suffix = LIST.suffix(input.as_bytes()).unwrap();
                        assert_eq!(suffix.typ(), typ);
                        if suffix.is_known() == known_suffix {
                            ExampleResult::Success
                        } else {
                            let msg = format!(
                                "expected `{:?}` but found `{:?}`",
                                known_suffix,
                                suffix.is_known()
                            );
                            ExampleResult::Failure(Some(msg))
                        }
                    },
                );
            });
        }
    }));
}

// Converts a String to &'static str
//
// This will leak memory but that's OK for our testing purposes
fn msg(s: String) -> &'static str {
    unsafe {
        let ret = mem::transmute(&s as &str);
        mem::forget(s);
        ret
    }
}

fn val(s: &Option<String>) -> String {
    match *s {
        Some(ref v) => format!("should be `{}`", v),
        None => format!("is invalid"),
    }
}

fn expected_tld(input: &str) -> bool {
    let var = if let Ok(var) = env::var("PSL_TLD") {
        var
    } else {
        String::new()
    };
    var.trim().is_empty() || input.trim().trim_end_matches('.').ends_with(&var)
}
<commit_msg>allow testing without anycase<commit_after>use std::fs::File;
use std::io::prelude::*;
use std::path::Path;
use std::{env, mem, str};

use psl_lexer::request;
use publicsuffix::{List, Psl, Type};
use rspec::report::ExampleResult;

lazy_static::lazy_static! {
    static ref ROOT: String = env::var("CARGO_MANIFEST_DIR").unwrap();
    static ref LIST: List = {
        let path = Path::new(ROOT.as_str())
            .join("tests")
            .join("public_suffix_list.dat");
        let mut file = File::open(path).unwrap();
        let mut contents = String::new();
        file.read_to_string(&mut contents).unwrap();
        contents.parse().unwrap()
    };
}

#[test]
fn list_behaviour() {
    rspec::run(&rspec::describe("the official test", (), |ctx| {
        let tests = "https://raw.githubusercontent.com/publicsuffix/list/master/tests/tests.txt";
        let body = request(tests).unwrap_or_else(|_| {
            let path = Path::new(ROOT.as_str()).join("tests").join("tests.txt");
            let mut file = File::open(path).unwrap();
            let mut contents = String::new();
            file.read_to_string(&mut contents).unwrap();
            contents
        });

        let mut parse = false;

        for (i, line) in body.lines().enumerate() {
            match line {
                line if line.trim().is_empty() => {
                    parse = true;
                    continue;
                }
                line if line.starts_with("//") => {
                    continue;
                }
                line => {
                    if !parse {
                        continue;
                    }
                    let mut test = line.split_whitespace().peekable();
                    if test.peek().is_none() {
                        continue;
                    }
                    let input = match test.next() {
                        Some("null") => "",
                        Some(res) => res,
                        None => {
                            panic!(format!(
                                "line {} of the test file doesn't seem to be valid",
                                i
                            ));
                        }
                    };
                    if !expected_tld(input) {
                        continue;
                    }
                    let (expected_root, expected_suffix) = match test.next() {
                        Some("null") => (None, None),
                        Some(root) => {
                            let suffix = {
                                let parts: Vec<&str> = root.split('.').rev().collect();
                                (&parts[..parts.len() - 1])
                                    .iter()
                                    .rev()
                                    .map(|part| *part)
                                    .collect::<Vec<_>>()
                                    .join(".")
                            };
                            (Some(root.to_string()), Some(suffix.to_string()))
                        }
                        None => {
                            panic!(format!(
                                "line {} of the test file doesn't seem to be valid",
                                i
                            ));
                        }
                    };
                    let (found_root, found_suffix) =
                        if input.starts_with(".") || input.contains("..") {
                            (None, None)
                        } else {
                            LIST.domain(input.to_lowercase().as_bytes())
                                .map(|d| {
                                    let domain = str::from_utf8(d.as_bytes()).unwrap().to_string();
                                    let suffix =
                                        str::from_utf8(d.suffix().as_bytes()).unwrap().to_string();
                                    (Some(domain), Some(suffix))
                                })
                                .unwrap_or((None, None))
                        };
                    ctx.when(msg(format!("input is `{}`", input)), |ctx| {
                        let full_domain = expected_root.is_some();

                        ctx.it(msg(format!("means the root domain {}", val(&expected_root))), move |_| {
                            if expected_root == found_root {
                                ExampleResult::Success
                            } else {
                                let msg = format!("expected `{:?}` but found `{:?}` on line {} of `test_psl.txt`", expected_root, found_root, i+1);
                                ExampleResult::Failure(Some(msg))
                            }
                        });

                        if full_domain {
                            ctx.it(msg(format!("also means the suffix {}", val(&expected_suffix))), move |_| {
                                if expected_suffix == found_suffix {
                                    ExampleResult::Success
                                } else {
                                    let msg = format!("expected `{:?}` but found `{:?}` on line {} of `test_psl.txt`", expected_suffix, found_suffix, i+1);
                                    ExampleResult::Failure(Some(msg))
                                }
                            });
                        }
                    });
                }
            }
        }
    }));

    rspec::run(&rspec::describe("suffix tests", (), |ctx| {
        let extra = vec![
            (
                "gp-id-ter-acc-1.to.gp-kl-cas-11-ses001-ses-1.wdsl.5m.za",
                "za",
            ),
            ("yokohama.jp", "jp"),
            ("kobe.jp", "jp"),
            #[cfg(feature = "anycase")]
            ("foo.bar.platformsh.Site", "bar.platformsh.Site"),
            ("bar.platformsh.site", "bar.platformsh.site"),
            ("platform.sh", "sh"),
            ("sh", "sh"),
            (".", "."),
            ("example.com.", "com."),
            ("www.食狮.中国", "中国"),
            ("www.xn--85x722f.xn--55qx5d.cn", "xn--55qx5d.cn"),
            ("a.b.example.uk.com", "uk.com"),
            ("_tcp.example.com.", "com."),
        ];

        for (input, expected) in extra {
            if !expected_tld(input) {
                continue;
            }
            ctx.when(msg(format!("input is `{}`", input)), |ctx| {
                let expected_suffix = Some(expected);
                ctx.it(
                    msg(format!(
                        "means the suffix {}",
                        val(&expected_suffix.map(ToString::to_string))
                    )),
                    move |_| {
                        let suffix = LIST.suffix(input.as_bytes()).unwrap();
                        if suffix == expected {
                            ExampleResult::Success
                        } else {
                            let msg = format!(
                                "expected `{:?}` but found `{:?}`",
                                expected_suffix,
                                Some(str::from_utf8(suffix.as_bytes()).unwrap().to_string())
                            );
                            ExampleResult::Failure(Some(msg))
                        }
                    },
                );
            });
        }
    }));

    rspec::run(&rspec::describe("suffix type tests", (), |ctx| {
        let extra = vec![
            (
                "gp-id-ter-acc-1.to.gp-kl-cas-11-ses001-ses-1.wdsl.5m.za",
                false,
                None,
            ),
            ("yokohama.jp", true, Some(Type::Icann)),
            ("kobe.jp", true, Some(Type::Icann)),
            ("foo.bar.platformsh.site", true, Some(Type::Private)),
            ("bar.platformsh.site", true, Some(Type::Private)),
            ("platform.sh", true, Some(Type::Icann)),
            ("sh", true, Some(Type::Icann)),
            (".", false, None),
            ("example.gafregsrse", false, None),
            ("www.食狮.中国", true, Some(Type::Icann)),
            ("www.xn--85x722f.xn--55qx5d.cn", true, Some(Type::Icann)),
        ];

        for (input, known_suffix, typ) in extra {
            if !expected_tld(input) {
                continue;
            }
            ctx.when(msg(format!("input is `{}`", input)), |ctx| {
                ctx.it(
                    msg(format!(
                        "means known suffix {}",
                        val(&Some(known_suffix.to_string()))
                    )),
                    move |_| {
                        let suffix = LIST.suffix(input.as_bytes()).unwrap();
                        assert_eq!(suffix.typ(), typ);
                        if suffix.is_known() == known_suffix {
                            ExampleResult::Success
                        } else {
                            let msg = format!(
                                "expected `{:?}` but found `{:?}`",
                                known_suffix,
                                suffix.is_known()
                            );
                            ExampleResult::Failure(Some(msg))
                        }
                    },
                );
            });
        }
    }));
}

// Converts a String to &'static str
//
// This will leak memory but that's OK for our testing purposes
fn msg(s: String) -> &'static str {
    unsafe {
        let ret = mem::transmute(&s as &str);
        mem::forget(s);
        ret
    }
}

fn val(s: &Option<String>) -> String {
    match *s {
        Some(ref v) => format!("should be `{}`", v),
        None => format!("is invalid"),
    }
}

fn expected_tld(input: &str) -> bool {
    let var = if let Ok(var) = env::var("PSL_TLD") {
        var
    } else {
        String::new()
    };
    var.trim().is_empty() || input.trim().trim_end_matches('.').ends_with(&var)
}
<|endoftext|>