<commit_before>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[doc(keyword = "as")]
//
/// The type coercion keyword.
///
/// `as` is most commonly used to turn primitive types into other primitive types, but it has other
/// uses that include turning pointers into addresses, addresses into pointers, and pointers into
/// other pointers.
///
/// ```rust
/// let thing1: u8 = 89.0 as u8;
/// assert_eq!('B' as u32, 66);
/// assert_eq!(thing1 as char, 'Y');
/// let thing2: f32 = thing1 as f32 + 10.5;
/// assert_eq!(true as u8 + thing2 as u8, 100);
/// ```
///
/// In general, any coercion that can be performed via writing out type hints can also be done
/// using `as`, so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (Note:
/// `let x = 123u32` would be best in that situation). The same is not true in the other direction,
/// however, explicitly using `as` allows a few more coercions that aren't allowed implicitly, such
/// as changing the type of a raw pointer or turning closures into raw pointers.
///
/// For more information on what `as` is capable of, see the [Reference]
///
/// [Reference]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions
mod as_keyword { }

#[doc(keyword = "const")]
//
/// The keyword for defining constants.
///
/// Sometimes a certain value is used many times throughout a program, and it can become
/// inconvenient to copy it over and over. What's more, it's not always possible or desirable to
/// make it a variable that gets carried around to each function that needs it. In these cases, the
/// `const` keyword provides a convenient alternative to code duplication.
///
/// ```rust
/// const THING: u32 = 0xABAD1DEA;
///
/// let foo = 123 + THING;
/// ```
///
/// Constants must be explicitly typed, unlike with `let` you can't ignore its type and let the
/// compiler figure it out. Any constant value can be defined in a const, which in practice happens
/// to be most things that would be reasonable to have a constant. For example, you can't have a
/// File as a `const`.
///
/// The only lifetime allowed in a constant is 'static, which is the lifetime that encompasses all
/// others in a Rust program. For example, if you wanted to define a constant string, it would look
/// like this:
///
/// ```rust
/// const WORDS: &'static str = "hello rust!";
/// ```
///
/// Thanks to static lifetime elision, you usually don't have to explicitly use 'static:
///
/// ```rust
/// const WORDS: &str = "hello convenience!";
/// ```
///
/// `const` items looks remarkably similar to [`static`] items, which introduces some confusion as
/// to which one should be used at which times. To put it simply, constants are inlined wherever
/// they're used, making using them identical to simply replacing the name of the const with its
/// value. Static variables on the other hand point to a single location in memory, which all
/// accesses share. This means that, unlike with constants, they can't have destructors, but it
/// also means that (via unsafe code) they can be mutable, which is useful for the rare situations
/// in which you can't avoid using global state.
///
/// Constants, as with statics, should always be in SCREAMING_SNAKE_CASE.
///
/// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const
/// T` and `*mut T`. More about that can be read at the [pointer] primitive part of the Rust docs.
///
/// For more detail on `const`, see the [Rust Book] or the [Reference]
///
/// [`static`]: keyword.static.html
/// [pointer]: primitive.pointer.html
/// [Rust Book]: https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
/// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html
mod const_keyword { }

#[doc(keyword = "crate")]
//
/// The `crate` keyword.
///
/// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are
/// used to specify a dependency on a crate external to the one it's declared in. Crates are the
/// fundamental compilation unit of Rust code, and can be seen as libraries or projects. More can
/// be read about crates in the [Reference].
///
/// ```rust ignore
/// extern crate rand;
/// extern crate my_crate as thing;
/// extern crate std; // implicitly added to the root of every Rust project
/// ```
///
/// The `as` keyword can be used to change what the crate is referred to as in your project. If a
/// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores.
///
/// `crate` is also used as in conjunction with [`pub`] to signify that the item it's attached to
/// is public only to other members of the same crate it's in.
///
/// ```rust
/// # #[allow(unused_imports)]
/// pub(crate) use std::io::Error as IoError;
/// pub(crate) enum CoolMarkerType { }
/// pub struct PublicThing {
///     pub(crate) semi_secret_thing: bool,
/// }
/// ```
///
/// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html
/// [`pub`]: keyword.pub.html
mod crate_keyword { }

#[doc(keyword = "enum")]
//
/// For defining enumerations.
///
/// Enums in Rust are similar to those of other compiled languages like C, but have important
/// differences that make them considerably more powerful. What Rust calls enums are more commonly
/// known as Algebraic Data Types if you're coming from a functional programming background, but
/// the important part is that data can go with the enum variants.
///
/// ```rust
/// # struct Coord;
/// enum SimpleEnum {
///     FirstVariant,
///     SecondVariant,
///     ThirdVariant,
/// }
///
/// enum Location {
///     Unknown,
///     Anonymous,
///     Known(Coord),
/// }
///
/// enum ComplexEnum {
///     Nothing,
///     Something(u32),
///     LotsOfThings {
///         usual_struct_stuff: bool,
///         blah: String,
///     }
/// }
///
/// enum EmptyEnum { }
/// ```
///
/// The first enum shown is the usual kind of enum you'd find in a C-style language. The second
/// shows off a hypothetical example of something storing location data, with Coord being any other
/// type that's needed, for example a struct. The third example demonstrates the kind of variant a
/// variant can store, ranging from nothing, to a tuple, to an anonymous struct.
///
/// Instantiating enum variants involves explicitly using the enum's name as its namespace,
/// followed by one of its variants. `SimpleEnum::SecondVariant` would be an example from above.
/// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data
/// is added as the type describes, for example `Option::Some(123)`. The same follows with
/// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff:
/// true, blah: "hello!".to_string(), }`. Empty Enums are similar to () in that they cannot be
/// instantiated at all, and are used mainly to mess with the type system in interesting ways.
///
/// For more information, take a look at the [Rust Book] or the [Reference]
///
/// [`Option`]: option/enum.Option.html
/// [Rust Book]: https://doc.rust-lang.org/book/second-edition/ch06-01-defining-an-enum.html
/// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html
mod enum_keyword { }

#[doc(keyword = "fn")]
//
/// The `fn` keyword.
///
/// The `fn` keyword is used to declare a function.
///
/// Example:
///
/// ```rust
/// fn some_function() {
///     // code goes in here
/// }
/// ```
///
/// For more information about functions, take a look at the [Rust Book][book].
///
/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html
mod fn_keyword { }

#[doc(keyword = "let")]
//
/// The `let` keyword.
///
/// The `let` keyword is used to declare a variable.
///
/// Example:
///
/// ```rust
/// # #![allow(unused_assignments)]
/// let x = 3; // We create a variable named `x` with the value `3`.
/// ```
///
/// By default, all variables are **not** mutable. If you want a mutable variable,
/// you'll have to use the `mut` keyword.
///
/// Example:
///
/// ```rust
/// # #![allow(unused_assignments)]
/// let mut x = 3; // We create a mutable variable named `x` with the value `3`.
///
/// x += 4; // `x` is now equal to `7`.
/// ```
///
/// For more information about the `let` keyword, take a look at the [Rust Book][book].
///
/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-01-variables-and-mutability.html
mod let_keyword { }

#[doc(keyword = "struct")]
//
/// The keyword used to define structs.
///
/// Structs in Rust come in three flavours: Regular structs, tuple structs,
/// and empty structs.
///
/// ```rust
/// struct Regular {
///     field1: f32,
///     field2: String,
///     pub field3: bool
/// }
///
/// struct Tuple(u32, String);
///
/// struct Empty;
/// ```
///
/// Regular structs are the most commonly used. Each field defined within them has a name and a
/// type, and once defined can be accessed using `example_struct.field` syntax. The fields of a
/// struct share its mutability, so `foo.bar = 2;` would only be valid if `foo` was mutable. Adding
/// `pub` to a field makes it visible to code in other modules, as well as allowing it to be
/// directly accessed and modified.
///
/// Tuple structs are similar to regular structs, but its fields have no names. They are used like
/// tuples, with deconstruction possible via `let TupleStruct(x, y) = foo;` syntax.  For accessing
/// individual variables, the same syntax is used as with regular tuples, namely `foo.0`, `foo.1`,
/// etc, starting at zero.
///
/// Empty structs, or unit-like structs, are most commonly used as markers, for example
/// [`PhantomData`]. Empty structs have a size of zero bytes, but unlike empty enums they can be
/// instantiated, making them similar to the unit type `()`. Unit-like structs are useful when you
/// need to implement a trait on something, but don't need to store any data inside it.
///
/// # Instantiation
///
/// Structs can be instantiated in a manner of different ways, each of which can be mixed and
/// matched as needed. The most common way to make a new struct is via a constructor method such as
/// `new()`, but when that isn't available (or you're writing the constructor itself), struct
/// literal syntax is used:
///
/// ```rust
/// # struct Foo { field1: f32, field2: String, etc: bool }
/// let example = Foo {
///     field1: 42.0,
///     field2: "blah".to_string(),
///     etc: true,
/// };
/// ```
///
/// It's only possible to directly instantiate a struct using struct literal syntax when all of its
/// fields are visible to you.
///
/// There are a handful of shortcuts provided to make writing constructors more convenient, most
/// common of which is the Field Init shorthand. When there is a variable and a field of the same
/// name, the assignment can be simplified from `field: field` into simply `field`. The following
/// example of a hypothetical constructor demonstrates this:
///
/// ```rust
/// struct User {
///     name: String,
///     admin: bool,
/// }
///
/// impl User {
///     pub fn new(name: String) -> Self {
///         Self {
///             name,
///             admin: false,
///         }
///     }
/// }
/// ```
///
/// Another shortcut for struct instantiation is available, used when you need to make a new
/// struct that has the same values as most of a previous struct of the same type, called struct
/// update syntax:
///
/// ```rust
/// # struct Foo { field1: String, field2: () }
/// # let thing = Foo { field1: "".to_string(), field2: () };
/// let updated_thing = Foo {
///     field1: "a new value".to_string(),
///     ..thing
/// };
/// ```
///
/// Tuple structs are instantiated in the same way as tuples themselves, except with the struct's
/// name as a prefix: `Foo(123, false, 0.1)`.
///
/// Empty structs are instantiated with just their name, and don't need anything else. `let thing =
/// EmptyStruct;`
///
/// # Style conventions
///
/// Structs are always written in CamelCase, with few exceptions. While the trailing comma on a
/// struct's list of fields can be omitted, it's usually kept for convenience in adding and
/// removing fields down the line.
///
/// For more information on structs, take a look at the [Rust Book][book] or the
/// [Reference][reference].
///
/// [`PhantomData`]: marker/struct.PhantomData.html
/// [book]: https://doc.rust-lang.org/book/second-edition/ch05-01-defining-structs.html
/// [reference]: https://doc.rust-lang.org/reference/items/structs.html
mod struct_keyword { }
<commit_msg>Add docs on `extern` keyword<commit_after>// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

#[doc(keyword = "as")]
//
/// The type coercion keyword.
///
/// `as` is most commonly used to turn primitive types into other primitive types, but it has other
/// uses that include turning pointers into addresses, addresses into pointers, and pointers into
/// other pointers.
///
/// ```rust
/// let thing1: u8 = 89.0 as u8;
/// assert_eq!('B' as u32, 66);
/// assert_eq!(thing1 as char, 'Y');
/// let thing2: f32 = thing1 as f32 + 10.5;
/// assert_eq!(true as u8 + thing2 as u8, 100);
/// ```
///
/// In general, any coercion that can be performed via writing out type hints can also be done
/// using `as`, so instead of writing `let x: u32 = 123`, you can write `let x = 123 as u32` (Note:
/// `let x = 123u32` would be best in that situation). The same is not true in the other direction,
/// however, explicitly using `as` allows a few more coercions that aren't allowed implicitly, such
/// as changing the type of a raw pointer or turning closures into raw pointers.
///
/// For more information on what `as` is capable of, see the [Reference]
///
/// [Reference]: https://doc.rust-lang.org/reference/expressions/operator-expr.html#type-cast-expressions
mod as_keyword { }

#[doc(keyword = "const")]
//
/// The keyword for defining constants.
///
/// Sometimes a certain value is used many times throughout a program, and it can become
/// inconvenient to copy it over and over. What's more, it's not always possible or desirable to
/// make it a variable that gets carried around to each function that needs it. In these cases, the
/// `const` keyword provides a convenient alternative to code duplication.
///
/// ```rust
/// const THING: u32 = 0xABAD1DEA;
///
/// let foo = 123 + THING;
/// ```
///
/// Constants must be explicitly typed, unlike with `let` you can't ignore its type and let the
/// compiler figure it out. Any constant value can be defined in a const, which in practice happens
/// to be most things that would be reasonable to have a constant. For example, you can't have a
/// File as a `const`.
///
/// The only lifetime allowed in a constant is 'static, which is the lifetime that encompasses all
/// others in a Rust program. For example, if you wanted to define a constant string, it would look
/// like this:
///
/// ```rust
/// const WORDS: &'static str = "hello rust!";
/// ```
///
/// Thanks to static lifetime elision, you usually don't have to explicitly use 'static:
///
/// ```rust
/// const WORDS: &str = "hello convenience!";
/// ```
///
/// `const` items looks remarkably similar to [`static`] items, which introduces some confusion as
/// to which one should be used at which times. To put it simply, constants are inlined wherever
/// they're used, making using them identical to simply replacing the name of the const with its
/// value. Static variables on the other hand point to a single location in memory, which all
/// accesses share. This means that, unlike with constants, they can't have destructors, but it
/// also means that (via unsafe code) they can be mutable, which is useful for the rare situations
/// in which you can't avoid using global state.
///
/// Constants, as with statics, should always be in SCREAMING_SNAKE_CASE.
///
/// The `const` keyword is also used in raw pointers in combination with `mut`, as seen in `*const
/// T` and `*mut T`. More about that can be read at the [pointer] primitive part of the Rust docs.
///
/// For more detail on `const`, see the [Rust Book] or the [Reference]
///
/// [`static`]: keyword.static.html
/// [pointer]: primitive.pointer.html
/// [Rust Book]: https://doc.rust-lang.org/stable/book/2018-edition/ch03-01-variables-and-mutability.html#differences-between-variables-and-constants
/// [Reference]: https://doc.rust-lang.org/reference/items/constant-items.html
mod const_keyword { }

#[doc(keyword = "crate")]
//
/// The `crate` keyword.
///
/// The primary use of the `crate` keyword is as a part of `extern crate` declarations, which are
/// used to specify a dependency on a crate external to the one it's declared in. Crates are the
/// fundamental compilation unit of Rust code, and can be seen as libraries or projects. More can
/// be read about crates in the [Reference].
///
/// ```rust ignore
/// extern crate rand;
/// extern crate my_crate as thing;
/// extern crate std; // implicitly added to the root of every Rust project
/// ```
///
/// The `as` keyword can be used to change what the crate is referred to as in your project. If a
/// crate name includes a dash, it is implicitly imported with the dashes replaced by underscores.
///
/// `crate` is also used as in conjunction with [`pub`] to signify that the item it's attached to
/// is public only to other members of the same crate it's in.
///
/// ```rust
/// # #[allow(unused_imports)]
/// pub(crate) use std::io::Error as IoError;
/// pub(crate) enum CoolMarkerType { }
/// pub struct PublicThing {
///     pub(crate) semi_secret_thing: bool,
/// }
/// ```
///
/// [Reference]: https://doc.rust-lang.org/reference/items/extern-crates.html
/// [`pub`]: keyword.pub.html
mod crate_keyword { }

#[doc(keyword = "enum")]
//
/// For defining enumerations.
///
/// Enums in Rust are similar to those of other compiled languages like C, but have important
/// differences that make them considerably more powerful. What Rust calls enums are more commonly
/// known as Algebraic Data Types if you're coming from a functional programming background, but
/// the important part is that data can go with the enum variants.
///
/// ```rust
/// # struct Coord;
/// enum SimpleEnum {
///     FirstVariant,
///     SecondVariant,
///     ThirdVariant,
/// }
///
/// enum Location {
///     Unknown,
///     Anonymous,
///     Known(Coord),
/// }
///
/// enum ComplexEnum {
///     Nothing,
///     Something(u32),
///     LotsOfThings {
///         usual_struct_stuff: bool,
///         blah: String,
///     }
/// }
///
/// enum EmptyEnum { }
/// ```
///
/// The first enum shown is the usual kind of enum you'd find in a C-style language. The second
/// shows off a hypothetical example of something storing location data, with Coord being any other
/// type that's needed, for example a struct. The third example demonstrates the kind of variant a
/// variant can store, ranging from nothing, to a tuple, to an anonymous struct.
///
/// Instantiating enum variants involves explicitly using the enum's name as its namespace,
/// followed by one of its variants. `SimpleEnum::SecondVariant` would be an example from above.
/// When data follows along with a variant, such as with rust's built-in [`Option`] type, the data
/// is added as the type describes, for example `Option::Some(123)`. The same follows with
/// struct-like variants, with things looking like `ComplexEnum::LotsOfThings { usual_struct_stuff:
/// true, blah: "hello!".to_string(), }`. Empty Enums are similar to () in that they cannot be
/// instantiated at all, and are used mainly to mess with the type system in interesting ways.
///
/// For more information, take a look at the [Rust Book] or the [Reference]
///
/// [`Option`]: option/enum.Option.html
/// [Rust Book]: https://doc.rust-lang.org/book/second-edition/ch06-01-defining-an-enum.html
/// [Reference]: https://doc.rust-lang.org/reference/items/enumerations.html
mod enum_keyword { }

#[doc(keyword = "extern")]
//
/// For external connections in Rust code.
///
/// The `extern` keyword is used in two places in Rust. One is in conjunction with the [`crate`]
/// keyword to make your Rust code aware of other Rust crates in your project, i.e. `extern crate
/// lazy_static;`. The other use is in foreign function interfaces (FFI).
///
/// `extern` is used in two different contexts within FFI. The first is in the form of external
/// blcoks, for declaring function interfaces that Rust code can call foreign code by.
///
/// ```rust ignore
/// #[link(name = "my_c_library")]
/// extern "C" {
///     fn my_c_function(x: i32) -> bool;
/// }
/// ```
///
/// This code would attempt to link with libmy_c_library.so on unix-like systems and
/// my_c_library.dll on Windows at runtime, and panic if it can't find something to link to. Rust
/// code could then use `my_c_function` as if it were any other unsafe Rust function. Working with
/// non-Rust languages and FFI is inherently unsafe, so wrappers are usually built around C APIs.
///
/// The mirror use case of FFI is also done via the `extern` keyword:
///
/// ```rust
/// # #![allow(private_no_mangle_fns)]
/// #[no_mangle]
/// pub extern fn callable_from_c(x: i32) -> bool {
///     x % 3 == 0
/// }
/// ```
///
/// If compiled as a dylib, the resulting .so could then be linked to from a C library, and the
/// function could be used as if it was from any other library.
///
/// For more information on FFI, check the [Rust book] or the [Reference].
///
/// [Rust book]: https://doc.rust-lang.org/book/second-edition/ch19-01-unsafe-rust.html#using-extern-functions-to-call-external-code
/// [Reference]: https://doc.rust-lang.org/reference/items/external-blocks.html
mod extern_keyword { }

#[doc(keyword = "fn")]
//
/// The `fn` keyword.
///
/// The `fn` keyword is used to declare a function.
///
/// Example:
///
/// ```rust
/// fn some_function() {
///     // code goes in here
/// }
/// ```
///
/// For more information about functions, take a look at the [Rust Book][book].
///
/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-03-how-functions-work.html
mod fn_keyword { }

#[doc(keyword = "let")]
//
/// The `let` keyword.
///
/// The `let` keyword is used to declare a variable.
///
/// Example:
///
/// ```rust
/// # #![allow(unused_assignments)]
/// let x = 3; // We create a variable named `x` with the value `3`.
/// ```
///
/// By default, all variables are **not** mutable. If you want a mutable variable,
/// you'll have to use the `mut` keyword.
///
/// Example:
///
/// ```rust
/// # #![allow(unused_assignments)]
/// let mut x = 3; // We create a mutable variable named `x` with the value `3`.
///
/// x += 4; // `x` is now equal to `7`.
/// ```
///
/// For more information about the `let` keyword, take a look at the [Rust Book][book].
///
/// [book]: https://doc.rust-lang.org/book/second-edition/ch03-01-variables-and-mutability.html
mod let_keyword { }

#[doc(keyword = "struct")]
//
/// The keyword used to define structs.
///
/// Structs in Rust come in three flavours: Regular structs, tuple structs,
/// and empty structs.
///
/// ```rust
/// struct Regular {
///     field1: f32,
///     field2: String,
///     pub field3: bool
/// }
///
/// struct Tuple(u32, String);
///
/// struct Empty;
/// ```
///
/// Regular structs are the most commonly used. Each field defined within them has a name and a
/// type, and once defined can be accessed using `example_struct.field` syntax. The fields of a
/// struct share its mutability, so `foo.bar = 2;` would only be valid if `foo` was mutable. Adding
/// `pub` to a field makes it visible to code in other modules, as well as allowing it to be
/// directly accessed and modified.
///
/// Tuple structs are similar to regular structs, but its fields have no names. They are used like
/// tuples, with deconstruction possible via `let TupleStruct(x, y) = foo;` syntax.  For accessing
/// individual variables, the same syntax is used as with regular tuples, namely `foo.0`, `foo.1`,
/// etc, starting at zero.
///
/// Empty structs, or unit-like structs, are most commonly used as markers, for example
/// [`PhantomData`]. Empty structs have a size of zero bytes, but unlike empty enums they can be
/// instantiated, making them similar to the unit type `()`. Unit-like structs are useful when you
/// need to implement a trait on something, but don't need to store any data inside it.
///
/// # Instantiation
///
/// Structs can be instantiated in a manner of different ways, each of which can be mixed and
/// matched as needed. The most common way to make a new struct is via a constructor method such as
/// `new()`, but when that isn't available (or you're writing the constructor itself), struct
/// literal syntax is used:
///
/// ```rust
/// # struct Foo { field1: f32, field2: String, etc: bool }
/// let example = Foo {
///     field1: 42.0,
///     field2: "blah".to_string(),
///     etc: true,
/// };
/// ```
///
/// It's only possible to directly instantiate a struct using struct literal syntax when all of its
/// fields are visible to you.
///
/// There are a handful of shortcuts provided to make writing constructors more convenient, most
/// common of which is the Field Init shorthand. When there is a variable and a field of the same
/// name, the assignment can be simplified from `field: field` into simply `field`. The following
/// example of a hypothetical constructor demonstrates this:
///
/// ```rust
/// struct User {
///     name: String,
///     admin: bool,
/// }
///
/// impl User {
///     pub fn new(name: String) -> Self {
///         Self {
///             name,
///             admin: false,
///         }
///     }
/// }
/// ```
///
/// Another shortcut for struct instantiation is available, used when you need to make a new
/// struct that has the same values as most of a previous struct of the same type, called struct
/// update syntax:
///
/// ```rust
/// # struct Foo { field1: String, field2: () }
/// # let thing = Foo { field1: "".to_string(), field2: () };
/// let updated_thing = Foo {
///     field1: "a new value".to_string(),
///     ..thing
/// };
/// ```
///
/// Tuple structs are instantiated in the same way as tuples themselves, except with the struct's
/// name as a prefix: `Foo(123, false, 0.1)`.
///
/// Empty structs are instantiated with just their name, and don't need anything else. `let thing =
/// EmptyStruct;`
///
/// # Style conventions
///
/// Structs are always written in CamelCase, with few exceptions. While the trailing comma on a
/// struct's list of fields can be omitted, it's usually kept for convenience in adding and
/// removing fields down the line.
///
/// For more information on structs, take a look at the [Rust Book][book] or the
/// [Reference][reference].
///
/// [`PhantomData`]: marker/struct.PhantomData.html
/// [book]: https://doc.rust-lang.org/book/second-edition/ch05-01-defining-structs.html
/// [reference]: https://doc.rust-lang.org/reference/items/structs.html
mod struct_keyword { }
<|endoftext|>


<commit_before>use super::prelude::v1::*;
use super::hash::*;
use core::mem;

/// An linked list (used for entries)
pub enum LinkedList<T> {
    Elem(T, Box<LinkedList<T>>),
    Nil,
}

impl<T> LinkedList<T> {
    /// Follow
    pub fn follow(&self) -> Option<&Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Follow mutable
    pub fn follow_mut(&mut self) -> Option<&mut Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref mut l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Push (consumes the list)
    pub fn push(self, elem: T) -> Self {
        LinkedList::Elem(elem, Box::new(self))
    }
}

/// A entry in the hash map
pub struct Entry<K, V> {
    data: LinkedList<(K, V)>,
}

impl<K: PartialEq<K>, V> Entry<K, V> {
    /// Create new
    pub fn new(key: K, value: V) -> Self {
        Entry {
            data: LinkedList::Elem((key, value), Box::new(LinkedList::Nil)),
        }
    }

    /// Get value from entry
    pub fn get(&self, key: &K) -> Option<&V> {
        let mut cur = self.data.follow();

        loop {
            cur = match cur {
                Some(&LinkedList::Elem((ref k, ref v), ref l)) => {
                    if key == k {
                        return Some(v);
                    } else {
                        l.follow()
                    }
                },
                Some(&LinkedList::Nil) | None => {
                    return None;
                },
            }
        }

    }

    /// Get value mutable from entry
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {

        let mut cur = self.data.follow_mut();

        loop {
            cur = match cur {
                Some(x) => match *x {
                    LinkedList::Elem((ref k, ref mut v), ref mut l) => {
                        if key == k {
                            return Some(v);
                        } else {
                            l.follow_mut()
                        }
                    },
                    LinkedList::Nil => {
                        return None;
                    },
                },
                None => {
                    return None;
                },
            }

        }
    }

    /// Push to the list (consumes the entry returning the new one)
    pub fn push(self, key: K, value: V) -> Self {
        Entry {
            data: self.data.push((key, value)),
        }
    }
}

/// A hashtable
pub struct HashMap<K, V> {
    data: [Entry<K, V>; 256],
}

impl<K: Hash + PartialEq, V> HashMap<K, V> {
    /// Get value
    pub fn get(&self, key: &K) -> Option<&V> {
        let mut s = Djb2::new();
        key.hash(&mut s);
        self.data[(s.finish() % 256) as usize].get(key)
    }
    /// Get value mutable
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
        let mut s = Djb2::new();
        key.hash(&mut s);
        self.data[(s.finish() % 256) as usize].get_mut(key)
    }
    /// Set value
    pub fn set(&mut self, key: K, val: V) {
        let mut s = Djb2::new();
        key.hash(&mut s);
        match self.get_mut(&key) {
            Some(k) => {
                *k = val;
                return;
            },
            _ => {}
        }
        let n = (s.finish() % 256) as usize;
        mem::replace(&mut self.data[n], self.data[n].push(key, val));
    }
}

/// DJB2 hashing
pub struct Djb2 {
    state: u64,
}

impl Djb2 {
    /// Create new DJB2 hasher
    pub fn new() -> Self {
        Djb2 {
            state: 5381,
        }
    }
}

impl Hasher for Djb2 {
    fn finish(&self) -> u64 {
        self.state
    }
    fn write(&mut self, bytes: &[u8]) {
        for &b in bytes {
            self.state = ((self.state << 5) + self.state) + b as u64;
        }
    }
}
<commit_msg>Fix the last error<commit_after>use super::prelude::v1::*;
use super::hash::*;
use core::mem;

/// An linked list (used for entries)
#[derive(Clone)]
pub enum LinkedList<T: Clone> {
    Elem(T, Box<LinkedList<T>>),
    Nil,
}

impl<T: Clone> LinkedList<T> {
    /// Follow
    pub fn follow(&self) -> Option<&Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Follow mutable
    pub fn follow_mut(&mut self) -> Option<&mut Self> {
        use self::LinkedList::*;
        match *self {
            Elem(_, box ref mut l) => {
                Some(l)
            },
            Nil => {
                None
            },
        }
    }

    /// Push (consumes the list)
    pub fn push(self, elem: T) -> Self {
        LinkedList::Elem(elem, Box::new(self))
    }
}

/// A entry in the hash map
#[derive(Clone)]
pub struct Entry<K: Clone, V: Clone> {
    data: LinkedList<(K, V)>,
}

impl<K: PartialEq<K> + Clone, V: Clone> Entry<K, V> {
    /// Create new
    pub fn new(key: K, value: V) -> Self {
        Entry {
            data: LinkedList::Elem((key, value), Box::new(LinkedList::Nil)),
        }
    }

    /// Get value from entry
    pub fn get(&self, key: &K) -> Option<&V> {
        let mut cur = self.data.follow();

        loop {
            cur = match cur {
                Some(&LinkedList::Elem((ref k, ref v), ref l)) => {
                    if key == k {
                        return Some(v);
                    } else {
                        l.follow()
                    }
                },
                Some(&LinkedList::Nil) | None => {
                    return None;
                },
            }
        }

    }

    /// Get value mutable from entry
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {

        let mut cur = self.data.follow_mut();

        loop {
            cur = match cur {
                Some(x) => match *x {
                    LinkedList::Elem((ref k, ref mut v), ref mut l) => {
                        if key == k {
                            return Some(v);
                        } else {
                            l.follow_mut()
                        }
                    },
                    LinkedList::Nil => {
                        return None;
                    },
                },
                None => {
                    return None;
                },
            }

        }
    }

    /// Push to the list (consumes the entry returning the new one)
    pub fn push(self, key: K, value: V) -> Self {
        Entry {
            data: self.data.push((key, value)),
        }
    }
}

/// A hashtable
pub struct HashMap<K: Clone, V: Clone> {
    data: [Entry<K, V>; 256],
}

impl<K: Hash + PartialEq + Clone, V: Clone> HashMap<K, V> {
    /// Get value
    pub fn get(&self, key: &K) -> Option<&V> {
        let mut s = Djb2::new();
        key.hash(&mut s);
        self.data[(s.finish() % 256) as usize].get(key)
    }
    /// Get value mutable
    pub fn get_mut(&mut self, key: &K) -> Option<&mut V> {
        let mut s = Djb2::new();
        key.hash(&mut s);
        self.data[(s.finish() % 256) as usize].get_mut(key)
    }
    /// Set value
    pub fn set(&mut self, key: K, val: V) {
        let mut s = Djb2::new();
        key.hash(&mut s);
        match self.get_mut(&key) {
            Some(k) => {
                *k = val;
                return;
            },
            _ => {}
        }
        let n = (s.finish() % 256) as usize;
        self.data[n] = self.data[n].clone().push(key, val);
    }
}

/// DJB2 hashing
pub struct Djb2 {
    state: u64,
}

impl Djb2 {
    /// Create new DJB2 hasher
    pub fn new() -> Self {
        Djb2 {
            state: 5381,
        }
    }
}

impl Hasher for Djb2 {
    fn finish(&self) -> u64 {
        self.state
    }
    fn write(&mut self, bytes: &[u8]) {
        for &b in bytes {
            self.state = ((self.state << 5) + self.state) + b as u64;
        }
    }
}
<|endoftext|>


<commit_before>use chrono::naive::date::NaiveDate as ChronoNaiveDate;

use parse::Parse;

pub struct Date {
    year: i32,
    month: u32,
    day: u32,
}

impl Date {

    pub fn new(year: i32, month: u32, day: u32) -> Date {
        Date {
            year: year,
            month: month,
            day: day,
        }
    }

    pub fn year(&self) -> i32 {
        self.year
    }

    pub fn month(&self) -> u32 {
        self.month
    }

    pub fn day(&self) -> u32 {
        self.day
    }

}

impl Into<ChronoNaiveDate> for Date {

    fn into(self) -> ChronoNaiveDate {
        ChronoNaiveDate::from_ymd(self.year, self.month, self.day)
    }

}

impl Parse for Date {

    /// Parse the date part of the full string into a Date object
    fn parse(s: &str) -> Option<Date> {
        use std::str::FromStr;
        use regex::Regex;
        use parse::time_parse_regex;

        lazy_static! {
            static ref R: Regex = Regex::new(time_parse_regex()).unwrap();
        }

        R.captures(s)
            .and_then(|capts| {
                let year  = capts.name("Y").and_then(|o| FromStr::from_str(o).ok());
                let month = capts.name("M").and_then(|o| FromStr::from_str(o).ok());
                let day   = capts.name("D").and_then(|o| FromStr::from_str(o).ok());

                if year.is_none() {
                    debug!("No year");
                    return None;
                }
                if month.is_none() {
                    debug!("No month");
                    return None;
                }
                if day.is_none() {
                    debug!("No day");
                    return None;
                }

                Some(Date::new(year.unwrap(), month.unwrap(), day.unwrap()))
            })

    }

}

#[cfg(test)]
mod test {
    use super::Date;
    use parse::Parse;

    #[test]
    fn test_valid() {
        let s = "2016-02-01";
        let d = Date::parse(s);

        assert!(d.is_some());
        let d = d.unwrap();

        assert_eq!(2016, d.year());
        assert_eq!(2, d.month());
        assert_eq!(1, d.day());
    }

    #[test]
    fn test_invalid() {
        assert!(Date::parse("2016-021-01").is_none());
        assert!(Date::parse("2016-02-012").is_none());
        assert!(Date::parse("2016-02-0").is_none());
        assert!(Date::parse("2016-0-02").is_none());
        assert!(Date::parse("2016-02").is_none());
        assert!(Date::parse("2016-2").is_none());
    }

}

<commit_msg>Replace unwrap() by match<commit_after>use chrono::naive::date::NaiveDate as ChronoNaiveDate;

use parse::Parse;

pub struct Date {
    year: i32,
    month: u32,
    day: u32,
}

impl Date {

    pub fn new(year: i32, month: u32, day: u32) -> Date {
        Date {
            year: year,
            month: month,
            day: day,
        }
    }

    pub fn year(&self) -> i32 {
        self.year
    }

    pub fn month(&self) -> u32 {
        self.month
    }

    pub fn day(&self) -> u32 {
        self.day
    }

}

impl Into<ChronoNaiveDate> for Date {

    fn into(self) -> ChronoNaiveDate {
        ChronoNaiveDate::from_ymd(self.year, self.month, self.day)
    }

}

impl Parse for Date {

    /// Parse the date part of the full string into a Date object
    fn parse(s: &str) -> Option<Date> {
        use std::str::FromStr;
        use regex::Regex;
        use parse::time_parse_regex;

        lazy_static! {
            static ref R: Regex = Regex::new(time_parse_regex()).unwrap();
        }

        R.captures(s)
            .and_then(|capts| {
                let year  = capts.name("Y").and_then(|o| FromStr::from_str(o).ok());
                let month = capts.name("M").and_then(|o| FromStr::from_str(o).ok());
                let day   = capts.name("D").and_then(|o| FromStr::from_str(o).ok());

                let year = match year {
                    None => {
                        debug!("No year");
                        return None;
                    },
                    Some(x) => x,
                };

                let month = match month {
                    None => {
                        debug!("No month");
                        return None;
                    },
                    Some(x) => x,
                };

                let day = match day {
                    None => {
                        debug!("No day");
                        return None;
                    },
                    Some(x) => x,
                };

                Some(Date::new(year, month, day))
            })

    }

}

#[cfg(test)]
mod test {
    use super::Date;
    use parse::Parse;

    #[test]
    fn test_valid() {
        let s = "2016-02-01";
        let d = Date::parse(s);

        assert!(d.is_some());
        let d = d.unwrap();

        assert_eq!(2016, d.year());
        assert_eq!(2, d.month());
        assert_eq!(1, d.day());
    }

    #[test]
    fn test_invalid() {
        assert!(Date::parse("2016-021-01").is_none());
        assert!(Date::parse("2016-02-012").is_none());
        assert!(Date::parse("2016-02-0").is_none());
        assert!(Date::parse("2016-0-02").is_none());
        assert!(Date::parse("2016-02").is_none());
        assert!(Date::parse("2016-2").is_none());
    }

}

<|endoftext|>


<commit_before>// FIXME This is the simplest most naive implementation of an allocator. I
// basically envisioned it in C in my head and translated it on the fly. I hope
// to revisit this someday when I know the language better, but in the meantime
// don't take this as an example for anything ever.

#![feature(allocator)]
#![feature(const_fn)]

#![allocator]
#![allow(not_unsafe_ptr_arg_deref)]
#![no_std]

use core::ptr;
use core::mem;

use self::spin::Mutex;

extern crate spin;

const SPLIT_FUDGE_FACTOR: usize = 32;

#[repr(C)]
struct Region {
    size: usize,
    prev: Option<*mut Region>,
    next: Option<*mut Region>,
}

pub struct Allocator {
    heap_start: *mut u8,
    heap_size: usize,
    free_list: Option<*mut Region>,
}

static mut ALLOCATOR: Mutex<Allocator> = Mutex::new(Allocator {
    heap_start: 0 as *mut u8,
    heap_size: 0,
    free_list: None,
});

pub fn init_global_allocator(size: u64, raw_bytes: *mut u8) {
    static mut CALLED: bool = false;

    unsafe {
        assert!(!CALLED);
        init_allocator(&mut ALLOCATOR.lock(), size as usize, raw_bytes);
        CALLED = true;
    }
}

pub fn init_allocator(allocator: &mut Allocator, size: usize, raw_bytes: *mut u8) {

    assert!(!raw_bytes.is_null());

    let mut region = raw_bytes as *mut Region;
    unsafe {
        (*region).size = size;
        (*region).next = None;
        (*region).prev = None;
    }
    allocator.heap_size = size;
    allocator.heap_start = raw_bytes;
    allocator.free_list = Some(raw_bytes as *mut Region);
}

impl Allocator {
    pub fn free(&mut self, bytes: *mut u8) {

        let mut region: *mut Region;

        if bytes.is_null() {
            return;
        }

        unsafe {
            let offset = -(mem::size_of::<Region>() as isize);
            region = bytes.offset(offset) as *mut Region;

            assert!(region as *mut u8 >= self.heap_start);

            assert!(!region.is_null());

            (*region).prev = None;
            (*region).next = self.free_list;
        }

        self.free_list = Some(region);
    }

    pub fn alloc(&mut self, size: usize) -> *mut u8 {

        let region_offset = mem::size_of::<Region>() as isize;
        let real_size = size + mem::size_of::<Region>();
        let mut current_region = self.free_list;

        while let Some(region) = current_region {

            unsafe {
                if (*region).size >= real_size {
                    let new_next: Option<*mut Region>;
                    let new_prev: Option<*mut Region>;
                    let split = (*region).size - real_size;
                    if split > (region_offset as usize) + SPLIT_FUDGE_FACTOR {
                        let split_region =
                            (region as *mut u8)
                                .offset((size as isize) +
                                        region_offset) as *mut Region;
                        new_next = Some(split_region);
                        new_prev = Some(split_region);
                    } else {
                        new_next = (*region).next;
                        new_prev = (*region).prev;
                    }
                    match (*region).prev {
                        None => {}
                        Some(prev) => (*prev).next = new_next,
                    }
                    match (*region).next {
                        None => {}
                        Some(next) => (*next).prev = new_prev,
                    }
                    if new_next == None && new_prev == None {
                        self.free_list = None;
                    }
                    return (region as *mut u8).offset(region_offset);
                }
                current_region = (*region).next;
            }
        }

        ptr::null::<u8>() as *mut u8
    }
}

#[cfg(not(test))]
#[no_mangle]
pub extern "C" fn __rust_allocate(size: usize, _align: usize) -> *mut u8 {
    unsafe { ALLOCATOR.lock().alloc(size) }
}

#[cfg(not(test))]
#[no_mangle]
pub extern "C" fn __rust_deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
    unsafe {
        ALLOCATOR.lock().free(ptr);
    }
}

#[cfg(not(test))]
#[no_mangle]
pub extern "C" fn __rust_reallocate(ptr: *mut u8,
                                    old_size: usize,
                                    new_size: usize,
                                    align: usize)
                                    -> *mut u8 {
    use core::cmp;
    let new_ptr = __rust_allocate(new_size, align);
    unsafe { ptr::copy(ptr, new_ptr, cmp::min(old_size, new_size)) };
    __rust_deallocate(ptr, old_size, align);
    new_ptr
}

#[cfg(not(test))]
#[no_mangle]
pub extern "C" fn __rust_reallocate_inplace(_ptr: *mut u8,
                                            old_size: usize,
                                            _size: usize,
                                            _align: usize)
                                            -> usize {
    old_size
}

#[cfg(not(test))]
#[no_mangle]
pub extern "C" fn __rust_usable_size(size: usize, _align: usize) -> usize {
    size
}

#[cfg(test)]
mod tests {
    use core::mem;

    use super::Allocator;
    use super::Region;
    use super::init_allocator;

    #[test]
    fn test_init_allocator() {

        let mut al = Allocator {
            heap_size: 0,
            heap_start: 0 as *mut u8,
            free_list: None,
        };

        let mut memory: [u8; 100] = [0; 100];
        let pmemory: *mut u8 = memory.as_mut_ptr();
        init_allocator(&mut al, mem::size_of::<[u8; 100]>(), pmemory);
        assert_eq!(al.heap_size, 100);
        assert_eq!(al.heap_start, pmemory);

        match al.free_list {
            None => assert!(false),
            Some(fl) => {
                assert!(!fl.is_null());
                unsafe {
                    assert_eq!((*fl).size, 100);
                    assert_eq!((*fl).next, None);
                };
            }
        }
    }

    #[test]
    fn test_alloc_and_free() {

        let mut al = Allocator {
            heap_size: 0,
            heap_start: 0 as *mut u8,
            free_list: None,
        };

        let mut memory: [u8; 1000] = [0; 1000];
        let pmemory: *mut u8 = memory.as_mut_ptr();
        init_allocator(&mut al, mem::size_of::<[u8; 1000]>(), pmemory);

        let m0_size = 10000 - mem::size_of::<Region>();
        let m0 = al.alloc(m0_size);
        assert!(m0.is_null());

        let m1_size = 1000 - mem::size_of::<Region>();
        let m1 = al.alloc(m1_size);
        assert!(!m1.is_null());

        assert_eq!(al.free_list, None);
        al.free(m1);
        assert_ne!(al.free_list, None);

        let m2_size = 100;
        let m2 = al.alloc(m2_size);
        assert!(!m2.is_null());

        let m3_size = 10;
        let m3 = al.alloc(m3_size);
        assert!(!m3.is_null());

        let m4_size = 1;
        let m4 = al.alloc(m4_size);
        assert!(!m4.is_null());

        assert_ne!(al.free_list, None);
        al.free(m3);

        assert_ne!(al.free_list, None);
        al.free(m2);

        assert_ne!(al.free_list, None);
        al.free(m4);
    }
}
<commit_msg>Allow unknown clippy lints<commit_after>// FIXME This is the simplest most naive implementation of an allocator. I
// basically envisioned it in C in my head and translated it on the fly. I hope
// to revisit this someday when I know the language better, but in the meantime
// don't take this as an example for anything ever.

#![feature(allocator)]
#![feature(const_fn)]

#![allocator]
#![allow(not_unsafe_ptr_arg_deref)]
#![allow(unknown_lints)]
#![no_std]

use core::ptr;
use core::mem;

use self::spin::Mutex;

extern crate spin;

const SPLIT_FUDGE_FACTOR: usize = 32;

#[repr(C)]
struct Region {
    size: usize,
    prev: Option<*mut Region>,
    next: Option<*mut Region>,
}

pub struct Allocator {
    heap_start: *mut u8,
    heap_size: usize,
    free_list: Option<*mut Region>,
}

static mut ALLOCATOR: Mutex<Allocator> = Mutex::new(Allocator {
    heap_start: 0 as *mut u8,
    heap_size: 0,
    free_list: None,
});

pub fn init_global_allocator(size: u64, raw_bytes: *mut u8) {
    static mut CALLED: bool = false;

    unsafe {
        assert!(!CALLED);
        init_allocator(&mut ALLOCATOR.lock(), size as usize, raw_bytes);
        CALLED = true;
    }
}

pub fn init_allocator(allocator: &mut Allocator, size: usize, raw_bytes: *mut u8) {

    assert!(!raw_bytes.is_null());

    let mut region = raw_bytes as *mut Region;
    unsafe {
        (*region).size = size;
        (*region).next = None;
        (*region).prev = None;
    }
    allocator.heap_size = size;
    allocator.heap_start = raw_bytes;
    allocator.free_list = Some(raw_bytes as *mut Region);
}

impl Allocator {
    pub fn free(&mut self, bytes: *mut u8) {

        let mut region: *mut Region;

        if bytes.is_null() {
            return;
        }

        unsafe {
            let offset = -(mem::size_of::<Region>() as isize);
            region = bytes.offset(offset) as *mut Region;

            assert!(region as *mut u8 >= self.heap_start);

            assert!(!region.is_null());

            (*region).prev = None;
            (*region).next = self.free_list;
        }

        self.free_list = Some(region);
    }

    pub fn alloc(&mut self, size: usize) -> *mut u8 {

        let region_offset = mem::size_of::<Region>() as isize;
        let real_size = size + mem::size_of::<Region>();
        let mut current_region = self.free_list;

        while let Some(region) = current_region {

            unsafe {
                if (*region).size >= real_size {
                    let new_next: Option<*mut Region>;
                    let new_prev: Option<*mut Region>;
                    let split = (*region).size - real_size;
                    if split > (region_offset as usize) + SPLIT_FUDGE_FACTOR {
                        let split_region =
                            (region as *mut u8)
                                .offset((size as isize) +
                                        region_offset) as *mut Region;
                        new_next = Some(split_region);
                        new_prev = Some(split_region);
                    } else {
                        new_next = (*region).next;
                        new_prev = (*region).prev;
                    }
                    match (*region).prev {
                        None => {}
                        Some(prev) => (*prev).next = new_next,
                    }
                    match (*region).next {
                        None => {}
                        Some(next) => (*next).prev = new_prev,
                    }
                    if new_next == None && new_prev == None {
                        self.free_list = None;
                    }
                    return (region as *mut u8).offset(region_offset);
                }
                current_region = (*region).next;
            }
        }

        ptr::null::<u8>() as *mut u8
    }
}

#[cfg(not(test))]
#[no_mangle]
pub extern "C" fn __rust_allocate(size: usize, _align: usize) -> *mut u8 {
    unsafe { ALLOCATOR.lock().alloc(size) }
}

#[cfg(not(test))]
#[no_mangle]
pub extern "C" fn __rust_deallocate(ptr: *mut u8, _old_size: usize, _align: usize) {
    unsafe {
        ALLOCATOR.lock().free(ptr);
    }
}

#[cfg(not(test))]
#[no_mangle]
pub extern "C" fn __rust_reallocate(ptr: *mut u8,
                                    old_size: usize,
                                    new_size: usize,
                                    align: usize)
                                    -> *mut u8 {
    use core::cmp;
    let new_ptr = __rust_allocate(new_size, align);
    unsafe { ptr::copy(ptr, new_ptr, cmp::min(old_size, new_size)) };
    __rust_deallocate(ptr, old_size, align);
    new_ptr
}

#[cfg(not(test))]
#[no_mangle]
pub extern "C" fn __rust_reallocate_inplace(_ptr: *mut u8,
                                            old_size: usize,
                                            _size: usize,
                                            _align: usize)
                                            -> usize {
    old_size
}

#[cfg(not(test))]
#[no_mangle]
pub extern "C" fn __rust_usable_size(size: usize, _align: usize) -> usize {
    size
}

#[cfg(test)]
mod tests {
    use core::mem;

    use super::Allocator;
    use super::Region;
    use super::init_allocator;

    #[test]
    fn test_init_allocator() {

        let mut al = Allocator {
            heap_size: 0,
            heap_start: 0 as *mut u8,
            free_list: None,
        };

        let mut memory: [u8; 100] = [0; 100];
        let pmemory: *mut u8 = memory.as_mut_ptr();
        init_allocator(&mut al, mem::size_of::<[u8; 100]>(), pmemory);
        assert_eq!(al.heap_size, 100);
        assert_eq!(al.heap_start, pmemory);

        match al.free_list {
            None => assert!(false),
            Some(fl) => {
                assert!(!fl.is_null());
                unsafe {
                    assert_eq!((*fl).size, 100);
                    assert_eq!((*fl).next, None);
                };
            }
        }
    }

    #[test]
    fn test_alloc_and_free() {

        let mut al = Allocator {
            heap_size: 0,
            heap_start: 0 as *mut u8,
            free_list: None,
        };

        let mut memory: [u8; 1000] = [0; 1000];
        let pmemory: *mut u8 = memory.as_mut_ptr();
        init_allocator(&mut al, mem::size_of::<[u8; 1000]>(), pmemory);

        let m0_size = 10000 - mem::size_of::<Region>();
        let m0 = al.alloc(m0_size);
        assert!(m0.is_null());

        let m1_size = 1000 - mem::size_of::<Region>();
        let m1 = al.alloc(m1_size);
        assert!(!m1.is_null());

        assert_eq!(al.free_list, None);
        al.free(m1);
        assert_ne!(al.free_list, None);

        let m2_size = 100;
        let m2 = al.alloc(m2_size);
        assert!(!m2.is_null());

        let m3_size = 10;
        let m3 = al.alloc(m3_size);
        assert!(!m3.is_null());

        let m4_size = 1;
        let m4 = al.alloc(m4_size);
        assert!(!m4.is_null());

        assert_ne!(al.free_list, None);
        al.free(m3);

        assert_ne!(al.free_list, None);
        al.free(m2);

        assert_ne!(al.free_list, None);
        al.free(m4);
    }
}
<|endoftext|>


<commit_before>
//! Apply transforms only to specific parts of a stream.

use std::rc;
use std::cell;

use event;
use select;
use transform;
use modifier;
use builder;

pub(crate) mod element;
pub(crate) mod select_any;
pub(crate) mod select_direct;
pub(crate) mod select_contents;
pub(crate) mod subselect_any;
pub(crate) mod subselect_direct;

pub use self::element::{ SingleElement };
pub use self::select_any::{ SelectAny, SelectAnyOnce };
pub use self::select_direct::{ SelectDirect, SelectDirectOnce };
pub use self::select_contents::{ SelectContent, CurrentContent };
pub use self::subselect_any::{ SubSelectAny, SubSelectAnyOnce };
pub use self::subselect_direct::{ SubSelectDirect, SubSelectDirectOnce };

type Shared<S> = rc::Rc<cell::RefCell<S>>;

trait Restrict {

    fn include(&self, level: &modifier::Level) -> bool;
}

#[derive(Debug)]
struct DirectOnly;

impl Restrict for DirectOnly {

    fn include(&self, level: &modifier::Level) -> bool { level.is_top_level() }
}

#[derive(Debug)]
struct NoRestriction;

impl Restrict for NoRestriction {

    fn include(&self, _level: &modifier::Level) -> bool { true }
}

pub(crate) type BuildElementStream<S> = element::SingleElement<Shared<S>>;

pub(crate) type BuildSubElementStream<S> = BuildElementStream<CurrentContent<S>>;

struct SelectOnce<S, M, B, R>
where
    B: builder::BuildOnce<BuildElementStream<S>>
{
    source: Shared<S>,
    state: modifier::State<SelectOnceState<S, M, B, R>>,
}

impl<S, M, B, R> SelectOnce<S, M, B, R>
where
    M: select::Selector,
    S: event::Stream,
    B: builder::BuildOnce<BuildElementStream<S>>,
    R: Restrict,
{
    fn new(source: S, matcher: M, builder: B, restriction: R) -> SelectOnce<S, M, B, R> {
        SelectOnce {
            source: rc::Rc::new(cell::RefCell::new(source)),
            state: modifier::State::new(SelectOnceState::Scanning {
                matcher,
                builder,
                restriction,
                level: modifier::Level::new(),
            }),
        }
    }
}

impl<S, M, B, R> event::ElementStream for SelectOnce<S, M, B, R>
where
    M: select::Selector,
    S: event::Stream,
    B: builder::BuildOnce<BuildElementStream<S>>,
    R: Restrict,
    B::Stream: event::ElementStream,
{}

impl<S, M, B, R> event::Stream for SelectOnce<S, M, B, R>
where
    S: event::Stream,
    M: select::Selector,
    B: builder::BuildOnce<BuildElementStream<S>>,
    R: Restrict,
{
    fn next_event(&mut self) -> event::StreamResult {
        let SelectOnce {
            ref mut state,
            ref mut source,
        } = *self;
        state.step(|state| match state {
            SelectOnceState::Scanning { level, matcher, builder, restriction } => {
                let event = match source.next_event_skip_noop()? {
                    Some(event) => event,
                    None => return Ok(None),
                };
                if restriction.include(&level) && matcher.matches(&event) {
                    let element = SingleElement::new(source.clone(), event);
                    let new_stream = transform::build_once(element, builder);
                    let state = SelectOnceState::Active { stream: new_stream };
                    Ok(Some((event::noop(), Some(state))))
                } else {
                    let new_level = level.adjust(&event)?;
                    let state = SelectOnceState::Scanning {
                        matcher,
                        builder,
                        restriction,
                        level: new_level,
                    };
                    Ok(Some((event, Some(state))))
                }
            },
            SelectOnceState::Active { mut stream } => match stream.next_event()? {
                None => Ok(Some((event::noop(), Some(SelectOnceState::Passthrough)))),
                Some(event) => Ok(Some((event, Some(SelectOnceState::Active { stream })))),
            },
            SelectOnceState::Passthrough => match source.next_event()? {
                Some(event) => Ok(Some((event, Some(SelectOnceState::Passthrough)))),
                None => Ok(None),
            },
        })
    }
}

enum SelectOnceState<S, M, B, R>
where
    B: builder::BuildOnce<BuildElementStream<S>>
{
    Scanning {
        matcher: M,
        builder: B,
        restriction: R,
        level: modifier::Level,
    },
    Active {
        stream: B::Stream,
    },
    Passthrough,
}

#[derive(Debug)]
struct Select<S, M, B, R> where B: builder::BuildMut<BuildElementStream<S>> {
    source: Shared<S>,
    matcher: M,
    builder: B,
    restriction: R,
    state: modifier::State<SelectState>,
}

impl<S, M, B, R> Select<S, M, B, R>
where
    M: select::Selector,
    S: event::Stream,
    B: builder::BuildMut<BuildElementStream<S>>,
    R: Restrict,
{
    fn new(source: S, matcher: M, builder: B, restriction: R) -> Select<S, M, B, R> {
        Select {
            matcher,
            builder,
            restriction,
            source: rc::Rc::new(cell::RefCell::new(source)),
            state: modifier::State::new(SelectState::Scanning { level: modifier::Level::new() }),
        }
    }
}

impl<S, M, B, R> event::ElementStream for Select<S, M, B, R>
where
    M: select::Selector,
    S: event::Stream,
    B: builder::BuildMut<BuildElementStream<S>>,
    R: Restrict,
    B::Stream: event::ElementStream,
{}

impl<S, M, B, R> event::Stream for Select<S, M, B, R>
where
    S: event::Stream,
    M: select::Selector,
    B: builder::BuildMut<BuildElementStream<S>>,
    R: Restrict,
{
    fn next_event(&mut self) -> event::StreamResult {
        let Select {
            ref mut state,
            ref mut builder,
            ref mut source,
            ref restriction,
            ref matcher,
        } = *self;
        state.step(|state| match state {
            SelectState::Scanning { level } => {
                let event = match source.next_event_skip_noop()? {
                    Some(event) => event,
                    None => return Ok(None),
                };
                if restriction.include(&level) && matcher.matches(&event) {
                    let element = SingleElement::new(source.clone(), event);
                    let new_stream = transform::build_mut(element, builder);
                    let state = SelectState::Active { stream: new_stream, level };
                    Ok(Some((event::noop(), Some(state))))
                } else {
                    let new_level = level.adjust(&event)?;
                    let state = SelectState::Scanning { level: new_level };
                    Ok(Some((event, Some(state))))
                }
            },
            SelectState::Active { mut stream, level } => match stream.next_event()? {
                None => Ok(Some((event::noop(), Some(SelectState::Scanning { level })))),
                Some(event) => Ok(Some((event, Some(SelectState::Active { stream, level })))),
            },
        })
    }
}

#[derive(Debug)]
enum SelectState<O> {
    Scanning {
        level: modifier::Level,
    },
    Active {
        level: modifier::Level,
        stream: O,
    },
}

#[cfg(test)]
mod tests {
    use std::str::{ FromStr };

    #[test]
    fn select_roundtrip() {
        let original = "<c>foo</c>";
        test_transform!(
            Default::default(),
            original,
            original,
            |html| html.select(::select::Tag::from_str("b").unwrap(), |elem| elem)
        );
    }
}
<commit_msg>moved select roundtrip test to new test structure<commit_after>
//! Apply transforms only to specific parts of a stream.

use std::rc;
use std::cell;

use event;
use select;
use transform;
use modifier;
use builder;

pub(crate) mod element;
pub(crate) mod select_any;
pub(crate) mod select_direct;
pub(crate) mod select_contents;
pub(crate) mod subselect_any;
pub(crate) mod subselect_direct;

pub use self::element::{ SingleElement };
pub use self::select_any::{ SelectAny, SelectAnyOnce };
pub use self::select_direct::{ SelectDirect, SelectDirectOnce };
pub use self::select_contents::{ SelectContent, CurrentContent };
pub use self::subselect_any::{ SubSelectAny, SubSelectAnyOnce };
pub use self::subselect_direct::{ SubSelectDirect, SubSelectDirectOnce };

type Shared<S> = rc::Rc<cell::RefCell<S>>;

trait Restrict {

    fn include(&self, level: &modifier::Level) -> bool;
}

#[derive(Debug)]
struct DirectOnly;

impl Restrict for DirectOnly {

    fn include(&self, level: &modifier::Level) -> bool { level.is_top_level() }
}

#[derive(Debug)]
struct NoRestriction;

impl Restrict for NoRestriction {

    fn include(&self, _level: &modifier::Level) -> bool { true }
}

pub(crate) type BuildElementStream<S> = element::SingleElement<Shared<S>>;

pub(crate) type BuildSubElementStream<S> = BuildElementStream<CurrentContent<S>>;

struct SelectOnce<S, M, B, R>
where
    B: builder::BuildOnce<BuildElementStream<S>>
{
    source: Shared<S>,
    state: modifier::State<SelectOnceState<S, M, B, R>>,
}

impl<S, M, B, R> SelectOnce<S, M, B, R>
where
    M: select::Selector,
    S: event::Stream,
    B: builder::BuildOnce<BuildElementStream<S>>,
    R: Restrict,
{
    fn new(source: S, matcher: M, builder: B, restriction: R) -> SelectOnce<S, M, B, R> {
        SelectOnce {
            source: rc::Rc::new(cell::RefCell::new(source)),
            state: modifier::State::new(SelectOnceState::Scanning {
                matcher,
                builder,
                restriction,
                level: modifier::Level::new(),
            }),
        }
    }
}

impl<S, M, B, R> event::ElementStream for SelectOnce<S, M, B, R>
where
    M: select::Selector,
    S: event::Stream,
    B: builder::BuildOnce<BuildElementStream<S>>,
    R: Restrict,
    B::Stream: event::ElementStream,
{}

impl<S, M, B, R> event::Stream for SelectOnce<S, M, B, R>
where
    S: event::Stream,
    M: select::Selector,
    B: builder::BuildOnce<BuildElementStream<S>>,
    R: Restrict,
{
    fn next_event(&mut self) -> event::StreamResult {
        let SelectOnce {
            ref mut state,
            ref mut source,
        } = *self;
        state.step(|state| match state {
            SelectOnceState::Scanning { level, matcher, builder, restriction } => {
                let event = match source.next_event_skip_noop()? {
                    Some(event) => event,
                    None => return Ok(None),
                };
                if restriction.include(&level) && matcher.matches(&event) {
                    let element = SingleElement::new(source.clone(), event);
                    let new_stream = transform::build_once(element, builder);
                    let state = SelectOnceState::Active { stream: new_stream };
                    Ok(Some((event::noop(), Some(state))))
                } else {
                    let new_level = level.adjust(&event)?;
                    let state = SelectOnceState::Scanning {
                        matcher,
                        builder,
                        restriction,
                        level: new_level,
                    };
                    Ok(Some((event, Some(state))))
                }
            },
            SelectOnceState::Active { mut stream } => match stream.next_event()? {
                None => Ok(Some((event::noop(), Some(SelectOnceState::Passthrough)))),
                Some(event) => Ok(Some((event, Some(SelectOnceState::Active { stream })))),
            },
            SelectOnceState::Passthrough => match source.next_event()? {
                Some(event) => Ok(Some((event, Some(SelectOnceState::Passthrough)))),
                None => Ok(None),
            },
        })
    }
}

enum SelectOnceState<S, M, B, R>
where
    B: builder::BuildOnce<BuildElementStream<S>>
{
    Scanning {
        matcher: M,
        builder: B,
        restriction: R,
        level: modifier::Level,
    },
    Active {
        stream: B::Stream,
    },
    Passthrough,
}

#[derive(Debug)]
struct Select<S, M, B, R> where B: builder::BuildMut<BuildElementStream<S>> {
    source: Shared<S>,
    matcher: M,
    builder: B,
    restriction: R,
    state: modifier::State<SelectState>,
}

impl<S, M, B, R> Select<S, M, B, R>
where
    M: select::Selector,
    S: event::Stream,
    B: builder::BuildMut<BuildElementStream<S>>,
    R: Restrict,
{
    fn new(source: S, matcher: M, builder: B, restriction: R) -> Select<S, M, B, R> {
        Select {
            matcher,
            builder,
            restriction,
            source: rc::Rc::new(cell::RefCell::new(source)),
            state: modifier::State::new(SelectState::Scanning { level: modifier::Level::new() }),
        }
    }
}

impl<S, M, B, R> event::ElementStream for Select<S, M, B, R>
where
    M: select::Selector,
    S: event::Stream,
    B: builder::BuildMut<BuildElementStream<S>>,
    R: Restrict,
    B::Stream: event::ElementStream,
{}

impl<S, M, B, R> event::Stream for Select<S, M, B, R>
where
    S: event::Stream,
    M: select::Selector,
    B: builder::BuildMut<BuildElementStream<S>>,
    R: Restrict,
{
    fn next_event(&mut self) -> event::StreamResult {
        let Select {
            ref mut state,
            ref mut builder,
            ref mut source,
            ref restriction,
            ref matcher,
        } = *self;
        state.step(|state| match state {
            SelectState::Scanning { level } => {
                let event = match source.next_event_skip_noop()? {
                    Some(event) => event,
                    None => return Ok(None),
                };
                if restriction.include(&level) && matcher.matches(&event) {
                    let element = SingleElement::new(source.clone(), event);
                    let new_stream = transform::build_mut(element, builder);
                    let state = SelectState::Active { stream: new_stream, level };
                    Ok(Some((event::noop(), Some(state))))
                } else {
                    let new_level = level.adjust(&event)?;
                    let state = SelectState::Scanning { level: new_level };
                    Ok(Some((event, Some(state))))
                }
            },
            SelectState::Active { mut stream, level } => match stream.next_event()? {
                None => Ok(Some((event::noop(), Some(SelectState::Scanning { level })))),
                Some(event) => Ok(Some((event, Some(SelectState::Active { stream, level })))),
            },
        })
    }
}

#[derive(Debug)]
enum SelectState<O> {
    Scanning {
        level: modifier::Level,
    },
    Active {
        level: modifier::Level,
        stream: O,
    },
}

#[cfg(test)]
mod tests {

    test_group!(select_roundtrip:
        "roundtrip" => transform_test!(
            "<c>foo</c>",
            "<c>foo</c>",
            |html| html.select("b", |elem| elem),
        ),
    );
}
<|endoftext|>


<commit_before>use super::{
    FnEvalContext,
    CachedMir,
    TerminatorTarget,
};
use error::EvalResult;
use rustc::mir::repr as mir;

pub enum Event<'a, 'tcx: 'a> {
    Assignment(&'a mir::Statement<'tcx>),
    Terminator(&'a mir::Terminator<'tcx>),
    Done,
}

pub struct Stepper<'fncx, 'a: 'fncx, 'b: 'a + 'mir, 'mir: 'fncx, 'tcx: 'b>{
    fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>,
    block: mir::BasicBlock,
    stmt: usize,
    mir: CachedMir<'mir, 'tcx>,
    process: fn (&mut Stepper<'fncx, 'a, 'b, 'mir, 'tcx>) -> EvalResult<()>,
}

impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx> {
    pub(super) fn new(fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>) -> Self {
        Stepper {
            block: fncx.frame().next_block,
            mir: fncx.mir(),
            fncx: fncx,
            stmt: 0,
            process: Self::dummy,
        }
    }
    fn dummy(&mut self) -> EvalResult<()> { Ok(()) }
    fn statement(&mut self) -> EvalResult<()> {
        let block_data = self.mir.basic_block_data(self.block);
        let stmt = &block_data.statements[self.stmt];
        let mir::StatementKind::Assign(ref lvalue, ref rvalue) = stmt.kind;
        let result = self.fncx.eval_assignment(lvalue, rvalue);
        self.fncx.maybe_report(stmt.span, result)?;
        self.stmt += 1;
        Ok(())
    }
    fn terminator(&mut self) -> EvalResult<()> {
        self.stmt = 0;
        let term = {
            let block_data = self.mir.basic_block_data(self.block);
            let terminator = block_data.terminator();
            let result = self.fncx.eval_terminator(terminator);
            self.fncx.maybe_report(terminator.span, result)?
        };
        match term {
            TerminatorTarget::Block(block) => {
                self.block = block;
            },
            TerminatorTarget::Return => {
                self.fncx.pop_stack_frame();
                self.fncx.name_stack.pop();
                if !self.fncx.stack.is_empty() {
                    self.block = self.fncx.frame().next_block;
                    self.mir = self.fncx.mir();
                }
            },
            TerminatorTarget::Call => {
                self.block = self.fncx.frame().next_block;
                self.mir = self.fncx.mir();
            },
        }
        Ok(())
    }
    pub fn step<'step>(&'step mut self) -> EvalResult<Event<'step, 'tcx>> {
        (self.process)(self)?;

        if self.fncx.stack.is_empty() {
            // fuse the iterator
            self.process = Self::dummy;
            return Ok(Event::Done);
        }

        let basic_block = self.mir.basic_block_data(self.block);

        if let Some(stmt) = basic_block.statements.get(self.stmt) {
            self.process = Self::statement;
            return Ok(Event::Assignment(&stmt));
        }

        self.process = Self::terminator;
        Ok(Event::Terminator(basic_block.terminator()))
    }
    pub fn block(&self) -> mir::BasicBlock {
        self.block
    }
}
<commit_msg>style: spaces between functions<commit_after>use super::{
    FnEvalContext,
    CachedMir,
    TerminatorTarget,
};
use error::EvalResult;
use rustc::mir::repr as mir;

pub enum Event<'a, 'tcx: 'a> {
    Assignment(&'a mir::Statement<'tcx>),
    Terminator(&'a mir::Terminator<'tcx>),
    Done,
}

pub struct Stepper<'fncx, 'a: 'fncx, 'b: 'a + 'mir, 'mir: 'fncx, 'tcx: 'b>{
    fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>,
    block: mir::BasicBlock,
    stmt: usize,
    mir: CachedMir<'mir, 'tcx>,
    process: fn (&mut Stepper<'fncx, 'a, 'b, 'mir, 'tcx>) -> EvalResult<()>,
}

impl<'fncx, 'a, 'b: 'a + 'mir, 'mir, 'tcx: 'b> Stepper<'fncx, 'a, 'b, 'mir, 'tcx> {
    pub(super) fn new(fncx: &'fncx mut FnEvalContext<'a, 'b, 'mir, 'tcx>) -> Self {
        Stepper {
            block: fncx.frame().next_block,
            mir: fncx.mir(),
            fncx: fncx,
            stmt: 0,
            process: Self::dummy,
        }
    }

    fn dummy(&mut self) -> EvalResult<()> { Ok(()) }

    fn statement(&mut self) -> EvalResult<()> {
        let block_data = self.mir.basic_block_data(self.block);
        let stmt = &block_data.statements[self.stmt];
        let mir::StatementKind::Assign(ref lvalue, ref rvalue) = stmt.kind;
        let result = self.fncx.eval_assignment(lvalue, rvalue);
        self.fncx.maybe_report(stmt.span, result)?;
        self.stmt += 1;
        Ok(())
    }

    fn terminator(&mut self) -> EvalResult<()> {
        self.stmt = 0;
        let term = {
            let block_data = self.mir.basic_block_data(self.block);
            let terminator = block_data.terminator();
            let result = self.fncx.eval_terminator(terminator);
            self.fncx.maybe_report(terminator.span, result)?
        };
        match term {
            TerminatorTarget::Block(block) => {
                self.block = block;
            },
            TerminatorTarget::Return => {
                self.fncx.pop_stack_frame();
                self.fncx.name_stack.pop();
                if !self.fncx.stack.is_empty() {
                    self.block = self.fncx.frame().next_block;
                    self.mir = self.fncx.mir();
                }
            },
            TerminatorTarget::Call => {
                self.block = self.fncx.frame().next_block;
                self.mir = self.fncx.mir();
            },
        }
        Ok(())
    }

    pub fn step<'step>(&'step mut self) -> EvalResult<Event<'step, 'tcx>> {
        (self.process)(self)?;

        if self.fncx.stack.is_empty() {
            // fuse the iterator
            self.process = Self::dummy;
            return Ok(Event::Done);
        }

        let basic_block = self.mir.basic_block_data(self.block);

        if let Some(stmt) = basic_block.statements.get(self.stmt) {
            self.process = Self::statement;
            return Ok(Event::Assignment(&stmt));
        }

        self.process = Self::terminator;
        Ok(Event::Terminator(basic_block.terminator()))
    }

    pub fn block(&self) -> mir::BasicBlock {
        self.block
    }
}
<|endoftext|>


<commit_before>// CITA
// Copyright 2016-2017 Cryptape Technologies LLC.

// This program is free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any
// later version.

// This program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! A multiplexed cita protocol

use byteorder::{ByteOrder, NetworkEndian};
use bytes::BufMut;
use bytes::BytesMut;
use std::io;
use std::str;
use tokio::codec::{Decoder, Encoder};

pub type CitaRequest = (String, Vec<u8>);
pub type CitaResponse = Option<(String, Vec<u8>)>;

/// Our multiplexed line-based codec
pub struct CitaCodec;

/// Implementation of the multiplexed line-based protocol.
///
/// Frames begin with a 4 byte header, consisting of the numeric request ID
/// encoded in network order, followed by the frame payload encoded as a UTF-8
/// string and terminated with a '\n' character:
///
/// # An example frame:
///
/// +------------------------+--------------------------+
/// | Type                   | Content                  |
/// +------------------------+--------------------------+
/// | Symbol for Start       | \xDEADBEEF               |
/// | Length of Full Payload | u32                      |
/// +------------------------+--------------------------+
/// | Length of Key          | u8                       |
/// | Key                    | bytes of a str           |
/// +------------------------+--------------------------+
/// | Message                | a serialize data         |
/// +------------------------+--------------------------+
///

// Start of network messages.
const NETMSG_START: u64 = 0xDEAD_BEEF_0000_0000;

fn opt_bytes_extend(buf: &mut BytesMut, data: &[u8]) {
    buf.reserve(data.len());
    unsafe {
        buf.bytes_mut()[..data.len()].copy_from_slice(data);
        buf.advance_mut(data.len());
    }
}

impl Decoder for CitaCodec {
    type Item = CitaRequest;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
        Ok(network_message_to_pubsub_message(buf))
    }
}

impl Encoder for CitaCodec {
    type Item = CitaResponse;
    type Error = io::Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> io::Result<()> {
        pubsub_message_to_network_message(buf, msg);
        Ok(())
    }
}

pub fn pubsub_message_to_network_message(buf: &mut BytesMut, msg: Option<(String, Vec<u8>)>) {
    let mut request_id_bytes = [0; 8];
    if let Some((key, body)) = msg {
        let length_key = key.len();
        // Use 1 byte to store key length.
        if length_key > u8::max_value() as usize {
            error!("The MQ message key is too long {}.", key);
        }
        // Use 1 bytes to store the length for key, then store key, the last part is body.
        let length_full = 1 + length_key + body.len();
        if length_full > u32::max_value() as usize {
            error!(
                "The MQ message with key {} is too long {}.",
                key,
                body.len()
            );
        }
        let request_id = NETMSG_START + length_full as u64;
        NetworkEndian::write_u64(&mut request_id_bytes, request_id);
        opt_bytes_extend(buf, &request_id_bytes);
        buf.put_u8(length_key as u8);
        opt_bytes_extend(buf, key.as_bytes());
        opt_bytes_extend(buf, &body);
    } else {
        let request_id = NETMSG_START;
        NetworkEndian::write_u64(&mut request_id_bytes, request_id);
        opt_bytes_extend(buf, &request_id_bytes);
    }
}

pub fn network_message_to_pubsub_message(buf: &mut BytesMut) -> Option<(String, Vec<u8>)> {
    if buf.len() < 8 {
        return None;
    }

    let request_id = NetworkEndian::read_u64(buf.as_ref());
    let netmsg_start = request_id & 0xffff_ffff_0000_0000;
    let length_full = (request_id & 0x0000_0000_ffff_ffff) as usize;
    if netmsg_start != NETMSG_START {
        return None;
    }
    if length_full + 8 > buf.len() {
        return None;
    }
    let _request_id_buf = buf.split_to(8);

    if length_full == 0 {
        return None;
    }
    let mut payload_buf = buf.split_to(length_full);

    let length_key = payload_buf[0] as usize;
    let _length_key_buf = payload_buf.split_to(1);
    if length_key == 0 {
        error!("network message key is empty.");
        return None;
    }
    if length_key > payload_buf.len() {
        error!(
            "Buffer is not enough for key {} > {}.",
            length_key,
            buf.len()
        );
        return None;
    }
    let key_buf = payload_buf.split_to(length_key);
    let key_str_result = str::from_utf8(&key_buf);
    if key_str_result.is_err() {
        error!("network message parse key error {:?}.", key_buf);
        return None;
    }
    let key = key_str_result.unwrap().to_string();
    if length_full == 1 + length_key {
        warn!("network message is empty.");
    }
    Some((key, payload_buf.to_vec()))
}

#[cfg(test)]
mod test {
    use super::{network_message_to_pubsub_message, pubsub_message_to_network_message};
    use bytes::BytesMut;

    #[test]
    fn convert_empty_message() {
        let mut buf = BytesMut::with_capacity(4 + 4);
        pubsub_message_to_network_message(&mut buf, None);
        let pub_msg_opt = network_message_to_pubsub_message(&mut buf);
        assert!(pub_msg_opt.is_none());
    }

    #[test]
    fn convert_messages() {
        let key = "this-is-the-key".to_string();
        let msg: Vec<u8> = vec![1, 3, 5, 7, 9];
        let mut buf = BytesMut::with_capacity(4 + 4 + 1 + key.len() + msg.len());
        pubsub_message_to_network_message(&mut buf, Some((key.clone(), msg.clone())));
        let pub_msg_opt = network_message_to_pubsub_message(&mut buf);
        assert!(pub_msg_opt.is_some());
        let (key_new, msg_new) = pub_msg_opt.unwrap();
        assert_eq!(key, key_new);
        assert_eq!(msg, msg_new);
    }
}
<commit_msg>Exit when the check fails<commit_after>// CITA
// Copyright 2016-2017 Cryptape Technologies LLC.

// This program is free software: you can redistribute it
// and/or modify it under the terms of the GNU General Public
// License as published by the Free Software Foundation,
// either version 3 of the License, or (at your option) any
// later version.

// This program is distributed in the hope that it will be
// useful, but WITHOUT ANY WARRANTY; without even the implied
// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
// PURPOSE. See the GNU General Public License for more details.

// You should have received a copy of the GNU General Public License
// along with this program.  If not, see <http://www.gnu.org/licenses/>.

//! A multiplexed cita protocol

use byteorder::{ByteOrder, NetworkEndian};
use bytes::BufMut;
use bytes::BytesMut;
use std::io;
use std::str;
use tokio::codec::{Decoder, Encoder};

pub type CitaRequest = (String, Vec<u8>);
pub type CitaResponse = Option<(String, Vec<u8>)>;

/// Our multiplexed line-based codec
pub struct CitaCodec;

/// Implementation of the multiplexed line-based protocol.
///
/// Frames begin with a 4 byte header, consisting of the numeric request ID
/// encoded in network order, followed by the frame payload encoded as a UTF-8
/// string and terminated with a '\n' character:
///
/// # An example frame:
///
/// +------------------------+--------------------------+
/// | Type                   | Content                  |
/// +------------------------+--------------------------+
/// | Symbol for Start       | \xDEADBEEF               |
/// | Length of Full Payload | u32                      |
/// +------------------------+--------------------------+
/// | Length of Key          | u8                       |
/// | Key                    | bytes of a str           |
/// +------------------------+--------------------------+
/// | Message                | a serialize data         |
/// +------------------------+--------------------------+
///

// Start of network messages.
const NETMSG_START: u64 = 0xDEAD_BEEF_0000_0000;

fn opt_bytes_extend(buf: &mut BytesMut, data: &[u8]) {
    buf.reserve(data.len());
    unsafe {
        buf.bytes_mut()[..data.len()].copy_from_slice(data);
        buf.advance_mut(data.len());
    }
}

impl Decoder for CitaCodec {
    type Item = CitaRequest;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
        Ok(network_message_to_pubsub_message(buf))
    }
}

impl Encoder for CitaCodec {
    type Item = CitaResponse;
    type Error = io::Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> io::Result<()> {
        pubsub_message_to_network_message(buf, msg);
        Ok(())
    }
}

pub fn pubsub_message_to_network_message(buf: &mut BytesMut, msg: Option<(String, Vec<u8>)>) {
    let mut request_id_bytes = [0; 8];
    if let Some((key, body)) = msg {
        let length_key = key.len();
        // Use 1 byte to store key length.
        if length_key > u8::max_value() as usize {
            error!("The MQ message key is too long {}.", key);
            return;
        }
        // Use 1 bytes to store the length for key, then store key, the last part is body.
        let length_full = 1 + length_key + body.len();
        if length_full > u32::max_value() as usize {
            error!(
                "The MQ message with key {} is too long {}.",
                key,
                body.len()
            );
            return;
        }
        let request_id = NETMSG_START + length_full as u64;
        NetworkEndian::write_u64(&mut request_id_bytes, request_id);
        opt_bytes_extend(buf, &request_id_bytes);
        buf.put_u8(length_key as u8);
        opt_bytes_extend(buf, key.as_bytes());
        opt_bytes_extend(buf, &body);
    } else {
        let request_id = NETMSG_START;
        NetworkEndian::write_u64(&mut request_id_bytes, request_id);
        opt_bytes_extend(buf, &request_id_bytes);
    }
}

pub fn network_message_to_pubsub_message(buf: &mut BytesMut) -> Option<(String, Vec<u8>)> {
    if buf.len() < 8 {
        return None;
    }

    let request_id = NetworkEndian::read_u64(buf.as_ref());
    let netmsg_start = request_id & 0xffff_ffff_0000_0000;
    let length_full = (request_id & 0x0000_0000_ffff_ffff) as usize;
    if netmsg_start != NETMSG_START {
        return None;
    }
    if length_full + 8 > buf.len() {
        return None;
    }
    let _request_id_buf = buf.split_to(8);

    if length_full == 0 {
        return None;
    }
    let mut payload_buf = buf.split_to(length_full);

    let length_key = payload_buf[0] as usize;
    let _length_key_buf = payload_buf.split_to(1);
    if length_key == 0 {
        error!("network message key is empty.");
        return None;
    }
    if length_key > payload_buf.len() {
        error!(
            "Buffer is not enough for key {} > {}.",
            length_key,
            buf.len()
        );
        return None;
    }
    let key_buf = payload_buf.split_to(length_key);
    let key_str_result = str::from_utf8(&key_buf);
    if key_str_result.is_err() {
        error!("network message parse key error {:?}.", key_buf);
        return None;
    }
    let key = key_str_result.unwrap().to_string();
    if length_full == 1 + length_key {
        warn!("network message is empty.");
    }
    Some((key, payload_buf.to_vec()))
}

#[cfg(test)]
mod test {
    use super::{network_message_to_pubsub_message, pubsub_message_to_network_message};
    use bytes::BytesMut;

    #[test]
    fn convert_empty_message() {
        let mut buf = BytesMut::with_capacity(4 + 4);
        pubsub_message_to_network_message(&mut buf, None);
        let pub_msg_opt = network_message_to_pubsub_message(&mut buf);
        assert!(pub_msg_opt.is_none());
    }

    #[test]
    fn convert_messages() {
        let key = "this-is-the-key".to_string();
        let msg: Vec<u8> = vec![1, 3, 5, 7, 9];
        let mut buf = BytesMut::with_capacity(4 + 4 + 1 + key.len() + msg.len());
        pubsub_message_to_network_message(&mut buf, Some((key.clone(), msg.clone())));
        let pub_msg_opt = network_message_to_pubsub_message(&mut buf);
        assert!(pub_msg_opt.is_some());
        let (key_new, msg_new) = pub_msg_opt.unwrap();
        assert_eq!(key, key_new);
        assert_eq!(msg, msg_new);
    }
}
<|endoftext|>


<commit_before>#![allow(dead_code)]

#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate languageserver_types;
#[macro_use]
extern crate log;
extern crate simple_logging;
extern crate url;
extern crate syntax;
extern crate errors;

// mod protocol;
// mod server;

mod transport;
mod jsonrpc;

use std::cell::RefCell;
use std::io;
use std::io::{BufRead, Write};
use std::ops::DerefMut;
use languageserver_types as lst;
use url::Url;
use jsonrpc::{RpcHandler, Response};
use transport::Transport;

fn main() {
    simple_logging::log_to_stderr(log::LogLevelFilter::Trace)
        .expect("failed to initialize logging");

    let stdin = io::stdin();
    let stdin = stdin.lock();
    let stdout = io::stdout();
    let stdout = stdout.lock();

    let transport = RefCell::new(Transport::new(stdin, stdout));
    let mut rpc = RpcHandler::new();

    rpc.add_method("initialize", |_: lst::InitializeParams| {
        Response::Success::<_, ()>(lst::InitializeResult {
            capabilities: lst::ServerCapabilities {
                text_document_sync: Some(lst::TextDocumentSyncKind::Full),
                .. Default::default()
            },
        })
    });

    rpc.add_notification("initialized", |_: serde_json::Value| {
    });

    rpc.add_notification("textDocument/didOpen", |params: lst::DidOpenTextDocumentParams| {
        publish_diagnostics(
            &params.text_document.text,
            params.text_document.uri,
            transport.borrow_mut().deref_mut(),
        );
    });

    rpc.add_notification("textDocument/didSave", |_: lst::DidSaveTextDocumentParams| {
    });

    rpc.add_notification("textDocument/didClose", |_: lst::DidCloseTextDocumentParams| {
    });

    rpc.add_notification("textDocument/didChange", |params: lst::DidChangeTextDocumentParams| {
        if params.content_changes.len() != 1 ||
            params.content_changes[0].range.is_some() ||
            params.content_changes[0].range_length.is_some()
        {
            debug!("got bad edit with `didChange` event");
        } else {
            publish_diagnostics(
                &params.content_changes[0].text,
                params.text_document.uri,
                transport.borrow_mut().deref_mut(),
            );
        }
    });

    loop {
        let response = {
            let msg = transport
                .borrow_mut()
                .read_message()
                .expect("failed to read message");
            rpc.handle_call(&msg)
        };
        if let Some(response) = response {
            transport
                .borrow_mut()
                .send_message(&response)
                .expect("failed to send");
        }
    }
}

fn publish_diagnostics<R, W>(source: &str, doc: Url, transport: &mut Transport<R, W>)
    where R: BufRead, W: Write
{
    let diagnostics = make_diagnostics(source);
    let params = lst::PublishDiagnosticsParams {
        uri: doc,
        diagnostics,
    };
    #[derive(Serialize)]
    struct Notification {
        jsonrpc: &'static str,
        method: &'static str,
        params: lst::PublishDiagnosticsParams,
    }

    let notification = Notification {
        jsonrpc: "2.0",
        method: "textDocument/publishDiagnostics",
        params,
    };
    let string = serde_json::to_string(&notification)
        .expect("failed to serialize diagnostics");
    transport.send_message(&string).expect("failed to write message");
}

fn make_diagnostics(source: &str) -> Vec<lst::Diagnostic> {
    let reporter = errors::Reporter::new();
    let tokens = syntax::lex(source, reporter.clone());
    let _ = syntax::parse(tokens, reporter.clone());
    reporter
        .get_diagnostics()
        .into_iter()
        .map(|d| note_to_diagnostic(&d.notes[0], d.message))
        .collect()
}

fn note_to_diagnostic(note: &errors::reporter::Note, msg: String) -> lst::Diagnostic {
    fn convert_pos(pos: errors::position::Position) -> lst::Position {
        lst::Position {
            line: (pos.line - 1) as u64,
            character: (pos.column - 1) as u64,
        }
    }
    fn convert_range(range: errors::position::Span) -> lst::Range {
        lst::Range {
            start: convert_pos(range.start),
            end: convert_pos(range.end),
        }
    }
    lst::Diagnostic {
        range: convert_range(note.span),
        severity: Some(lst::DiagnosticSeverity::Error),
        code: None,
        source: Some("plank".into()),
        message: msg,
    }
}
<commit_msg>minor cleanup<commit_after>#[macro_use]
extern crate serde_derive;
extern crate serde;
extern crate serde_json;
extern crate languageserver_types;
#[macro_use]
extern crate log;
extern crate simple_logging;
extern crate url;
extern crate syntax;
extern crate errors;

mod transport;
mod jsonrpc;

use std::cell::RefCell;
use std::io;
use std::io::{BufRead, Write};
use std::ops::DerefMut;
use languageserver_types as lst;
use url::Url;
use jsonrpc::{RpcHandler, Response};
use transport::Transport;

fn main() {
    simple_logging::log_to_stderr(log::LogLevelFilter::Trace)
        .expect("failed to initialize logging");

    let stdin = io::stdin();
    let stdin = stdin.lock();
    let stdout = io::stdout();
    let stdout = stdout.lock();

    let transport = RefCell::new(Transport::new(stdin, stdout));
    let mut rpc = RpcHandler::new();

    rpc.add_method("initialize", |_: lst::InitializeParams| {
        Response::Success::<_, ()>(lst::InitializeResult {
            capabilities: lst::ServerCapabilities {
                text_document_sync: Some(lst::TextDocumentSyncKind::Full),
                .. Default::default()
            },
        })
    });

    rpc.add_notification("initialized", |_: serde_json::Value| {
    });

    rpc.add_notification("textDocument/didOpen", |params: lst::DidOpenTextDocumentParams| {
        publish_diagnostics(
            &params.text_document.text,
            params.text_document.uri,
            transport.borrow_mut().deref_mut(),
        );
    });

    rpc.add_notification("textDocument/didSave", |_: lst::DidSaveTextDocumentParams| {
    });

    rpc.add_notification("textDocument/didClose", |_: lst::DidCloseTextDocumentParams| {
    });

    rpc.add_notification("textDocument/didChange", |params: lst::DidChangeTextDocumentParams| {
        if params.content_changes.len() != 1 ||
            params.content_changes[0].range.is_some() ||
            params.content_changes[0].range_length.is_some()
        {
            debug!("got bad edit with `didChange` event");
        } else {
            publish_diagnostics(
                &params.content_changes[0].text,
                params.text_document.uri,
                transport.borrow_mut().deref_mut(),
            );
        }
    });

    loop {
        let response = {
            let msg = transport
                .borrow_mut()
                .read_message()
                .expect("failed to read message");
            rpc.handle_call(&msg)
        };
        if let Some(response) = response {
            transport
                .borrow_mut()
                .send_message(&response)
                .expect("failed to send");
        }
    }
}

fn publish_diagnostics<R, W>(source: &str, doc: Url, transport: &mut Transport<R, W>)
    where R: BufRead, W: Write
{
    let diagnostics = make_diagnostics(source);
    let params = lst::PublishDiagnosticsParams {
        uri: doc,
        diagnostics,
    };
    #[derive(Serialize)]
    struct Notification {
        jsonrpc: &'static str,
        method: &'static str,
        params: lst::PublishDiagnosticsParams,
    }

    let notification = Notification {
        jsonrpc: "2.0",
        method: "textDocument/publishDiagnostics",
        params,
    };
    let string = serde_json::to_string(&notification)
        .expect("failed to serialize diagnostics");
    transport.send_message(&string).expect("failed to write message");
}

fn make_diagnostics(source: &str) -> Vec<lst::Diagnostic> {
    let reporter = errors::Reporter::new();
    let tokens = syntax::lex(source, reporter.clone());
    let _ = syntax::parse(tokens, reporter.clone());
    reporter
        .get_diagnostics()
        .into_iter()
        .map(|d| note_to_diagnostic(&d.notes[0], d.message))
        .collect()
}

fn note_to_diagnostic(note: &errors::reporter::Note, msg: String) -> lst::Diagnostic {
    fn convert_pos(pos: errors::position::Position) -> lst::Position {
        lst::Position {
            line: (pos.line - 1) as u64,
            character: (pos.column - 1) as u64,
        }
    }
    fn convert_range(range: errors::position::Span) -> lst::Range {
        lst::Range {
            start: convert_pos(range.start),
            end: convert_pos(range.end),
        }
    }
    lst::Diagnostic {
        range: convert_range(note.span),
        severity: Some(lst::DiagnosticSeverity::Error),
        code: None,
        source: Some("plank".into()),
        message: msg,
    }
}
<|endoftext|>