<commit_before>/// Asserts that the type implements exactly one in a set of traits.
///
/// This is achieved by combining [`assert_impl_any!`] with
/// [`assert_not_impl_all!`].
///
/// # Examples
///
/// Given some type `Foo`, it is expected to implement either `Snap`, `Crackle`,
/// or `Pop`:
///
/// ```compile_fail
/// # use static_assertions::assert_impl_one; fn main() {}
/// struct Foo;
///
/// trait Snap {}
/// trait Crackle {}
/// trait Pop {}
///
/// assert_impl_one!(Foo: Snap, Crackle, Pop);
/// ```
///
/// If _only_ `Crackle` is implemented, the assertion passes:
///
/// ```
/// # use static_assertions::assert_impl_one; fn main() {}
/// # struct Foo;
/// # trait Snap {}
/// # trait Crackle {}
/// # trait Pop {}
/// impl Crackle for Foo {}
///
/// assert_impl_one!(Foo: Snap, Crackle, Pop);
/// ```
///
/// If `Snap` or `Pop` is _also_ implemented, the assertion fails:
///
/// ```compile_fail
/// # use static_assertions::assert_impl_one; fn main() {}
/// # struct Foo;
/// # trait Snap {}
/// # trait Crackle {}
/// # trait Pop {}
/// # impl Crackle for Foo {}
/// impl Pop for Foo {}
///
/// assert_impl_one!(Foo: Snap, Crackle, Pop);
/// ```
///
/// [`assert_impl_any!`]:     macro.assert_impl_any.html
/// [`assert_not_impl_all!`]: macro.assert_not_impl_all.html
#[macro_export]
macro_rules! assert_impl_one {
    ($x:ty: $($t:path),+ $(,)?) => {
        const _: fn() = || {
            // Generic trait that must be implemented for `$x` exactly once.
            trait AmbiguousIfMoreThanOne<A> {
                // Required for actually being able to reference the trait.
                fn some_item() {}
            }

            // Creates multiple scoped `Token` types for each trait `$t`, over
            // which a specialized `AmbiguousIfMoreThanOne<Token>` is
            // implemented for every type that implements `$t`.
            $({
                #[allow(dead_code)]
                struct Token;

                impl<T: ?Sized + $t> AmbiguousIfMoreThanOne<Token> for T {}
            })+

            // If there is only one specialized trait impl, type inference with
            // `_` can be resolved and this can compile. Fails to compile if
            // `$x` implements more than one `AmbiguousIfMoreThanOne<Token>` or
            // does not implement any at all.
            let _ = <$x as AmbiguousIfMoreThanOne<_>>::some_item;
        };
    };
}

/// Asserts that the type implements _all_ of the given traits.
///
/// See [`assert_not_impl_all!`] for achieving the opposite effect.
///
/// # Examples
///
/// This can be used to ensure types implement auto traits such as [`Send`] and
/// [`Sync`], as well as traits with [blanket `impl`s][blanket].
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_impl_all!(u32: Copy, Send);
/// assert_impl_all!(&str: Into<String>);
/// ```
///
/// The following example fails to compile because raw pointers do not implement
/// [`Send`] since they cannot be moved between threads safely:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_impl_all!(*const u8: Send);
/// ```
///
/// [`assert_not_impl_all!`]: macro.assert_not_impl_all.html
/// [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
/// [blanket]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
#[macro_export]
macro_rules! assert_impl_all {
    ($type:ty: $($trait:path),+ $(,)?) => {
        const _: fn() = || {
            // Only callable when `$type` implements all traits in `$($trait)+`.
            fn assert_impl_all<T: ?Sized $(+ $trait)+>() {}
            assert_impl_all::<$type>();
        };
    };
}

/// Asserts that the type implements _any_ of the given traits.
///
/// See [`assert_not_impl_any!`] for achieving the opposite effect.
///
/// # Examples
///
/// `u8` cannot be converted from `u16`, but it can be converted into `u16`:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_impl_any!(u8: From<u16>, Into<u16>);
/// ```
///
/// The unit type cannot be converted from `u8` or `u16`, but it does implement
/// [`Send`]:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_impl_any!((): From<u8>, From<u16>, Send);
/// ```
///
/// The following example fails to compile because raw pointers do not implement
/// [`Send`] or [`Sync`] since they cannot be moved or shared between threads
/// safely:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_impl_any!(*const u8: Send, Sync);
/// ```
///
/// [`assert_not_impl_any!`]: macro.assert_not_impl_any.html
/// [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
#[macro_export]
macro_rules! assert_impl_any {
    ($x:ty: $($t:path),+ $(,)?) => {
        const _: fn() = || {
            use $crate::_core::marker::PhantomData;
            use $crate::_core::ops::Deref;

            // Fallback to use as the first iterative assignment to `previous`.
            let previous = AssertImplAnyFallback;
            struct AssertImplAnyFallback;

            // Ensures that blanket traits can't impersonate the method. This
            // prevents a false positive attack where---if a blanket trait is in
            // scope that has `_static_assertions_impl_any`---the macro will
            // compile when it shouldn't.
            //
            // See https://github.com/nvzqz/static-assertions-rs/issues/19 for
            // more info.
            struct ActualAssertImplAnyToken;
            trait AssertImplAnyToken {}
            impl AssertImplAnyToken for ActualAssertImplAnyToken {}
            fn assert_impl_any_token<T: AssertImplAnyToken>(_: T) {}

            $(let previous = {
                struct Wrapper<T, N>(PhantomData<T>, N);

                // If the method for this wrapper can't be called then the
                // compiler will insert a deref and try again. This forwards the
                // compiler's next attempt to the previous wrapper.
                impl<T, N> Deref for Wrapper<T, N> {
                    type Target = N;

                    fn deref(&self) -> &Self::Target {
                        &self.1
                    }
                }

                // This impl is bounded on the `$t` trait, so the method can
                // only be called if `$x` implements `$t`. This is why a new
                // `Wrapper` is defined for each `previous`.
                impl<T: $t, N> Wrapper<T, N> {
                    fn _static_assertions_impl_any(&self) -> ActualAssertImplAnyToken {
                        ActualAssertImplAnyToken
                    }
                }

                Wrapper::<$x, _>(PhantomData, previous)
            };)+

            // Attempt to find the method that can actually be called. The found
            // method must return a type that implements the sealed `Token`
            // trait, this ensures that blanket trait methods can't cause this
            // macro to compile.
            assert_impl_any_token(previous._static_assertions_impl_any());
        };
    };
}

/// Asserts that the type does **not** implement _all_ of the given traits.
///
/// This can be used to ensure types do not implement auto traits such as
/// [`Send`] and [`Sync`], as well as traits with [blanket `impl`s][blanket].
///
/// Note that the combination of all provided traits is required to not be
/// implemented. If you want to check that none of multiple traits are
/// implemented you should invoke [`assert_not_impl_any!`] instead.
///
/// # Examples
///
/// Although `u32` implements `From<u16>`, it does not implement `Into<usize>`:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_not_impl_all!(u32: From<u16>, Into<usize>);
/// ```
///
/// The following example fails to compile since `u32` can be converted into
/// `u64`.
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_not_impl_all!(u32: Into<u64>);
/// ```
///
/// The following compiles because [`Cell`] is not both [`Sync`] _and_ [`Send`]:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// use std::cell::Cell;
///
/// assert_not_impl_all!(Cell<u32>: Sync, Send);
/// ```
///
/// But it is [`Send`], so this fails to compile:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// # std::cell::Cell;
/// assert_not_impl_all!(Cell<u32>: Send);
/// ```
///
/// [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
/// [`assert_not_impl_any!`]: macro.assert_not_impl_any.html
/// [`Cell`]: https://doc.rust-lang.org/std/cell/struct.Cell.html
/// [blanket]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
#[macro_export]
macro_rules! assert_not_impl_all {
    ($x:ty: $($t:path),+ $(,)?) => {
        const _: fn() = || {
            // Generic trait with a blanket impl over `()` for all types.
            trait AmbiguousIfImpl<A> {
                // Required for actually being able to reference the trait.
                fn some_item() {}
            }

            impl<T: ?Sized> AmbiguousIfImpl<()> for T {}

            // Used for the specialized impl when *all* traits in
            // `$($t)+` are implemented.
            #[allow(dead_code)]
            struct Invalid;

            impl<T: ?Sized $(+ $t)+> AmbiguousIfImpl<Invalid> for T {}

            // If there is only one specialized trait impl, type inference with
            // `_` can be resolved and this can compile. Fails to compile if
            // `$x` implements `AmbiguousIfImpl<Invalid>`.
            let _ = <$x as AmbiguousIfImpl<_>>::some_item;
        };
    };
}

/// Asserts that the type does **not** implement _any_ of the given traits.
///
/// This can be used to ensure types do not implement auto traits such as
/// [`Send`] and [`Sync`], as well as traits with [blanket `impl`s][blanket].
///
/// This macro causes a compilation failure if any of the provided individual
/// traits are implemented for the type. If you want to check that a combination
/// of traits is not implemented you should invoke [`assert_not_impl_all!`]
/// instead. For single traits both macros behave the same.
///
/// # Examples
///
/// If `u32` were to implement `Into` conversions for `usize` _and_ for `u8`,
/// the following would fail to compile:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_not_impl_any!(u32: Into<usize>, Into<u8>);
/// ```
///
/// This is also good for simple one-off cases:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_not_impl_any!(&'static mut u8: Copy);
/// ```
///
/// The following example fails to compile since `u32` can be converted into
/// `u64` even though it can not be converted into a `u16`:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_not_impl_any!(u32: Into<u64>, Into<u16>);
/// ```
///
/// [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
/// [`assert_not_impl_all!`]: macro.assert_not_impl_all.html
/// [blanket]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
#[macro_export]
macro_rules! assert_not_impl_any {
    ($x:ty: $($t:path),+ $(,)?) => {
        const _: fn() = || {
            // Generic trait with a blanket impl over `()` for all types.
            trait AmbiguousIfImpl<A> {
                // Required for actually being able to reference the trait.
                fn some_item() {}
            }

            impl<T: ?Sized> AmbiguousIfImpl<()> for T {}

            // Creates multiple scoped `Invalid` types for each trait `$t`, over
            // which a specialized `AmbiguousIfImpl<Invalid>` is implemented for
            // every type that implements `$t`.
            $({
                #[allow(dead_code)]
                struct Invalid;

                impl<T: ?Sized + $t> AmbiguousIfImpl<Invalid> for T {}
            })+

            // If there is only one specialized trait impl, type inference with
            // `_` can be resolved and this can compile. Fails to compile if
            // `$x` implements any `AmbiguousIfImpl<Invalid>`.
            let _ = <$x as AmbiguousIfImpl<_>>::some_item;
        };
    };
}
<commit_msg>Change assert_impl_one! docs<commit_after>/// Asserts that the type implements exactly one in a set of traits.
///
/// Related:
/// - [`assert_impl_any!`]
/// - [`assert_impl_all!`]
/// - [`assert_not_impl_all!`]
/// - [`assert_not_impl_any!`]
///
/// # Examples
///
/// Given some type `Foo`, it is expected to implement either `Snap`, `Crackle`,
/// or `Pop`:
///
/// ```compile_fail
/// # use static_assertions::assert_impl_one; fn main() {}
/// struct Foo;
///
/// trait Snap {}
/// trait Crackle {}
/// trait Pop {}
///
/// assert_impl_one!(Foo: Snap, Crackle, Pop);
/// ```
///
/// If _only_ `Crackle` is implemented, the assertion passes:
///
/// ```
/// # use static_assertions::assert_impl_one; fn main() {}
/// # struct Foo;
/// # trait Snap {}
/// # trait Crackle {}
/// # trait Pop {}
/// impl Crackle for Foo {}
///
/// assert_impl_one!(Foo: Snap, Crackle, Pop);
/// ```
///
/// If `Snap` or `Pop` is _also_ implemented, the assertion fails:
///
/// ```compile_fail
/// # use static_assertions::assert_impl_one; fn main() {}
/// # struct Foo;
/// # trait Snap {}
/// # trait Crackle {}
/// # trait Pop {}
/// # impl Crackle for Foo {}
/// impl Pop for Foo {}
///
/// assert_impl_one!(Foo: Snap, Crackle, Pop);
/// ```
///
/// [`assert_impl_any!`]:     macro.assert_impl_any.html
/// [`assert_impl_all!`]:     macro.assert_impl_all.html
/// [`assert_not_impl_all!`]: macro.assert_not_impl_all.html
/// [`assert_not_impl_any!`]: macro.assert_not_impl_any.html
#[macro_export]
macro_rules! assert_impl_one {
    ($x:ty: $($t:path),+ $(,)?) => {
        const _: fn() = || {
            // Generic trait that must be implemented for `$x` exactly once.
            trait AmbiguousIfMoreThanOne<A> {
                // Required for actually being able to reference the trait.
                fn some_item() {}
            }

            // Creates multiple scoped `Token` types for each trait `$t`, over
            // which a specialized `AmbiguousIfMoreThanOne<Token>` is
            // implemented for every type that implements `$t`.
            $({
                #[allow(dead_code)]
                struct Token;

                impl<T: ?Sized + $t> AmbiguousIfMoreThanOne<Token> for T {}
            })+

            // If there is only one specialized trait impl, type inference with
            // `_` can be resolved and this can compile. Fails to compile if
            // `$x` implements more than one `AmbiguousIfMoreThanOne<Token>` or
            // does not implement any at all.
            let _ = <$x as AmbiguousIfMoreThanOne<_>>::some_item;
        };
    };
}

/// Asserts that the type implements _all_ of the given traits.
///
/// See [`assert_not_impl_all!`] for achieving the opposite effect.
///
/// # Examples
///
/// This can be used to ensure types implement auto traits such as [`Send`] and
/// [`Sync`], as well as traits with [blanket `impl`s][blanket].
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_impl_all!(u32: Copy, Send);
/// assert_impl_all!(&str: Into<String>);
/// ```
///
/// The following example fails to compile because raw pointers do not implement
/// [`Send`] since they cannot be moved between threads safely:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_impl_all!(*const u8: Send);
/// ```
///
/// [`assert_not_impl_all!`]: macro.assert_not_impl_all.html
/// [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
/// [blanket]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
#[macro_export]
macro_rules! assert_impl_all {
    ($type:ty: $($trait:path),+ $(,)?) => {
        const _: fn() = || {
            // Only callable when `$type` implements all traits in `$($trait)+`.
            fn assert_impl_all<T: ?Sized $(+ $trait)+>() {}
            assert_impl_all::<$type>();
        };
    };
}

/// Asserts that the type implements _any_ of the given traits.
///
/// See [`assert_not_impl_any!`] for achieving the opposite effect.
///
/// # Examples
///
/// `u8` cannot be converted from `u16`, but it can be converted into `u16`:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_impl_any!(u8: From<u16>, Into<u16>);
/// ```
///
/// The unit type cannot be converted from `u8` or `u16`, but it does implement
/// [`Send`]:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_impl_any!((): From<u8>, From<u16>, Send);
/// ```
///
/// The following example fails to compile because raw pointers do not implement
/// [`Send`] or [`Sync`] since they cannot be moved or shared between threads
/// safely:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_impl_any!(*const u8: Send, Sync);
/// ```
///
/// [`assert_not_impl_any!`]: macro.assert_not_impl_any.html
/// [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
#[macro_export]
macro_rules! assert_impl_any {
    ($x:ty: $($t:path),+ $(,)?) => {
        const _: fn() = || {
            use $crate::_core::marker::PhantomData;
            use $crate::_core::ops::Deref;

            // Fallback to use as the first iterative assignment to `previous`.
            let previous = AssertImplAnyFallback;
            struct AssertImplAnyFallback;

            // Ensures that blanket traits can't impersonate the method. This
            // prevents a false positive attack where---if a blanket trait is in
            // scope that has `_static_assertions_impl_any`---the macro will
            // compile when it shouldn't.
            //
            // See https://github.com/nvzqz/static-assertions-rs/issues/19 for
            // more info.
            struct ActualAssertImplAnyToken;
            trait AssertImplAnyToken {}
            impl AssertImplAnyToken for ActualAssertImplAnyToken {}
            fn assert_impl_any_token<T: AssertImplAnyToken>(_: T) {}

            $(let previous = {
                struct Wrapper<T, N>(PhantomData<T>, N);

                // If the method for this wrapper can't be called then the
                // compiler will insert a deref and try again. This forwards the
                // compiler's next attempt to the previous wrapper.
                impl<T, N> Deref for Wrapper<T, N> {
                    type Target = N;

                    fn deref(&self) -> &Self::Target {
                        &self.1
                    }
                }

                // This impl is bounded on the `$t` trait, so the method can
                // only be called if `$x` implements `$t`. This is why a new
                // `Wrapper` is defined for each `previous`.
                impl<T: $t, N> Wrapper<T, N> {
                    fn _static_assertions_impl_any(&self) -> ActualAssertImplAnyToken {
                        ActualAssertImplAnyToken
                    }
                }

                Wrapper::<$x, _>(PhantomData, previous)
            };)+

            // Attempt to find the method that can actually be called. The found
            // method must return a type that implements the sealed `Token`
            // trait, this ensures that blanket trait methods can't cause this
            // macro to compile.
            assert_impl_any_token(previous._static_assertions_impl_any());
        };
    };
}

/// Asserts that the type does **not** implement _all_ of the given traits.
///
/// This can be used to ensure types do not implement auto traits such as
/// [`Send`] and [`Sync`], as well as traits with [blanket `impl`s][blanket].
///
/// Note that the combination of all provided traits is required to not be
/// implemented. If you want to check that none of multiple traits are
/// implemented you should invoke [`assert_not_impl_any!`] instead.
///
/// # Examples
///
/// Although `u32` implements `From<u16>`, it does not implement `Into<usize>`:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_not_impl_all!(u32: From<u16>, Into<usize>);
/// ```
///
/// The following example fails to compile since `u32` can be converted into
/// `u64`.
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_not_impl_all!(u32: Into<u64>);
/// ```
///
/// The following compiles because [`Cell`] is not both [`Sync`] _and_ [`Send`]:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// use std::cell::Cell;
///
/// assert_not_impl_all!(Cell<u32>: Sync, Send);
/// ```
///
/// But it is [`Send`], so this fails to compile:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// # std::cell::Cell;
/// assert_not_impl_all!(Cell<u32>: Send);
/// ```
///
/// [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
/// [`assert_not_impl_any!`]: macro.assert_not_impl_any.html
/// [`Cell`]: https://doc.rust-lang.org/std/cell/struct.Cell.html
/// [blanket]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
#[macro_export]
macro_rules! assert_not_impl_all {
    ($x:ty: $($t:path),+ $(,)?) => {
        const _: fn() = || {
            // Generic trait with a blanket impl over `()` for all types.
            trait AmbiguousIfImpl<A> {
                // Required for actually being able to reference the trait.
                fn some_item() {}
            }

            impl<T: ?Sized> AmbiguousIfImpl<()> for T {}

            // Used for the specialized impl when *all* traits in
            // `$($t)+` are implemented.
            #[allow(dead_code)]
            struct Invalid;

            impl<T: ?Sized $(+ $t)+> AmbiguousIfImpl<Invalid> for T {}

            // If there is only one specialized trait impl, type inference with
            // `_` can be resolved and this can compile. Fails to compile if
            // `$x` implements `AmbiguousIfImpl<Invalid>`.
            let _ = <$x as AmbiguousIfImpl<_>>::some_item;
        };
    };
}

/// Asserts that the type does **not** implement _any_ of the given traits.
///
/// This can be used to ensure types do not implement auto traits such as
/// [`Send`] and [`Sync`], as well as traits with [blanket `impl`s][blanket].
///
/// This macro causes a compilation failure if any of the provided individual
/// traits are implemented for the type. If you want to check that a combination
/// of traits is not implemented you should invoke [`assert_not_impl_all!`]
/// instead. For single traits both macros behave the same.
///
/// # Examples
///
/// If `u32` were to implement `Into` conversions for `usize` _and_ for `u8`,
/// the following would fail to compile:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_not_impl_any!(u32: Into<usize>, Into<u8>);
/// ```
///
/// This is also good for simple one-off cases:
///
/// ```
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_not_impl_any!(&'static mut u8: Copy);
/// ```
///
/// The following example fails to compile since `u32` can be converted into
/// `u64` even though it can not be converted into a `u16`:
///
/// ```compile_fail
/// # #[macro_use] extern crate static_assertions; fn main() {}
/// assert_not_impl_any!(u32: Into<u64>, Into<u16>);
/// ```
///
/// [`Send`]: https://doc.rust-lang.org/std/marker/trait.Send.html
/// [`Sync`]: https://doc.rust-lang.org/std/marker/trait.Sync.html
/// [`assert_not_impl_all!`]: macro.assert_not_impl_all.html
/// [blanket]: https://doc.rust-lang.org/book/ch10-02-traits.html#using-trait-bounds-to-conditionally-implement-methods
#[macro_export]
macro_rules! assert_not_impl_any {
    ($x:ty: $($t:path),+ $(,)?) => {
        const _: fn() = || {
            // Generic trait with a blanket impl over `()` for all types.
            trait AmbiguousIfImpl<A> {
                // Required for actually being able to reference the trait.
                fn some_item() {}
            }

            impl<T: ?Sized> AmbiguousIfImpl<()> for T {}

            // Creates multiple scoped `Invalid` types for each trait `$t`, over
            // which a specialized `AmbiguousIfImpl<Invalid>` is implemented for
            // every type that implements `$t`.
            $({
                #[allow(dead_code)]
                struct Invalid;

                impl<T: ?Sized + $t> AmbiguousIfImpl<Invalid> for T {}
            })+

            // If there is only one specialized trait impl, type inference with
            // `_` can be resolved and this can compile. Fails to compile if
            // `$x` implements any `AmbiguousIfImpl<Invalid>`.
            let _ = <$x as AmbiguousIfImpl<_>>::some_item;
        };
    };
}
<|endoftext|>


<commit_before>#![feature(phase)]
#[phase(syntax, link)] extern crate log;
extern crate collections;
extern crate sync;
extern crate rand;
extern crate serialize;
use std::cmp::min;
use std::io::{IoResult, IoError, InvalidInput, SeekStyle, MemWriter};
use std::io::{SeekSet, SeekEnd, SeekCur};
use serialize::ebml::{reader,writer};
use serialize::{Encodable, Decodable};
mod buffer;

#[deriving(Encodable, Decodable)]
enum SqlType {
	Char(uint),
	Varchar(uint),
	Integer,
}

#[deriving(Encodable, Decodable)]
enum SqlAttribute {
	Null,
	NotNull,
}

#[deriving(Encodable, Decodable)]
struct Column {
	name: ~str,
	datatype: SqlType,
	attributes: Vec<SqlAttribute>,
}

#[deriving(Encodable, Decodable)]
struct Relation {
	name: ~str,
	columns: Vec<Column>,
}

impl Relation {
	pub fn new(name: ~str) -> Relation {
		Relation {name: name, columns: Vec::new()}
	}

	pub fn add_column(&mut self, column: Column) {
		self.columns.push(column);
	}
}

#[deriving(Encodable, Decodable)]
struct Schema {
	relations: Vec<Relation>,
}

struct SchemaWriter{
	buffer_manager: buffer::BufferManager,
	location: u64,
}

impl Writer for SchemaWriter {
	fn write(&mut self, buf: &[u8]) -> IoResult<()> {
		let pageno = self.location / buffer::PAGE_SIZE as u64;
		let start_from = (self.location % buffer::PAGE_SIZE as u64) as uint;
		//let remaining_bytes = buffer::PAGE_SIZE - start_from;

		let pagelock = self.buffer_manager.fix_page(pageno).unwrap_or_else(|| fail!("Fix page failed"));
		let mut copied = 0;
		{
			let mut page = pagelock.write();
			let content = page.get_mut_data();

			for i in range(0, min(buf.len(), buffer::PAGE_SIZE)) {
				content[start_from+i] = buf[i];
				copied += 1;
				self.location += 1;
			}
		}
		self.buffer_manager.unfix_page(pagelock, true);
		//TODO remaining bytes from buf
		println!("copied {}/{}, location: {}", copied, buf.len(), self.location);
		//assert!(copied, buf.len());
		if copied == buf.len() {
			Ok(())
		} else {
			Err(IoError {
				kind: InvalidInput,
				desc: "Did not copy all data",
				detail: None,
			})
		}
	}
}

impl Seek for SchemaWriter {
	fn tell(&self) -> IoResult<u64> {
		Ok(self.location)
	}

	fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
		println!("Seeking {}", pos);
		match style {
			SeekSet => {
				self.location = pos as u64;
				Ok(())
			}
			SeekEnd => {
				Err(IoError {
					kind: InvalidInput,
					desc: "seek to end not supported",
					detail: None,
				})
			}
			SeekCur => {
				self.location = (self.location as i64 + pos) as u64;
				Ok(())
			}
		}
	}
}

impl SchemaWriter {
	pub fn new(bufman: buffer::BufferManager) -> SchemaWriter {
		SchemaWriter {buffer_manager: bufman, location: 0}
	}

	pub fn get_data(&mut self) -> Vec<u8> {
		let mut data: Vec<u8> = Vec::new();

		println!("location: {}", self.location);
		for i in range(0, self.location / buffer::PAGE_SIZE as u64 + 1) {
			println!("Reading page {}", i);
			let pagelock = self.buffer_manager.fix_page(i).unwrap_or_else(
				|| fail!("Failed fixing page {}", i));
			{
				let page = pagelock.read();
				data.push_all(page.get_data());
			}
			self.buffer_manager.unfix_page(pagelock, false);
		}
		data
	}
}

impl Schema {
	pub fn new() -> Schema {
		Schema {relations: Vec::new()}
	}

	pub fn new_from_disk(bufmanager: buffer::BufferManager) -> Schema {
		// TODO
		Schema {relations: Vec::new()}
	}

	pub fn add_relation(&mut self, relation: Relation) {
		self.relations.push(relation);
	}

	pub fn save_to_disk(&self, bufmanager: buffer::BufferManager) {
		let mut wr1 = MemWriter::new();
		let mut wr2 = SchemaWriter::new(bufmanager);
		let v: u64 = 42;
		{
			let mut ebml_w1 = writer::Encoder(&mut wr1);
			let _ = self.encode(&mut ebml_w1);
			let mut ebml_w2 = writer::Encoder(&mut wr2);
			let _ = self.encode(&mut ebml_w2);
		}

		let dta = wr2.get_data();
		println!("wr1 len: {}", wr1.get_ref().len());
		println!("wr2 len: {}", dta.len());
		let ebml_doc1 = reader::Doc(wr1.get_ref());
		let ebml_doc2 = reader::Doc(dta.slice_to(290));
		let mut deser1 = reader::Decoder(ebml_doc1);
		let mut deser2 = reader::Decoder(ebml_doc2);
		let v1: Schema = match Decodable::decode(&mut deser1) {
			Ok(v) => v,
			Err(e) => fail!("Error decoding: {}", e),
		};
		println!("v1 == {:?}", v1);
		let v2: Schema = match Decodable::decode(&mut deser2) {
			Ok(v) => v,
			Err(e) => fail!("Error decoding: {}", e),
		};
		println!("v2 == {:?}", v2);

		for rel in self.relations.iter() {
			//rel.save_to_disk()
		}
	}
}

struct Record {
	// TODO: do we even need this?
	len: uint,
	data: Vec<u8>,
}

impl Record {
	/* move semantics, no copy */
	pub fn new(len: uint, data: Vec<u8>) -> Record {
		Record {len: len, data: data}
	}

	pub fn get_data<'a>(&'a self) -> &'a [u8] {
		self.data.as_slice()
	}
}

struct SPSegment;

/* our newtype struct: create a TID type as an alias to another type */
struct TID(u8);

impl SPSegment {
	pub fn insert(r: Record) -> TID {
		TID(0)
	}

	pub fn remove(tid: TID) -> bool {
		false
	}

	pub fn lookup(tid: TID) -> Record {
		// TODO
		Record {len: 1, data: vec!(1)}
	}

	pub fn update(tid: TID, r: Record) -> bool {
		false
	}
}

#[test]
fn main() {
}

#[test]
fn create_schema() {
	let name = Column {name: ~"name", datatype: Varchar(128), attributes: vec!(NotNull)};
	let age = Column {name: ~"age", datatype: Integer, attributes: vec!(NotNull)};
	let mut relation = Relation::new(~"Person");
	relation.add_column(name);
	relation.add_column(age);
	let mut schema = Schema::new();
	schema.add_relation(relation);
	let mut manager = buffer::BufferManager::new(1024, Path::new("."));
	schema.save_to_disk(manager);
	assert!(false);
}
<commit_msg>Save length of serialized schema into page 0<commit_after>#![feature(phase)]
#[phase(syntax, link)] extern crate log;
extern crate collections;
extern crate sync;
extern crate rand;
extern crate serialize;
use std::cmp::{min, max};
use std::io::{IoResult, IoError, InvalidInput, SeekStyle, MemWriter, BufWriter, BufReader};
use std::io::{SeekSet, SeekEnd, SeekCur};
use serialize::ebml::{reader,writer};
use serialize::{Encodable, Decodable};
mod buffer;

#[deriving(Encodable, Decodable)]
enum SqlType {
	Char(uint),
	Varchar(uint),
	Integer,
}

#[deriving(Encodable, Decodable)]
enum SqlAttribute {
	Null,
	NotNull,
}

#[deriving(Encodable, Decodable)]
struct Column {
	name: ~str,
	datatype: SqlType,
	attributes: Vec<SqlAttribute>,
}

#[deriving(Encodable, Decodable)]
struct Relation {
	name: ~str,
	columns: Vec<Column>,
}

impl Relation {
	pub fn new(name: ~str) -> Relation {
		Relation {name: name, columns: Vec::new()}
	}

	pub fn add_column(&mut self, column: Column) {
		self.columns.push(column);
	}
}

#[deriving(Encodable, Decodable)]
struct Schema {
	relations: Vec<Relation>,
}

struct SchemaWriter{
	buffer_manager: buffer::BufferManager,
	location: u64,
	maximum: u64,
}

impl Writer for SchemaWriter {
	fn write(&mut self, buf: &[u8]) -> IoResult<()> {
		let pageno = self.location / buffer::PAGE_SIZE as u64 + 1;
		let start_from = (self.location % buffer::PAGE_SIZE as u64) as uint;

		let pagelock = self.buffer_manager.fix_page(pageno).unwrap_or_else(|| fail!("Fix page failed"));
		let mut copied = 0;
		{
			let mut page = pagelock.write();
			let content = page.get_mut_data();

			for i in range(0, min(buf.len(), buffer::PAGE_SIZE)) {
				content[start_from+i] = buf[i];
				copied += 1;
				self.location += 1;
			}
		}
		self.buffer_manager.unfix_page(pagelock, true);
		if self.location > self.maximum {
			self.maximum = self.location;
			let pagelock = self.buffer_manager.fix_page(0).unwrap_or_else(
				|| fail!("Fixing zero page failed"));
			{
				let mut page = pagelock.write();
				let content = page.get_mut_data();
				let mut writer = BufWriter::new(content);
				writer.write_le_u64(self.maximum);
			}
			self.buffer_manager.unfix_page(pagelock, true);
		}
		//TODO remaining bytes from buf
		println!("copied {}/{}, location: {}", copied, buf.len(), self.location);
		//assert!(copied, buf.len());
		if copied == buf.len() {
			Ok(())
		} else {
			Err(IoError {
				kind: InvalidInput,
				desc: "Did not copy all data",
				detail: None,
			})
		}
	}
}

impl Seek for SchemaWriter {
	fn tell(&self) -> IoResult<u64> {
		Ok(self.location)
	}

	fn seek(&mut self, pos: i64, style: SeekStyle) -> IoResult<()> {
		println!("Seeking {}", pos);
		match style {
			SeekSet => {
				self.location = pos as u64;
				Ok(())
			}
			SeekEnd => {
				Err(IoError {
					kind: InvalidInput,
					desc: "seek to end not supported",
					detail: None,
				})
			}
			SeekCur => {
				self.location = (self.location as i64 + pos) as u64;
				Ok(())
			}
		}
	}
}

impl SchemaWriter {
	pub fn new(bufman: buffer::BufferManager) -> SchemaWriter {
		SchemaWriter {buffer_manager: bufman, location: 0,
			maximum: 0}
	}

	pub fn get_data(&mut self) -> Vec<u8> {
		let pagelock = self.buffer_manager.fix_page(0).unwrap_or_else(
			|| fail!("Failed fixing 0 page for schema length"));
		let mut size = 0_u64;
		{
			let page = pagelock.read();
			let mut reader = BufReader::new(page.get_data());
			size = reader.read_le_u64().unwrap();
		}
		self.buffer_manager.unfix_page(pagelock, false);
		println!("Size: {}", size);

		let mut data: Vec<u8> = Vec::with_capacity(size as uint);
		let mut read = 0;

		println!("location: {}", self.location);
		for i in range(1, self.location / buffer::PAGE_SIZE as u64 + 2) {
			println!("Reading page {}", i);
			let pagelock = self.buffer_manager.fix_page(i).unwrap_or_else(
				|| fail!("Failed fixing page {}", i));
			{
				let page = pagelock.read();
				let content = page.get_data();
				let mut j = 0;
				while read < size {
					data.push(content[j]);
					j += 1;
					read += 1;
				}
			}
			self.buffer_manager.unfix_page(pagelock, false);
		}
		data
	}
}

impl Schema {
	pub fn new() -> Schema {
		Schema {relations: Vec::new()}
	}

	pub fn new_from_disk(bufmanager: buffer::BufferManager) -> Schema {
		// TODO
		Schema {relations: Vec::new()}
	}

	pub fn add_relation(&mut self, relation: Relation) {
		self.relations.push(relation);
	}

	pub fn save_to_disk(&self, bufmanager: buffer::BufferManager) {
		let mut wr1 = MemWriter::new();
		let mut wr2 = SchemaWriter::new(bufmanager);
		let v: u64 = 42;
		{
			let mut ebml_w1 = writer::Encoder(&mut wr1);
			let _ = self.encode(&mut ebml_w1);
			let mut ebml_w2 = writer::Encoder(&mut wr2);
			let _ = self.encode(&mut ebml_w2);
		}

		let dta = wr2.get_data();
		println!("wr1 len: {}", wr1.get_ref().len());
		println!("wr2 len: {}", dta.len());
		let ebml_doc1 = reader::Doc(wr1.get_ref());
		let ebml_doc2 = reader::Doc(dta.slice_to(290));
		let mut deser1 = reader::Decoder(ebml_doc1);
		let mut deser2 = reader::Decoder(ebml_doc2);
		let v1: Schema = match Decodable::decode(&mut deser1) {
			Ok(v) => v,
			Err(e) => fail!("Error decoding: {}", e),
		};
		println!("v1 == {:?}", v1);
		let v2: Schema = match Decodable::decode(&mut deser2) {
			Ok(v) => v,
			Err(e) => fail!("Error decoding: {}", e),
		};
		println!("v2 == {:?}", v2);

		for rel in self.relations.iter() {
			//rel.save_to_disk()
		}
	}
}

struct Record {
	// TODO: do we even need this?
	len: uint,
	data: Vec<u8>,
}

impl Record {
	/* move semantics, no copy */
	pub fn new(len: uint, data: Vec<u8>) -> Record {
		Record {len: len, data: data}
	}

	pub fn get_data<'a>(&'a self) -> &'a [u8] {
		self.data.as_slice()
	}
}

struct SPSegment;

/* our newtype struct: create a TID type as an alias to another type */
struct TID(u8);

impl SPSegment {
	pub fn insert(r: Record) -> TID {
		TID(0)
	}

	pub fn remove(tid: TID) -> bool {
		false
	}

	pub fn lookup(tid: TID) -> Record {
		// TODO
		Record {len: 1, data: vec!(1)}
	}

	pub fn update(tid: TID, r: Record) -> bool {
		false
	}
}

#[test]
fn main() {
}

#[test]
fn create_schema() {
	let name = Column {name: ~"name", datatype: Varchar(128), attributes: vec!(NotNull)};
	let age = Column {name: ~"age", datatype: Integer, attributes: vec!(NotNull)};
	let mut relation = Relation::new(~"Person");
	relation.add_column(name);
	relation.add_column(age);
	let mut schema = Schema::new();
	schema.add_relation(relation);
	let mut manager = buffer::BufferManager::new(1024, Path::new("."));
	schema.save_to_disk(manager);
	assert!(false);
}
<|endoftext|>


<commit_before>extern crate nom;
extern crate num;

use std::mem;
use std::fmt;

use nom::{IResult, ErrorKind};
use num::bigint;
use num::bigint::ToBigInt;
use num::traits::{Zero, One};

static BERT_MAGIC_NUMBER: u8 = 131;
static SMALL_INTEGER_EXT: u8 = 97;
static INTEGER_EXT: u8 = 98;
static FLOAT_EXT: u8 = 99;
static ATOM_EXT: u8 = 100;
static SMALL_TUPLE_EXT: u8 = 104;
static LARGE_TUPLE_EXT: u8 = 105;
static NIL_EXT: u8 = 106;
static STRING_EXT: u8 = 107;
static LIST_EXT: u8 = 108;
static BINARY_EXT: u8 = 109;
static SMALL_BIG_EXT: u8 = 110;
static LARGE_BIG_EXT: u8 = 111;
static ATOM_UTF8_EXT: u8 = 118;
static SMALL_ATOM_UTF8_EXT: u8 = 119;
static NEW_FLOAT_EXT: u8 = 70;

#[derive(Debug, PartialEq)]
pub enum BertTerm {
    Int(i32),
    BigInt(bigint::BigInt),
    Float(f64),
    Atom(String),
    Tuple(Vec<BertTerm>),
    List(Vec<BertTerm>),
    Binary(Vec<u8>)
}

impl fmt::Display for BertTerm {
    #[allow(unused_must_use)]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            BertTerm::Int(n) => { write!(f, "{}", n) }
            BertTerm::BigInt(ref n) => { write!(f, "{}", n) }
            BertTerm::Float(x) => { write!(f, "{}", x) }
            BertTerm::Atom(ref s) => { write!(f, "{}", s) }
            BertTerm::Tuple(ref ts) => {
                write!(f, "{}", '{');
                let mut first = true;
                for t in ts {
                    if !first { write!(f, ", "); }
                    write!(f, "{}", t);
                    first = false;
                }
                write!(f, "{}", '}')
            }
            BertTerm::List(ref ts) => {
                write!(f, "[");
                let mut first = true;
                for t in ts {
                    if !first { write!(f, ", "); }
                    write!(f, "{}", t);
                    first = false;
                }
                write!(f, "]")
            }
            BertTerm::Binary(ref bytes) => {
                write!(f, "<<");
                let mut first = true;
                for b in bytes {
                    if !first { write!(f, ", "); }
                    write!(f, "{}", b);
                    first = false;
                }
                write!(f, ">>")
            }
        }
    }
}

#[derive(Debug)]
pub enum BertError {
    Unknown,
    InvalidMagicNumber
}

named!(bert_magic_number, tag!([BERT_MAGIC_NUMBER]));

fn small_integer(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([SMALL_INTEGER_EXT]));
    let (i2, n) = try_parse!(i1, nom::be_u8);
    IResult::Done(i2, BertTerm::Int(n as i32))
}

#[test]
fn test_small_integer() {
    for i in 0 .. u8::max_value() {
        let buf = &[SMALL_INTEGER_EXT, i];
        let t = small_integer(buf);
        assert_eq!(t, IResult::Done(&b""[..], BertTerm::Int(i as i32)));
    }
}

fn integer(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([INTEGER_EXT]));
    let (i2, n) = try_parse!(i1, nom::be_i32);
    IResult::Done(i2, BertTerm::Int(n))
}

#[test]
fn test_integer() {
    let buf0 = &[INTEGER_EXT, 0, 0, 0, 1];
    let buf1 = &[INTEGER_EXT, 0, 0, 1, 0];
    let buf2 = &[INTEGER_EXT, 0, 1, 0, 0];
    let buf3 = &[INTEGER_EXT, 1, 0, 0, 0];

    assert_eq!(integer(buf0), IResult::Done(&b""[..], BertTerm::Int(1)));
    assert_eq!(integer(buf1), IResult::Done(&b""[..], BertTerm::Int(1 << 8)));
    assert_eq!(integer(buf2), IResult::Done(&b""[..], BertTerm::Int(1 << 16)));
    assert_eq!(integer(buf3), IResult::Done(&b""[..], BertTerm::Int(1 << 24)));
}

fn atom(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([ATOM_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u16);
    let (i3, atom_name) = try_parse!(i2, take_str!(len));
    IResult::Done(i3, BertTerm::Atom(atom_name.to_string()))
}

#[test]
fn test_atom() {
    let buf = &[ATOM_EXT, 0, 2, b'a', b'b'];
    assert_eq!(atom(buf), IResult::Done(&b""[..], BertTerm::Atom("ab".to_string())));
}

fn small_atom_utf8(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([SMALL_ATOM_UTF8_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u8);
    let (i3, atom_name) = try_parse!(i2, take_str!(len));
    IResult::Done(i3, BertTerm::Atom(atom_name.to_string()))
}

fn atom_utf8(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([ATOM_UTF8_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u16);
    let (i3, atom_name) = try_parse!(i2, take_str!(len));
    IResult::Done(i3, BertTerm::Atom(atom_name.to_string()))
}

fn small_tuple(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([SMALL_TUPLE_EXT]));
    let (i2, arity) = try_parse!(i1, nom::be_u8);
    let (i3, tuple) = try_parse!(i2, count!(bert_term, arity as usize));
    IResult::Done(i3, BertTerm::Tuple(tuple))
}

#[test]
fn test_small_tuple() {
    let buf = &[SMALL_TUPLE_EXT, 2, ATOM_EXT, 0, 2, b'o', b'k', SMALL_INTEGER_EXT, 42];
    assert_eq!(small_tuple(buf),
               IResult::Done(&b""[..],
                             BertTerm::Tuple(vec![BertTerm::Atom("ok".to_string()),
                                                  BertTerm::Int(42)])));
}

fn large_tuple(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([LARGE_TUPLE_EXT]));
    let (i2, arity) = try_parse!(i1, nom::be_u32);
    let (i3, tuple) = try_parse!(i2, count!(bert_term, arity as usize));
    IResult::Done(i3, BertTerm::Tuple(tuple))
}

fn nil(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([NIL_EXT]));
    IResult::Done(i1, BertTerm::List(vec![]))
}

#[test]
fn test_nil() {
    let buf = &[NIL_EXT];
    assert_eq!(nil(buf), IResult::Done(&b""[..], BertTerm::List(vec![])));
}

fn string_like_list(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([STRING_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u16);
    let (i3, nums) = try_parse!(i2, count!(nom::be_u8, len as usize));
    let elements = nums.into_iter().map(|n| BertTerm::Int(n as i32)).collect();
    IResult::Done(i3, BertTerm::List(elements))
}

#[test]
fn string_like_list_test() {
    use self::BertTerm::*;
    let buf = &[STRING_EXT, 0, 5, b'h', b'e', b'l', b'l', b'o'];
    assert_eq!(string_like_list(buf),
               IResult::Done(&b""[..], List(vec![Int(104), Int(101), Int(108), Int(108), Int(111)])));
}

fn list(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([LIST_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u32);
    let (i3, mut elements) = try_parse!(i2, count!(bert_term, len as usize));
    let (i4, tail) = try_parse!(i3, bert_term);
    match tail {
        BertTerm::List(_) => (),
        last_term => { elements.push(last_term); }
    };
    IResult::Done(i4, BertTerm::List(elements))
}

#[test]
fn test_list() {
    use self::BertTerm::*;
    let buf0 = &[
        LIST_EXT, 0, 0, 0, 2,
        SMALL_INTEGER_EXT, 42,
        INTEGER_EXT, 0, 1, 0, 0,
        NIL_EXT
    ];
    let buf1 = &[
        LIST_EXT, 0, 0, 0, 2,
        SMALL_INTEGER_EXT, 42,
        INTEGER_EXT, 0, 1, 0, 0,
        SMALL_INTEGER_EXT, 84
    ];
    assert_eq!(list(buf0), IResult::Done(&b""[..], List(vec![Int(42), Int(65536)])));
    assert_eq!(list(buf1), IResult::Done(&b""[..], List(vec![Int(42), Int(65536), Int(84)])));
}

fn binary(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([BINARY_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u32);
    let (i3, elements) = try_parse!(i2, count!(nom::be_u8, len as usize));
    IResult::Done(i3, BertTerm::Binary(elements))
}

#[test]
fn binary_test() {
    let buf = &[BINARY_EXT, 0, 0, 0, 4, 1, 3, 3, 7];
    assert_eq!(binary(buf), IResult::Done(&b""[..], BertTerm::Binary(vec![1,3,3,7])));
}

fn is_zero(b: u8) -> bool { b == 0 }
fn is_non_zero(b: u8) -> bool { b != 0 }

fn old_float(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([FLOAT_EXT]));
    let (i2, bytes) = try_parse!(i1, take_while!(is_non_zero));
    let (i3, _) = try_parse!(i2, take_while!(is_zero));
    let mut s = String::new();
    for b in bytes { s.push(*b as char); }
    let f = s.parse::<f64>().unwrap();
    IResult::Done(i3, BertTerm::Float(f))
}

fn new_float(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([NEW_FLOAT_EXT]));
    let (i2, raw_bytes) = try_parse!(i1, nom::be_u64);
    let f: f64 = unsafe { mem::transmute(raw_bytes) };
    IResult::Done(i2, BertTerm::Float(f))
}

fn compute_big_int(is_negative: bool, digits: &[u8]) -> bigint::BigInt {
    let mut sum: bigint::BigInt = Zero::zero();
    let mut pos: bigint::BigInt = One::one();
    for d in digits {
        let t = &pos * &(d.to_bigint().unwrap());
        sum = sum + &t;
        pos = pos * (256).to_bigint().unwrap();
    }
    if is_negative { sum = -sum; }
    return sum;
}

fn small_big_int(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([SMALL_BIG_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u8);
    let (i3, sign) = try_parse!(i2, nom::be_u8);
    let (i4, digits) = try_parse!(i3, count!(nom::be_u8, len as usize));
    let b = compute_big_int(sign == 1, &digits);
    IResult::Done(i4, BertTerm::BigInt(b))
}

fn large_big_int(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([LARGE_BIG_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u32);
    let (i3, sign) = try_parse!(i2, nom::be_u8);
    let (i4, digits) = try_parse!(i3, count!(nom::be_u8, len as usize));
    let b = compute_big_int(sign == 1, &digits);
    IResult::Done(i4, BertTerm::BigInt(b))
}

named!(bert_term<&[u8], BertTerm>,
       alt!(small_integer
            | integer
            | atom
            | small_atom_utf8
            | atom_utf8
            | small_tuple
            | large_tuple
            | nil
            | list
            | string_like_list
            | binary
            | old_float
            | new_float
            | small_big_int
            | large_big_int
       )
);

pub fn parse(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, bert_magic_number);
    let (i2, t) = try_parse!(i1, bert_term);
    IResult::Done(i2, t)
}
<commit_msg>Replace a few count!() with take!()<commit_after>extern crate nom;
extern crate num;

use std::mem;
use std::fmt;

use nom::{IResult, ErrorKind};
use num::bigint;
use num::bigint::ToBigInt;
use num::traits::{Zero, One};

static BERT_MAGIC_NUMBER: u8 = 131;
static SMALL_INTEGER_EXT: u8 = 97;
static INTEGER_EXT: u8 = 98;
static FLOAT_EXT: u8 = 99;
static ATOM_EXT: u8 = 100;
static SMALL_TUPLE_EXT: u8 = 104;
static LARGE_TUPLE_EXT: u8 = 105;
static NIL_EXT: u8 = 106;
static STRING_EXT: u8 = 107;
static LIST_EXT: u8 = 108;
static BINARY_EXT: u8 = 109;
static SMALL_BIG_EXT: u8 = 110;
static LARGE_BIG_EXT: u8 = 111;
static ATOM_UTF8_EXT: u8 = 118;
static SMALL_ATOM_UTF8_EXT: u8 = 119;
static NEW_FLOAT_EXT: u8 = 70;

#[derive(Debug, PartialEq)]
pub enum BertTerm {
    Int(i32),
    BigInt(bigint::BigInt),
    Float(f64),
    Atom(String),
    Tuple(Vec<BertTerm>),
    List(Vec<BertTerm>),
    Binary(Vec<u8>)
}

impl fmt::Display for BertTerm {
    #[allow(unused_must_use)]
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            BertTerm::Int(n) => { write!(f, "{}", n) }
            BertTerm::BigInt(ref n) => { write!(f, "{}", n) }
            BertTerm::Float(x) => { write!(f, "{}", x) }
            BertTerm::Atom(ref s) => { write!(f, "{}", s) }
            BertTerm::Tuple(ref ts) => {
                write!(f, "{}", '{');
                let mut first = true;
                for t in ts {
                    if !first { write!(f, ", "); }
                    write!(f, "{}", t);
                    first = false;
                }
                write!(f, "{}", '}')
            }
            BertTerm::List(ref ts) => {
                write!(f, "[");
                let mut first = true;
                for t in ts {
                    if !first { write!(f, ", "); }
                    write!(f, "{}", t);
                    first = false;
                }
                write!(f, "]")
            }
            BertTerm::Binary(ref bytes) => {
                write!(f, "<<");
                let mut first = true;
                for b in bytes {
                    if !first { write!(f, ", "); }
                    write!(f, "{}", b);
                    first = false;
                }
                write!(f, ">>")
            }
        }
    }
}

#[derive(Debug)]
pub enum BertError {
    Unknown,
    InvalidMagicNumber
}

named!(bert_magic_number, tag!([BERT_MAGIC_NUMBER]));

fn small_integer(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([SMALL_INTEGER_EXT]));
    let (i2, n) = try_parse!(i1, nom::be_u8);
    IResult::Done(i2, BertTerm::Int(n as i32))
}

#[test]
fn test_small_integer() {
    for i in 0 .. u8::max_value() {
        let buf = &[SMALL_INTEGER_EXT, i];
        let t = small_integer(buf);
        assert_eq!(t, IResult::Done(&b""[..], BertTerm::Int(i as i32)));
    }
}

fn integer(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([INTEGER_EXT]));
    let (i2, n) = try_parse!(i1, nom::be_i32);
    IResult::Done(i2, BertTerm::Int(n))
}

#[test]
fn test_integer() {
    let buf0 = &[INTEGER_EXT, 0, 0, 0, 1];
    let buf1 = &[INTEGER_EXT, 0, 0, 1, 0];
    let buf2 = &[INTEGER_EXT, 0, 1, 0, 0];
    let buf3 = &[INTEGER_EXT, 1, 0, 0, 0];

    assert_eq!(integer(buf0), IResult::Done(&b""[..], BertTerm::Int(1)));
    assert_eq!(integer(buf1), IResult::Done(&b""[..], BertTerm::Int(1 << 8)));
    assert_eq!(integer(buf2), IResult::Done(&b""[..], BertTerm::Int(1 << 16)));
    assert_eq!(integer(buf3), IResult::Done(&b""[..], BertTerm::Int(1 << 24)));
}

fn atom(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([ATOM_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u16);
    let (i3, atom_name) = try_parse!(i2, take_str!(len));
    IResult::Done(i3, BertTerm::Atom(atom_name.to_string()))
}

#[test]
fn test_atom() {
    let buf = &[ATOM_EXT, 0, 2, b'a', b'b'];
    assert_eq!(atom(buf), IResult::Done(&b""[..], BertTerm::Atom("ab".to_string())));
}

fn small_atom_utf8(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([SMALL_ATOM_UTF8_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u8);
    let (i3, atom_name) = try_parse!(i2, take_str!(len));
    IResult::Done(i3, BertTerm::Atom(atom_name.to_string()))
}

fn atom_utf8(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([ATOM_UTF8_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u16);
    let (i3, atom_name) = try_parse!(i2, take_str!(len));
    IResult::Done(i3, BertTerm::Atom(atom_name.to_string()))
}

fn small_tuple(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([SMALL_TUPLE_EXT]));
    let (i2, arity) = try_parse!(i1, nom::be_u8);
    let (i3, tuple) = try_parse!(i2, count!(bert_term, arity as usize));
    IResult::Done(i3, BertTerm::Tuple(tuple))
}

#[test]
fn test_small_tuple() {
    let buf = &[SMALL_TUPLE_EXT, 2, ATOM_EXT, 0, 2, b'o', b'k', SMALL_INTEGER_EXT, 42];
    assert_eq!(small_tuple(buf),
               IResult::Done(&b""[..],
                             BertTerm::Tuple(vec![BertTerm::Atom("ok".to_string()),
                                                  BertTerm::Int(42)])));
}

fn large_tuple(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([LARGE_TUPLE_EXT]));
    let (i2, arity) = try_parse!(i1, nom::be_u32);
    let (i3, tuple) = try_parse!(i2, count!(bert_term, arity as usize));
    IResult::Done(i3, BertTerm::Tuple(tuple))
}

fn nil(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([NIL_EXT]));
    IResult::Done(i1, BertTerm::List(vec![]))
}

#[test]
fn test_nil() {
    let buf = &[NIL_EXT];
    assert_eq!(nil(buf), IResult::Done(&b""[..], BertTerm::List(vec![])));
}

fn string_like_list(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([STRING_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u16);
    let (i3, nums) = try_parse!(i2, take!(len as usize));
    let elements = nums.iter().map(|n| BertTerm::Int(*n as i32)).collect();
    IResult::Done(i3, BertTerm::List(elements))
}

#[test]
fn string_like_list_test() {
    use self::BertTerm::*;
    let buf = &[STRING_EXT, 0, 5, b'h', b'e', b'l', b'l', b'o'];
    assert_eq!(string_like_list(buf),
               IResult::Done(&b""[..], List(vec![Int(104), Int(101), Int(108), Int(108), Int(111)])));
}

fn list(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([LIST_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u32);
    let (i3, mut elements) = try_parse!(i2, count!(bert_term, len as usize));
    let (i4, tail) = try_parse!(i3, bert_term);
    match tail {
        BertTerm::List(_) => (),
        last_term => { elements.push(last_term); }
    };
    IResult::Done(i4, BertTerm::List(elements))
}

#[test]
fn test_list() {
    use self::BertTerm::*;
    let buf0 = &[
        LIST_EXT, 0, 0, 0, 2,
        SMALL_INTEGER_EXT, 42,
        INTEGER_EXT, 0, 1, 0, 0,
        NIL_EXT
    ];
    let buf1 = &[
        LIST_EXT, 0, 0, 0, 2,
        SMALL_INTEGER_EXT, 42,
        INTEGER_EXT, 0, 1, 0, 0,
        SMALL_INTEGER_EXT, 84
    ];
    assert_eq!(list(buf0), IResult::Done(&b""[..], List(vec![Int(42), Int(65536)])));
    assert_eq!(list(buf1), IResult::Done(&b""[..], List(vec![Int(42), Int(65536), Int(84)])));
}

fn binary(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([BINARY_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u32);
    let (i3, elements) = try_parse!(i2, count!(nom::be_u8, len as usize));
    IResult::Done(i3, BertTerm::Binary(elements))
}

#[test]
fn binary_test() {
    let buf = &[BINARY_EXT, 0, 0, 0, 4, 1, 3, 3, 7];
    assert_eq!(binary(buf), IResult::Done(&b""[..], BertTerm::Binary(vec![1,3,3,7])));
}

fn is_zero(b: u8) -> bool { b == 0 }
fn is_non_zero(b: u8) -> bool { b != 0 }

fn old_float(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([FLOAT_EXT]));
    let (i2, bytes) = try_parse!(i1, take_while!(is_non_zero));
    let (i3, _) = try_parse!(i2, take_while!(is_zero));
    let mut s = String::new();
    for b in bytes { s.push(*b as char); }
    let f = s.parse::<f64>().unwrap();
    IResult::Done(i3, BertTerm::Float(f))
}

fn new_float(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([NEW_FLOAT_EXT]));
    let (i2, raw_bytes) = try_parse!(i1, nom::be_u64);
    let f: f64 = unsafe { mem::transmute(raw_bytes) };
    IResult::Done(i2, BertTerm::Float(f))
}

fn compute_big_int(is_negative: bool, digits: &[u8]) -> bigint::BigInt {
    let mut sum: bigint::BigInt = Zero::zero();
    let mut pos: bigint::BigInt = One::one();
    for d in digits {
        let t = &pos * &(d.to_bigint().unwrap());
        sum = sum + &t;
        pos = pos * (256).to_bigint().unwrap();
    }
    if is_negative { sum = -sum; }
    return sum;
}

fn small_big_int(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([SMALL_BIG_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u8);
    let (i3, sign) = try_parse!(i2, nom::be_u8);
    let (i4, digits) = try_parse!(i3, take!(len as usize));
    let b = compute_big_int(sign == 1, &digits);
    IResult::Done(i4, BertTerm::BigInt(b))
}

fn large_big_int(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, tag!([LARGE_BIG_EXT]));
    let (i2, len) = try_parse!(i1, nom::be_u32);
    let (i3, sign) = try_parse!(i2, nom::be_u8);
    let (i4, digits) = try_parse!(i3, take!(len as usize));
    let b = compute_big_int(sign == 1, &digits);
    IResult::Done(i4, BertTerm::BigInt(b))
}

named!(bert_term<&[u8], BertTerm>,
       alt!(small_integer
            | integer
            | atom
            | small_atom_utf8
            | atom_utf8
            | small_tuple
            | large_tuple
            | nil
            | list
            | string_like_list
            | binary
            | old_float
            | new_float
            | small_big_int
            | large_big_int
       )
);

pub fn parse(i0: &[u8]) -> IResult<&[u8], BertTerm> {
    let (i1, _) = try_parse!(i0, bert_magic_number);
    let (i2, t) = try_parse!(i1, bert_term);
    IResult::Done(i2, t)
}
<|endoftext|>


<commit_before>use std::thread;
use std::thread::JoinHandle;
use std::path::Path;
use std::time::Duration;

use websocket::{WebSocketStream, Server};
use websocket::Message as WebMessage;
use websocket::Sender as WebSender;
use websocket::client::Sender as WebClientSender;
use websocket::Receiver as WebReceiver;
use websocket::message::Type as WebMessageType;
use websocket::server::Connection;
use websocket::header::WebSocketProtocol;

use git2::Repository;
use git2::ObjectType;
use git2::BranchType;

use payload;
use state::State;

extern crate fsevent;
use self::fsevent::Event as FsEvent;
use std::sync::mpsc::channel;
use std::sync::mpsc::Sender;
use std::sync::mpsc::Receiver;

use serde_xml as xml;
use yaml_rust::yaml::Hash;
use yaml_rust::{Yaml, YamlEmitter};

#[derive(Debug)]
enum NotifierMessage<'a> {
    WebMessage(WebMessage<'a>),
    FsEvent(FsEvent)
}

pub fn start() {
    let server = Server::bind("127.0.0.1:2794").unwrap();
    thread::spawn(move || {
        for connection in server {
            thread::spawn(move || connect(connection.unwrap()));
        }
    });
}

fn connect(connection: Connection<WebSocketStream, WebSocketStream>) {
    let request = connection.read_request().unwrap();
    let headers = request.headers.clone();
    request.validate().unwrap();
    let mut response = request.accept();
    println!("Connected");

    if let Some(&WebSocketProtocol(ref protocols)) = headers.get() {
        if protocols.contains(&("superconductor".to_string())) {
            response.headers.set(WebSocketProtocol(vec!["superconductor".to_string()]));
        }
    }

    let mut client = response.send().unwrap();
    let message = WebMessage::text(payload::generate(None));
    client.send_message(&message).unwrap();

    let (tx, rx) = channel::<NotifierMessage>();
    let (mut sender, mut receiver) = client.split();
    let notifier = thread::spawn(move || start_notifier(rx, sender));
    let txc = tx.clone();
    let monitor = thread::spawn(move || start_monitor(txc));
    for message in receiver.incoming_messages() {
        let message: WebMessage = message.unwrap_or(WebMessage::close());
        match message.opcode {
            WebMessageType::Close => {
                tx.send(NotifierMessage::WebMessage(message));
                break;
            },
            _ => tx.send(NotifierMessage::WebMessage(message))
        };
    }
    monitor.join();
    notifier.join();
}

fn start_monitor(tx: Sender<NotifierMessage>) {
    let (ftx, rx) = channel();
    let observer = thread::spawn(move || {
        println!("Monitoring");
        let fsevent = fsevent::FsEvent::new(ftx);
        fsevent.append_path(".");
        fsevent.observe();
    });
    loop {
        let event = rx.recv().unwrap();
        thread::sleep(Duration::from_millis(500));
        let mut events = vec![];
        events.push(event);
        while let Ok(aggregator) = rx.try_recv() {
            events.push(aggregator);
        }
        tx.send(NotifierMessage::FsEvent(events.pop().unwrap()));
    }
    observer.join();
}

fn start_notifier(rx: Receiver<NotifierMessage>, mut sender: WebClientSender<WebSocketStream>) {
    let mut last_state: Option<State> = None;
    loop {
        let value = rx.recv().unwrap();
        match value {
            NotifierMessage::WebMessage(message) => {
                match message.opcode {
                    WebMessageType::Close => {
                        break;
                    },
                    WebMessageType::Ping => {
                        let message = WebMessage::pong(message.payload);
                        sender.send_message(&message).unwrap();
                    },
                    _ => {
                        let payload = String::from_utf8_lossy(message.payload.as_ref());
                        println!("{}", payload);
                        let state: State = xml::from_str(&payload).unwrap();
                        println!("{:?}", state);

                        let repo = Repository::discover(".").unwrap();
                        let branch = repo.find_branch(&state.task, BranchType::Local);
                        let head = match branch {
                            Ok(branch) => branch.into_reference(),
                            _ => repo.head().unwrap()
                        };
                        let commit = head.peel(ObjectType::Commit).unwrap();
                        let mut index = repo.index().unwrap();

                        let to_remove = index.iter().fold(vec![], |mut acc, entry| {
                            let entry_path = String::from_utf8_lossy(entry.path.as_ref());
                            match state.include.iter().find(|i| i.as_ref() == entry_path) {
                                None => acc.push(entry_path.into_owned()),
                                _ => {}
                            };
                            acc
                        });

                        repo.reset_default(Some(&commit), to_remove.iter()).unwrap();
                        for change in state.clone().include {
                            let path = Path::new(&change);
                            index.add_path(path).unwrap();
                        }
                        index.write().unwrap();

                        if let Some(event) = state.save_update.clone() {
                            let author = repo.signature().unwrap();
                            let mut yaml = String::new();
                            {
                                // Constructing the properties YAML
                                let mut tasks = Hash::new();
                                let mut properties = Hash::new();
                                let mut emitter = YamlEmitter::new(&mut yaml);
                                for property in state.property {
                                    properties.insert(Yaml::String(property.name), Yaml::String(property.value));
                                }
                                tasks.insert(Yaml::String(String::from(head.shorthand().unwrap_or("master"))), Yaml::Hash(properties));
                                emitter.dump(&Yaml::Hash(tasks)).unwrap();
                            }
                            let message = state.message + "\n" + &yaml;

                            index.read(false);
                            let tree_oid = index.write_tree().unwrap();
                            let tree = repo.find_tree(tree_oid).unwrap();
                            repo.commit(Some(&head.name().unwrap_or("HEAD")), &author, &author, &message, &tree, &[&commit.as_commit().unwrap()]);
                            let message = WebMessage::text(payload::generate(None));
                            sender.send_message(&message).unwrap();
                            last_state = None;
                        } else {
                            last_state = Some(state);
                        }
                        let message = WebMessage::text(payload::generate(last_state.clone()));
                        sender.send_message(&message).unwrap();
                    }
                }
            },
            NotifierMessage::FsEvent(event) => {
                let repo = Repository::discover(".").unwrap();
                let message = WebMessage::text(payload::generate(last_state.clone()));
                sender.send_message(&message).unwrap();
            }
        }
    }
}
<commit_msg>Skip checking changes when transitioning between tasks. --- master: {}<commit_after>use std::thread;
use std::thread::JoinHandle;
use std::path::Path;
use std::time::Duration;

use websocket::{WebSocketStream, Server};
use websocket::Message as WebMessage;
use websocket::Sender as WebSender;
use websocket::client::Sender as WebClientSender;
use websocket::Receiver as WebReceiver;
use websocket::message::Type as WebMessageType;
use websocket::server::Connection;
use websocket::header::WebSocketProtocol;

use git2::Repository;
use git2::ObjectType;
use git2::BranchType;

use payload;
use state::State;

extern crate fsevent;
use self::fsevent::Event as FsEvent;
use std::sync::mpsc::channel;
use std::sync::mpsc::Sender;
use std::sync::mpsc::Receiver;

use serde_xml as xml;
use yaml_rust::yaml::Hash;
use yaml_rust::{Yaml, YamlEmitter};

#[derive(Debug)]
enum NotifierMessage<'a> {
    WebMessage(WebMessage<'a>),
    FsEvent(FsEvent)
}

pub fn start() {
    let server = Server::bind("127.0.0.1:2794").unwrap();
    thread::spawn(move || {
        for connection in server {
            thread::spawn(move || connect(connection.unwrap()));
        }
    });
}

fn connect(connection: Connection<WebSocketStream, WebSocketStream>) {
    let request = connection.read_request().unwrap();
    let headers = request.headers.clone();
    request.validate().unwrap();
    let mut response = request.accept();
    println!("Connected");

    if let Some(&WebSocketProtocol(ref protocols)) = headers.get() {
        if protocols.contains(&("superconductor".to_string())) {
            response.headers.set(WebSocketProtocol(vec!["superconductor".to_string()]));
        }
    }

    let mut client = response.send().unwrap();
    let message = WebMessage::text(payload::generate(None));
    client.send_message(&message).unwrap();

    let (tx, rx) = channel::<NotifierMessage>();
    let (mut sender, mut receiver) = client.split();
    let notifier = thread::spawn(move || start_notifier(rx, sender));
    let txc = tx.clone();
    let monitor = thread::spawn(move || start_monitor(txc));
    for message in receiver.incoming_messages() {
        let message: WebMessage = message.unwrap_or(WebMessage::close());
        match message.opcode {
            WebMessageType::Close => {
                tx.send(NotifierMessage::WebMessage(message));
                break;
            },
            _ => tx.send(NotifierMessage::WebMessage(message))
        };
    }
    monitor.join();
    notifier.join();
}

fn start_monitor(tx: Sender<NotifierMessage>) {
    let (ftx, rx) = channel();
    let observer = thread::spawn(move || {
        println!("Monitoring");
        let fsevent = fsevent::FsEvent::new(ftx);
        fsevent.append_path(".");
        fsevent.observe();
    });
    loop {
        let event = rx.recv().unwrap();
        thread::sleep(Duration::from_millis(500));
        let mut events = vec![];
        events.push(event);
        while let Ok(aggregator) = rx.try_recv() {
            events.push(aggregator);
        }
        tx.send(NotifierMessage::FsEvent(events.pop().unwrap()));
    }
    observer.join();
}

fn start_notifier(rx: Receiver<NotifierMessage>, mut sender: WebClientSender<WebSocketStream>) {
    let mut last_state: Option<State> = None;
    loop {
        let value = rx.recv().unwrap();
        match value {
            NotifierMessage::WebMessage(message) => {
                match message.opcode {
                    WebMessageType::Close => {
                        break;
                    },
                    WebMessageType::Ping => {
                        let message = WebMessage::pong(message.payload);
                        sender.send_message(&message).unwrap();
                    },
                    _ => {
                        let payload = String::from_utf8_lossy(message.payload.as_ref());
                        println!("{}", payload);
                        let state: State = xml::from_str(&payload).unwrap();
                        println!("{:?}", state);

                        let repo = Repository::discover(".").unwrap();
                        let branch = repo.find_branch(&state.task, BranchType::Local);
                        let head = match branch {
                            Ok(branch) => branch.into_reference(),
                            _ => repo.head().unwrap()
                        };
                        let commit = head.peel(ObjectType::Commit).unwrap();
                        let mut index = repo.index().unwrap();
                        if let Some(last_state) = last_state {
                            if state.task == last_state.task {
                                let to_remove = index.iter().fold(vec![], |mut acc, entry| {
                                    let entry_path = String::from_utf8_lossy(entry.path.as_ref());
                                    match state.include.iter().find(|i| i.as_ref() == entry_path) {
                                        None => acc.push(entry_path.into_owned()),
                                        _ => {}
                                    };
                                    acc
                                });

                                repo.reset_default(Some(&commit), to_remove.iter()).unwrap();
                                for change in state.clone().include {
                                    let path = Path::new(&change);
                                    index.add_path(path).unwrap();
                                }
                                index.write().unwrap();
                            }
                        }

                        if let Some(event) = state.save_update.clone() {
                            let author = repo.signature().unwrap();
                            let mut yaml = String::new();
                            {
                                // Constructing the properties YAML
                                let mut tasks = Hash::new();
                                let mut properties = Hash::new();
                                let mut emitter = YamlEmitter::new(&mut yaml);
                                for property in state.property {
                                    properties.insert(Yaml::String(property.name), Yaml::String(property.value));
                                }
                                tasks.insert(Yaml::String(String::from(head.shorthand().unwrap_or("master"))), Yaml::Hash(properties));
                                emitter.dump(&Yaml::Hash(tasks)).unwrap();
                            }
                            let message = state.message + "\n" + &yaml;

                            index.read(false);
                            let tree_oid = index.write_tree().unwrap();
                            let tree = repo.find_tree(tree_oid).unwrap();
                            repo.commit(Some(&head.name().unwrap_or("HEAD")), &author, &author, &message, &tree, &[&commit.as_commit().unwrap()]);
                            let message = WebMessage::text(payload::generate(None));
                            sender.send_message(&message).unwrap();
                            last_state = None;
                        } else {
                            last_state = Some(state);
                        }
                        let message = WebMessage::text(payload::generate(last_state.clone()));
                        sender.send_message(&message).unwrap();
                    }
                }
            },
            NotifierMessage::FsEvent(event) => {
                let repo = Repository::discover(".").unwrap();
                let message = WebMessage::text(payload::generate(last_state.clone()));
                sender.send_message(&message).unwrap();
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::rc::Rc;
use std::cell::Cell;
use std::sync::mpsc;
use std::fmt;
use types::{MaybeOwned, Storage, SerialId};
use stream::Stream;

use self::SigValue::*;

/// Represents a discrete value that changes over time.
///
/// Signals are usually constructed by stream operations and can be read using the `sample` or
/// `sample_with` methods.
#[derive(Debug)]
pub struct Signal<T>(SigValue<T>);

enum SigValue<T>
{
    /// A signal with constant value.
    Constant(Rc<T>),
    /// A signal that generates it's values from a function.
    ///
    /// This is produced by `Signal::from_fn`
    Dynamic(Rc<Fn() -> T>, Cell<SerialId>),
    /// A signal that contains shared data.
    ///
    /// This is produced by stream methods that create a signal.
    Shared(Rc<Fn()>, Rc<Storage<T>>),
    /// A signal that contains a signal, and allows sampling the inner signal directly.
    ///
    /// This is produced by `Signal::switch`
    Nested(Rc<Fn() -> Signal<T>>),
}

impl<T> Signal<T>
{
    /// Creates a signal with constant value.
    ///
    /// The value is assumed to be constant, so changing it while it's stored on the
    /// signal is a logic error and will cause unexpected results.
    pub fn constant<V: Into<Rc<T>>>(val: V) -> Self
    {
        Signal(Constant(val.into()))
    }

    /// Creates a signal that samples it's values from an external source.
    ///
    /// This samples some value from the mutable real world and stores it discretely,
    /// so it's assumed to be always changing.
    pub fn from_fn<F>(f: F) -> Self
        where F: Fn() -> T + 'static
    {
        Signal(Dynamic(Rc::new(f), Default::default()))
    }

    /// Gets the serial id for this signal.
    ///
    /// The `SerialId` is a value that increases every time the signal value has changed.
    /// This way the observer can detect changes and avoid needless re-computation.
    pub fn get_serial(&self) -> SerialId
    {
        match self.0 {
            Constant(_) => SerialId::once(),
            Dynamic(_, ref ser) => ser.get(),
            Shared(_, ref st) => st.get_serial(),
            Nested(ref f) => f().get_serial(),
        }
    }

    /// Sample by reference.
    ///
    /// This is meant to be the most efficient way when cloning is undesirable,
    /// but it requires a callback to prevent outliving internal borrows.
    pub fn sample_with<F, R>(&self, cb: F) -> R
        where F: FnOnce(MaybeOwned<T>) -> R
    {
        match self.0
        {
            Constant(ref val) => cb(MaybeOwned::Borrowed(val)),
            Dynamic(ref f, ref ser) => { SerialId::inc_cell(ser); cb(MaybeOwned::Owned(f())) },
            Shared(ref f, ref st) => { f(); st.borrow(|val| cb(MaybeOwned::Borrowed(val))) },
            Nested(ref f) => f().sample_with(cb),
        }
    }
}

impl<T: Clone> Signal<T>
{
    /// Sample by value.
    ///
    /// This will clone the content of the signal.
    pub fn sample(&self) -> T
    {
        match self.0
        {
            Constant(ref val) => (**val).clone(),
            Dynamic(ref f, ref ser) => { SerialId::inc_cell(ser); f() },
            Shared(ref f, ref st) => { f(); st.get() },
            Nested(ref f) => f().sample(),
        }
    }
}

impl<T: 'static> Signal<T>
{
    /// Maps a signal with the provided function.
    ///
    /// The closure is called only when the parent signal changes.
    pub fn map<F, R>(&self, f: F) -> Signal<R>
        where F: Fn(MaybeOwned<T>) -> R + 'static,
        R: 'static
    {
        match self.0 {
            // constant signal: apply f once to produce another constant signal
            Constant(ref val) => {
                Signal::constant(f(MaybeOwned::Borrowed(val)))
            }
            // shared signal: apply f only when the parent signal has changed
            Shared(_, _) => {
                let this = self.clone();
                let storage = Rc::new(Storage::empty());
                let st_cloned = storage.clone();
                Signal(Shared(Rc::new(move || {
                    let parent_ser = this.get_serial();
                    if parent_ser > storage.get_serial()
                    {
                        // inherit the SerialId from the parent signal so we can compare it later
                        storage.set_with_serial(this.sample_with(&f), parent_ser)
                    }
                }), st_cloned))
            }
            // dynamic/nested signal: apply f unconditionally
            Dynamic(_, _) | Nested(_) => {
                let this = self.clone();
                Signal::from_fn(move || this.sample_with(&f))
            }
        }
    }

    /// Samples the value of this signal every time the trigger stream fires.
    pub fn snapshot<S, F, R>(&self, trigger: &Stream<S>, f: F) -> Stream<R>
        where F: Fn(MaybeOwned<T>, MaybeOwned<S>) -> R + 'static,
        S: 'static, R: 'static
    {
        let this = self.clone();
        trigger.map(move |b| this.sample_with(|a| f(a, b)))
    }

    /// Creates a signal from a shared value.
    pub(crate) fn from_storage<A: 'static>(storage: Rc<Storage<T>>, keepalive: A) -> Self
    {
        Signal(Shared(Rc::new(move || {
            let _keepalive = &keepalive;
        }), storage))
    }

    /// Stores the last value sent to a channel.
    ///
    /// When sampled, the resulting signal consumes all the current values on the channel
    /// (using non-blocking operations) and returns the last value seen.
    pub fn from_channel(initial: T, rx: mpsc::Receiver<T>) -> Self
    {
        let storage = Rc::new(Storage::new(initial));
        let st_cloned = storage.clone();
        Signal(Shared(Rc::new(move || {
            let last = rx.try_iter().last();
            if let Some(val) = last { storage.set(val); }
        }), st_cloned))
    }

    /// Creates a signal that folds the values from a channel.
    ///
    /// When sampled, the resulting signal consumes all the current values on the channel
    /// (using non-blocking operations) and folds them using the current signal value as the
    /// initial accumulator state.
    pub fn fold_channel<V, F>(initial: T, rx: mpsc::Receiver<V>, f: F) -> Self
        where F: Fn(T, V) -> T + 'static,
        V: 'static
    {
        let storage = Rc::new(Storage::new(initial));
        let st_cloned = storage.clone();
        Signal(Shared(Rc::new(move || {
            let acc = storage.take();
            let current = rx.try_iter().fold(acc, &f);
            storage.set(current);
        }), st_cloned))
    }
}

impl<T: 'static> Signal<Signal<T>>
{
    /// Creates a new signal that samples the inner value of a nested signal.
    pub fn switch(&self) -> Signal<T>
    {
        let this = self.clone();
        Signal(Nested(Rc::new(move || this.sample())))
    }
}

impl<T: Default> Default for Signal<T>
{
    /// Creates a constant signal with T's default value.
    #[inline]
    fn default() -> Self
    {
        Signal::constant(T::default())
    }
}

impl<T> From<T> for Signal<T>
{
    #[inline]
    fn from(val: T) -> Self
    {
        Signal::constant(val)
    }
}

impl<T> From<Rc<T>> for Signal<T>
{
    #[inline]
    fn from(val: Rc<T>) -> Self
    {
        Signal(Constant(val))
    }
}

// the derive impl adds a `T: Clone` we don't want
impl<T> Clone for Signal<T>
{
    fn clone(&self) -> Self
    {
        match self.0
        {
            Constant(ref val) => Signal(Constant(val.clone())),
            Dynamic(ref rf, ref ser) => Signal(Dynamic(rf.clone(), ser.clone())),
            Shared(ref rf, ref st) => Signal(Shared(rf.clone(), st.clone())),
            Nested(ref rf) => Signal(Nested(rf.clone())),
        }
    }
}

impl<T: fmt::Debug> fmt::Debug for SigValue<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        match *self
        {
            Constant(ref val) => write!(f, "Constant({:?})", val),
            Dynamic(ref rf, ref ser) => write!(f, "Dynamic(Fn@{:p}, {:?})", rf, ser),
            Shared(ref rf, ref st) => write!(f, "Shared(Fn@{:p}, {:?})", rf, st),
            Nested(ref rf) => write!(f, "Nested(Fn@{:p})", rf),
        }
    }
}

impl<T: fmt::Display> fmt::Display for Signal<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        self.sample_with(|val| fmt::Display::fmt(&*val, f))
    }
}

#[cfg(test)]
mod tests
{
    use super::*;
    use std::rc::Rc;
    use std::cell::Cell;
    use std::time::Instant;

    #[test]
    fn signal_basic()
    {
        let signal = Signal::constant(42);
        let double = signal.map(|a| *a * 2);
        let plusone = double.map(|a| *a + 1);
        assert_eq!(signal.sample(), 42);
        assert_eq!(double.sample(), 84);
        assert_eq!(plusone.sample(), 85);
        signal.sample_with(|val| assert_eq!(*val, 42));
    }

    #[test]
    fn signal_shared()
    {
        let st = Rc::new(Storage::new(1));
        let signal = Signal::from_storage(st.clone(), ());
        let double = signal.map(|a| *a * 2);

        assert_eq!(signal.sample(), 1);
        assert_eq!(double.sample(), 2);
        st.set(42);
        assert_eq!(signal.sample(), 42);
        assert_eq!(double.sample(), 84);
    }

    #[test]
    fn signal_dynamic()
    {
        let t = Instant::now();
        let signal = Signal::from_fn(move || t);
        assert_eq!(signal.sample(), t);
        signal.sample_with(|val| assert_eq!(*val, t));

        let n = Rc::new(Cell::new(1));
        let cloned = n.clone();
        let signal = Signal::from_fn(move || cloned.get());
        let double = signal.map(|a| *a * 2);
        let plusone = double.map(|a| *a + 1);
        assert_eq!(signal.sample(), 1);
        assert_eq!(double.sample(), 2);
        assert_eq!(plusone.sample(), 3);
        n.set(13);
        assert_eq!(signal.sample(), 13);
        assert_eq!(double.sample(), 26);
        assert_eq!(plusone.sample(), 27);
    }
}
<commit_msg>simplify code<commit_after>use std::rc::Rc;
use std::cell::Cell;
use std::sync::mpsc;
use std::fmt;
use types::{MaybeOwned, Storage, SerialId};
use stream::Stream;

use self::SigValue::*;

/// Represents a discrete value that changes over time.
///
/// Signals are usually constructed by stream operations and can be read using the `sample` or
/// `sample_with` methods.
#[derive(Debug)]
pub struct Signal<T>(SigValue<T>);

enum SigValue<T>
{
    /// A signal with constant value.
    Constant(Rc<T>),
    /// A signal that generates it's values from a function.
    ///
    /// This is produced by `Signal::from_fn`
    Dynamic(Rc<Fn() -> T>, Cell<SerialId>),
    /// A signal that contains shared data.
    ///
    /// This is produced by stream methods that create a signal.
    Shared(Rc<Fn()>, Rc<Storage<T>>),
    /// A signal that contains a signal, and allows sampling the inner signal directly.
    ///
    /// This is produced by `Signal::switch`
    Nested(Rc<Fn() -> Signal<T>>),
}

impl<T> Signal<T>
{
    /// Creates a signal with constant value.
    ///
    /// The value is assumed to be constant, so changing it while it's stored on the
    /// signal is a logic error and will cause unexpected results.
    pub fn constant<V: Into<Rc<T>>>(val: V) -> Self
    {
        Signal(Constant(val.into()))
    }

    /// Creates a signal that samples it's values from an external source.
    ///
    /// This samples some value from the mutable real world and stores it discretely,
    /// so it's assumed to be always changing.
    pub fn from_fn<F>(f: F) -> Self
        where F: Fn() -> T + 'static
    {
        Signal(Dynamic(Rc::new(f), Default::default()))
    }

    /// Gets the serial id for this signal.
    ///
    /// The `SerialId` is a value that increases every time the signal value has changed.
    /// This way the observer can detect changes and avoid needless re-computation.
    pub fn get_serial(&self) -> SerialId
    {
        match self.0 {
            Constant(_) => SerialId::once(),
            Dynamic(_, ref ser) => ser.get(),
            Shared(_, ref st) => st.get_serial(),
            Nested(ref f) => f().get_serial(),
        }
    }

    /// Sample by reference.
    ///
    /// This is meant to be the most efficient way when cloning is undesirable,
    /// but it requires a callback to prevent outliving internal borrows.
    pub fn sample_with<F, R>(&self, cb: F) -> R
        where F: FnOnce(MaybeOwned<T>) -> R
    {
        match self.0
        {
            Constant(ref val) => cb(MaybeOwned::Borrowed(val)),
            Dynamic(ref f, ref ser) => { SerialId::inc_cell(ser); cb(MaybeOwned::Owned(f())) },
            Shared(ref f, ref st) => { f(); st.borrow(|val| cb(MaybeOwned::Borrowed(val))) },
            Nested(ref f) => f().sample_with(cb),
        }
    }
}

impl<T: Clone> Signal<T>
{
    /// Sample by value.
    ///
    /// This will clone the content of the signal.
    pub fn sample(&self) -> T
    {
        match self.0
        {
            Constant(ref val) => (**val).clone(),
            Dynamic(ref f, ref ser) => { SerialId::inc_cell(ser); f() },
            Shared(ref f, ref st) => { f(); st.get() },
            Nested(ref f) => f().sample(),
        }
    }
}

impl<T: 'static> Signal<T>
{
    /// Maps a signal with the provided function.
    ///
    /// The closure is called only when the parent signal changes.
    pub fn map<F, R>(&self, f: F) -> Signal<R>
        where F: Fn(MaybeOwned<T>) -> R + 'static,
        R: 'static
    {
        match self.0 {
            // constant signal: apply f once to produce another constant signal
            Constant(ref val) => {
                Signal::constant(f(MaybeOwned::Borrowed(val)))
            }
            // shared signal: apply f only when the parent signal has changed
            Shared(_, _) => {
                let this = self.clone();
                let storage = Rc::new(Storage::empty());
                let st_cloned = storage.clone();
                Signal(Shared(Rc::new(move || {
                    let parent_ser = this.get_serial();
                    if parent_ser > storage.get_serial()
                    {
                        // inherit the SerialId from the parent signal so we can compare it later
                        storage.set_with_serial(this.sample_with(&f), parent_ser)
                    }
                }), st_cloned))
            }
            // dynamic/nested signal: apply f unconditionally
            Dynamic(_, _) | Nested(_) => {
                let this = self.clone();
                Signal::from_fn(move || this.sample_with(&f))
            }
        }
    }

    /// Samples the value of this signal every time the trigger stream fires.
    pub fn snapshot<S, F, R>(&self, trigger: &Stream<S>, f: F) -> Stream<R>
        where F: Fn(MaybeOwned<T>, MaybeOwned<S>) -> R + 'static,
        S: 'static, R: 'static
    {
        let this = self.clone();
        trigger.map(move |b| this.sample_with(|a| f(a, b)))
    }

    /// Creates a signal from a shared value.
    pub(crate) fn from_storage<A: 'static>(storage: Rc<Storage<T>>, keepalive: A) -> Self
    {
        Signal(Shared(Rc::new(move || {
            let _keepalive = &keepalive;
        }), storage))
    }

    /// Stores the last value sent to a channel.
    ///
    /// When sampled, the resulting signal consumes all the current values on the channel
    /// (using non-blocking operations) and returns the last value seen.
    pub fn from_channel(initial: T, rx: mpsc::Receiver<T>) -> Self
    {
        let storage = Rc::new(Storage::new(initial));
        let st_cloned = storage.clone();
        Signal(Shared(Rc::new(move || {
            let last = rx.try_iter().last();
            if let Some(val) = last { storage.set(val); }
        }), st_cloned))
    }

    /// Creates a signal that folds the values from a channel.
    ///
    /// When sampled, the resulting signal consumes all the current values on the channel
    /// (using non-blocking operations) and folds them using the current signal value as the
    /// initial accumulator state.
    pub fn fold_channel<V, F>(initial: T, rx: mpsc::Receiver<V>, f: F) -> Self
        where F: Fn(T, V) -> T + 'static,
        V: 'static
    {
        let storage = Rc::new(Storage::new(initial));
        let st_cloned = storage.clone();
        Signal(Shared(Rc::new(move || {
            let acc = storage.take();
            let current = rx.try_iter().fold(acc, &f);
            storage.set(current);
        }), st_cloned))
    }
}

impl<T: 'static> Signal<Signal<T>>
{
    /// Creates a new signal that samples the inner value of a nested signal.
    pub fn switch(&self) -> Signal<T>
    {
        let this = self.clone();
        Signal(Nested(Rc::new(move || this.sample())))
    }
}

impl<T: Default> Default for Signal<T>
{
    /// Creates a constant signal with T's default value.
    #[inline]
    fn default() -> Self
    {
        Signal::constant(T::default())
    }
}

impl<T> From<T> for Signal<T>
{
    #[inline]
    fn from(val: T) -> Self
    {
        Signal::constant(val)
    }
}

impl<T> From<Rc<T>> for Signal<T>
{
    #[inline]
    fn from(val: Rc<T>) -> Self
    {
        Signal(Constant(val))
    }
}

// the derive impl adds a `T: Clone` we don't want
impl<T> Clone for Signal<T>
{
    fn clone(&self) -> Self
    {
        Signal(match self.0
        {
            Constant(ref val) => Constant(val.clone()),
            Dynamic(ref rf, ref ser) => Dynamic(rf.clone(), ser.clone()),
            Shared(ref rf, ref st) => Shared(rf.clone(), st.clone()),
            Nested(ref rf) => Nested(rf.clone()),
        })
    }
}

impl<T: fmt::Debug> fmt::Debug for SigValue<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        match *self
        {
            Constant(ref val) => write!(f, "Constant({:?})", val),
            Dynamic(ref rf, ref ser) => write!(f, "Dynamic(Fn@{:p}, {:?})", rf, ser),
            Shared(ref rf, ref st) => write!(f, "Shared(Fn@{:p}, {:?})", rf, st),
            Nested(ref rf) => write!(f, "Nested(Fn@{:p})", rf),
        }
    }
}

impl<T: fmt::Display> fmt::Display for Signal<T>
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result
    {
        self.sample_with(|val| fmt::Display::fmt(&*val, f))
    }
}

#[cfg(test)]
mod tests
{
    use super::*;
    use std::rc::Rc;
    use std::cell::Cell;
    use std::time::Instant;

    #[test]
    fn signal_basic()
    {
        let signal = Signal::constant(42);
        let double = signal.map(|a| *a * 2);
        let plusone = double.map(|a| *a + 1);
        assert_eq!(signal.sample(), 42);
        assert_eq!(double.sample(), 84);
        assert_eq!(plusone.sample(), 85);
        signal.sample_with(|val| assert_eq!(*val, 42));
    }

    #[test]
    fn signal_shared()
    {
        let st = Rc::new(Storage::new(1));
        let signal = Signal::from_storage(st.clone(), ());
        let double = signal.map(|a| *a * 2);

        assert_eq!(signal.sample(), 1);
        assert_eq!(double.sample(), 2);
        st.set(42);
        assert_eq!(signal.sample(), 42);
        assert_eq!(double.sample(), 84);
    }

    #[test]
    fn signal_dynamic()
    {
        let t = Instant::now();
        let signal = Signal::from_fn(move || t);
        assert_eq!(signal.sample(), t);
        signal.sample_with(|val| assert_eq!(*val, t));

        let n = Rc::new(Cell::new(1));
        let cloned = n.clone();
        let signal = Signal::from_fn(move || cloned.get());
        let double = signal.map(|a| *a * 2);
        let plusone = double.map(|a| *a + 1);
        assert_eq!(signal.sample(), 1);
        assert_eq!(double.sample(), 2);
        assert_eq!(plusone.sample(), 3);
        n.set(13);
        assert_eq!(signal.sample(), 13);
        assert_eq!(double.sample(), 26);
        assert_eq!(plusone.sample(), 27);
    }
}
<|endoftext|>