<commit_before>// Copyright 2014 Strahinja Val Markovic
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![feature(macro_rules)]
#![allow(non_snake_case_functions)]

#[cfg(not(test))]
pub use base::{Node, ParseState, Data, Children, NodeContents};

#[macro_escape]
mod base;

macro_rules! rule(
  (
    $name:ident <- $body:expr
  ) => (
    pub fn $name<'a>( parse_state: &base::ParseState<'a> )
         -> std::option::Option< base::ParseResult<'a> > {
      use base::Expression;
      use base::Node;
      use base::ParseResult;
      use std::clone::Clone;
      use std::option::{Some, None};

      match $body.apply( parse_state ) {
        Some( result ) => {
          let state = result.parse_state.clone();
          Some( ParseResult::oneNode(
              Node::withChildren( stringify!( $name ), result.nodes ), state ) )
        }
        _ => None
      }
    }
  );
)

#[cfg(not(test))]
pub fn parse<'a>( input: &'a [u8] ) -> Option< Node<'a> > {
  static root_name : &'static str = "NailgunRoot";
  let parse_state = ParseState { input: input, offset: 0 };
  match rules::Grammar( &parse_state ) {
    Some( result ) => Some( Node::withChildren( root_name, result.nodes ) ),
    _ => None
  }
}

mod rules {
  #![no_implicit_prelude]

  use base;
  use std;

  // RULES START

  rule!( Grammar <- seq!( ex!( Spacing ), plus!( ex!( Definition ) ), ex!( EndOfFile ) ) )
  rule!( Definition <- seq!( ex!( Identifier ), ex!( LEFTARROW ), ex!( Expression ) ) )
  rule!( Expression <- seq!( ex!( Sequence ), star!( seq!( ex!( SLASH ), ex!( Sequence ) ) ) ) )
  rule!( Sequence <- star!( ex!( Prefix ) ) )
  rule!( Prefix <- seq!( opt!( or!( ex!( AND ), ex!( NOT ) ) ), ex!( Suffix ) ) )
  rule!( Suffix <- seq!( ex!( Primary ), opt!( or!( ex!( QUESTION ), ex!( STAR ), ex!( PLUS ) ) ) ) )
  rule!( Primary <- or!( seq!( ex!( Identifier ), not!( ex!( LEFTARROW ) ) ), seq!( ex!( OPEN ), ex!( Expression ), ex!( CLOSE ) ), ex!( Literal ), ex!( Class ), ex!( DOT ) ) )
  rule!( Identifier <- seq!( ex!( IdentStart ), star!( ex!( IdentCont ) ), ex!( Spacing ) ) )
  rule!( IdentStart <- class!( "a-zA-Z_" ) )
  rule!( IdentCont <- or!( ex!( IdentStart ), class!( "0-9" ) ) )
  rule!( Literal <- or!( seq!( class!( "'" ), star!( seq!( not!( class!( "'" ) ), ex!( Char ) ) ), class!( "'" ), ex!( Spacing ) ), seq!( class!( "\"" ), star!( seq!( not!( class!( "\"" ) ), ex!( Char ) ) ), class!( "\"" ), ex!( Spacing ) ) ) )
  rule!( Class <- seq!( lit!( "[" ), star!( seq!( not!( lit!( "]" ) ), ex!( Range ) ) ), lit!( "]" ), ex!( Spacing ) ) )
  rule!( Range <- or!( seq!( ex!( Char ), lit!( "-" ), ex!( Char ) ), ex!( Char ) ) )
  rule!( Char <- or!( seq!( lit!( "\\" ), class!( "nrt'\"[]\\" ) ), seq!( lit!( "\\" ), class!( "0-2" ), class!( "0-7" ), class!( "0-7" ) ), seq!( lit!( "\\" ), class!( "0-7" ), opt!( class!( "0-7" ) ) ), seq!( not!( lit!( "\\" ) ), base::Dot ) ) )
  rule!( LEFTARROW <- seq!( lit!( "<-" ), ex!( Spacing ) ) )
  rule!( SLASH <- seq!( lit!( "/" ), ex!( Spacing ) ) )
  rule!( AND <- seq!( lit!( "&" ), ex!( Spacing ) ) )
  rule!( NOT <- seq!( lit!( "!" ), ex!( Spacing ) ) )
  rule!( QUESTION <- seq!( lit!( "?" ), ex!( Spacing ) ) )
  rule!( STAR <- seq!( lit!( "*" ), ex!( Spacing ) ) )
  rule!( PLUS <- seq!( lit!( "+" ), ex!( Spacing ) ) )
  rule!( OPEN <- seq!( lit!( "(" ), ex!( Spacing ) ) )
  rule!( CLOSE <- seq!( lit!( ")" ), ex!( Spacing ) ) )
  rule!( DOT <- seq!( lit!( "." ), ex!( Spacing ) ) )
  rule!( Spacing <- star!( or!( ex!( Space ), ex!( Comment ) ) ) )
  rule!( Comment <- seq!( lit!( "#" ), star!( seq!( not!( ex!( EndOfLine ) ), base::Dot ) ), ex!( EndOfLine ) ) )
  rule!( Space <- or!( lit!( " " ), lit!( "\t" ), ex!( EndOfLine ) ) )
  rule!( EndOfLine <- or!( lit!( "\r\n" ), lit!( "\n" ), lit!( "\r" ) ) )
  rule!( EndOfFile <- not!( base::Dot ) )

  // RULES END

  #[cfg(test)]
  mod tests {
    use super::{EndOfFile, EndOfLine, Space, Comment, Spacing, Char, Range,
                Class, Literal, Identifier, Definition, Grammar};

    macro_rules! consumes(
      (
        $name:ident, $input:expr
      ) => (
        {
          use base::ParseResult;
          use std::option::Some;
          use std::collections::Collection;

          match $name( &input_state!( $input ) ) {
            Some( ParseResult{ nodes: _,
                              parse_state: parse_state } ) => {
              parse_state.input.is_empty()
            }
            _ => false
          }
        }
      );
    )

    macro_rules! matches(
      (
        $name:ident, $input:expr
      ) => (
        $name( &input_state!( $input ) ).is_some()
      );
    )

    #[test]
    fn Grammar_Works() {
      assert!( consumes!( Grammar,
                          r#"
        h16           <- HEXDIGIT (HEXDIGIT (HEXDIGIT HEXDIGIT?)?)?
        ls32          <- h16 ":" h16 / IPv4address
        IPv4address   <- dec_octet "." dec_octet "." dec_octet "." dec_octet"#
        ) )
    }

    #[test]
    fn Definition_Works() {
      assert!( consumes!( Definition,
                          "Grammar <- Spacing Definition+ EndOfFile" ) )
      assert!( consumes!( Definition,
                          r#"Char <- '\\' [nrt'"\[\]\\] /
                                    '\\' [0-2][0-7][0-7] /
                                    '\\' [0-7][0-7]? /
                                    !'\\' ."# ) )
    }

    #[test]
    fn Identifier_Works() {
      assert!( consumes!( Identifier, "abc" ) );
      assert!( consumes!( Identifier, "a" ) );
      assert!( consumes!( Identifier, "_" ) );
      assert!( consumes!( Identifier, "a123" ) );
      assert!( consumes!( Identifier, "a  \n" ) );

      assert!( !consumes!( Identifier, "1a" ) );
      assert!( !consumes!( Identifier, "1" ) );
      assert!( !consumes!( Identifier, "Ć" ) );
    }

    #[test]
    fn Literal_Works() {
      assert!( consumes!( Literal, "'abc'" ) );
      assert!( consumes!( Literal, r#""abc""# ) );
      assert!( consumes!( Literal, "'abc'  \n" ) );
      assert!( !consumes!( Literal, "'abc''bb'" ) );
    }

    #[test]
    fn Class_Works() {
      assert!( consumes!( Class, "[a-z]" ) );
      assert!( consumes!( Class, "[a-z]  \n" ) );
      assert!( consumes!( Class, "[abc]" ) );
      assert!( consumes!( Class, "[abc0-9g]" ) );
    }

    #[test]
    fn Range_Works() {
      assert!( consumes!( Range, "a-z" ) );
      assert!( consumes!( Range, "a" ) );
    }

    #[test]
    fn Char_Works() {
      assert!( consumes!( Char, r"\n" ) );
      assert!( consumes!( Char, r"\]" ) );
      assert!( consumes!( Char, r"\\" ) );
      assert!( consumes!( Char, r"\'" ) );
      assert!( consumes!( Char, "a" ) );
      assert!( consumes!( Char, "x" ) );
      assert!( consumes!( Char, "Ć" ) );
      assert!( consumes!( Char, "€" ) );
      assert!( consumes!( Char, r"\277" ) );
      assert!( consumes!( Char, r"\77" ) );
      assert!( consumes!( Char, r"\7" ) );

      assert!( !consumes!( Char, "aa" ) );
    }

    #[test]
    fn Spacing_Works() {
      assert!( consumes!( Spacing, "  \t #g\n" ) );
      assert!( consumes!( Spacing, "#a\n  #1\n" ) );

      // Spacing DOES match here because at the top level, it is a star
      // expression which can match consuming nothing.
      assert!( matches!( Spacing, "" ) );
      assert!( !consumes!( Spacing, "#" ) );
      assert!( !consumes!( Spacing, "a" ) );
    }

    #[test]
    fn Comment_Works() {
      assert!( consumes!( Comment, "#\n" ) );
      assert!( consumes!( Comment, "# foo! \n" ) );
      assert!( !matches!( Comment, "\n" ) );
      assert!( !matches!( Comment, "#" ) );
      assert!( !matches!( Comment, "a" ) );
    }

    #[test]
    fn Space_Works() {
      assert!( consumes!( Space, " " ) );
      assert!( consumes!( Space, "\t" ) );
      assert!( consumes!( Space, "\n" ) );
      assert!( !matches!( Space, "a" ) );
    }

    #[test]
    fn EndOfLine_Works() {
      assert!( consumes!( EndOfLine, "\n" ) );
      assert!( consumes!( EndOfLine, "\r" ) );
      assert!( consumes!( EndOfLine, "\r\n" ) );
      assert!( !matches!( EndOfLine, "a" ) );
    }

    #[test]
    fn EndOfFile_Works() {
      assert!( consumes!( EndOfFile, "" ) );
      assert!( !matches!( EndOfFile, "a" ) );
    }
  }
}
<commit_msg>Adding extra pub use to silence warning<commit_after>// Copyright 2014 Strahinja Val Markovic
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
#![feature(macro_rules)]
#![allow(non_snake_case_functions)]

#[cfg(not(test))]
pub use base::{Node, ParseState, Data, Children, NodeContents, PreOrderNodes};

#[macro_escape]
mod base;

macro_rules! rule(
  (
    $name:ident <- $body:expr
  ) => (
    pub fn $name<'a>( parse_state: &base::ParseState<'a> )
         -> std::option::Option< base::ParseResult<'a> > {
      use base::Expression;
      use base::Node;
      use base::ParseResult;
      use std::clone::Clone;
      use std::option::{Some, None};

      match $body.apply( parse_state ) {
        Some( result ) => {
          let state = result.parse_state.clone();
          Some( ParseResult::oneNode(
              Node::withChildren( stringify!( $name ), result.nodes ), state ) )
        }
        _ => None
      }
    }
  );
)

#[cfg(not(test))]
pub fn parse<'a>( input: &'a [u8] ) -> Option< Node<'a> > {
  static root_name : &'static str = "NailgunRoot";
  let parse_state = ParseState { input: input, offset: 0 };
  match rules::Grammar( &parse_state ) {
    Some( result ) => Some( Node::withChildren( root_name, result.nodes ) ),
    _ => None
  }
}

mod rules {
  #![no_implicit_prelude]

  use base;
  use std;

  // RULES START

  rule!( Grammar <- seq!( ex!( Spacing ), plus!( ex!( Definition ) ), ex!( EndOfFile ) ) )
  rule!( Definition <- seq!( ex!( Identifier ), ex!( LEFTARROW ), ex!( Expression ) ) )
  rule!( Expression <- seq!( ex!( Sequence ), star!( seq!( ex!( SLASH ), ex!( Sequence ) ) ) ) )
  rule!( Sequence <- star!( ex!( Prefix ) ) )
  rule!( Prefix <- seq!( opt!( or!( ex!( AND ), ex!( NOT ) ) ), ex!( Suffix ) ) )
  rule!( Suffix <- seq!( ex!( Primary ), opt!( or!( ex!( QUESTION ), ex!( STAR ), ex!( PLUS ) ) ) ) )
  rule!( Primary <- or!( seq!( ex!( Identifier ), not!( ex!( LEFTARROW ) ) ), seq!( ex!( OPEN ), ex!( Expression ), ex!( CLOSE ) ), ex!( Literal ), ex!( Class ), ex!( DOT ) ) )
  rule!( Identifier <- seq!( ex!( IdentStart ), star!( ex!( IdentCont ) ), ex!( Spacing ) ) )
  rule!( IdentStart <- class!( "a-zA-Z_" ) )
  rule!( IdentCont <- or!( ex!( IdentStart ), class!( "0-9" ) ) )
  rule!( Literal <- or!( seq!( class!( "'" ), star!( seq!( not!( class!( "'" ) ), ex!( Char ) ) ), class!( "'" ), ex!( Spacing ) ), seq!( class!( "\"" ), star!( seq!( not!( class!( "\"" ) ), ex!( Char ) ) ), class!( "\"" ), ex!( Spacing ) ) ) )
  rule!( Class <- seq!( lit!( "[" ), star!( seq!( not!( lit!( "]" ) ), ex!( Range ) ) ), lit!( "]" ), ex!( Spacing ) ) )
  rule!( Range <- or!( seq!( ex!( Char ), lit!( "-" ), ex!( Char ) ), ex!( Char ) ) )
  rule!( Char <- or!( seq!( lit!( "\\" ), class!( "nrt'\"[]\\" ) ), seq!( lit!( "\\" ), class!( "0-2" ), class!( "0-7" ), class!( "0-7" ) ), seq!( lit!( "\\" ), class!( "0-7" ), opt!( class!( "0-7" ) ) ), seq!( not!( lit!( "\\" ) ), base::Dot ) ) )
  rule!( LEFTARROW <- seq!( lit!( "<-" ), ex!( Spacing ) ) )
  rule!( SLASH <- seq!( lit!( "/" ), ex!( Spacing ) ) )
  rule!( AND <- seq!( lit!( "&" ), ex!( Spacing ) ) )
  rule!( NOT <- seq!( lit!( "!" ), ex!( Spacing ) ) )
  rule!( QUESTION <- seq!( lit!( "?" ), ex!( Spacing ) ) )
  rule!( STAR <- seq!( lit!( "*" ), ex!( Spacing ) ) )
  rule!( PLUS <- seq!( lit!( "+" ), ex!( Spacing ) ) )
  rule!( OPEN <- seq!( lit!( "(" ), ex!( Spacing ) ) )
  rule!( CLOSE <- seq!( lit!( ")" ), ex!( Spacing ) ) )
  rule!( DOT <- seq!( lit!( "." ), ex!( Spacing ) ) )
  rule!( Spacing <- star!( or!( ex!( Space ), ex!( Comment ) ) ) )
  rule!( Comment <- seq!( lit!( "#" ), star!( seq!( not!( ex!( EndOfLine ) ), base::Dot ) ), ex!( EndOfLine ) ) )
  rule!( Space <- or!( lit!( " " ), lit!( "\t" ), ex!( EndOfLine ) ) )
  rule!( EndOfLine <- or!( lit!( "\r\n" ), lit!( "\n" ), lit!( "\r" ) ) )
  rule!( EndOfFile <- not!( base::Dot ) )

  // RULES END

  #[cfg(test)]
  mod tests {
    use super::{EndOfFile, EndOfLine, Space, Comment, Spacing, Char, Range,
                Class, Literal, Identifier, Definition, Grammar};

    macro_rules! consumes(
      (
        $name:ident, $input:expr
      ) => (
        {
          use base::ParseResult;
          use std::option::Some;
          use std::collections::Collection;

          match $name( &input_state!( $input ) ) {
            Some( ParseResult{ nodes: _,
                              parse_state: parse_state } ) => {
              parse_state.input.is_empty()
            }
            _ => false
          }
        }
      );
    )

    macro_rules! matches(
      (
        $name:ident, $input:expr
      ) => (
        $name( &input_state!( $input ) ).is_some()
      );
    )

    #[test]
    fn Grammar_Works() {
      assert!( consumes!( Grammar,
                          r#"
        h16           <- HEXDIGIT (HEXDIGIT (HEXDIGIT HEXDIGIT?)?)?
        ls32          <- h16 ":" h16 / IPv4address
        IPv4address   <- dec_octet "." dec_octet "." dec_octet "." dec_octet"#
        ) )
    }

    #[test]
    fn Definition_Works() {
      assert!( consumes!( Definition,
                          "Grammar <- Spacing Definition+ EndOfFile" ) )
      assert!( consumes!( Definition,
                          r#"Char <- '\\' [nrt'"\[\]\\] /
                                    '\\' [0-2][0-7][0-7] /
                                    '\\' [0-7][0-7]? /
                                    !'\\' ."# ) )
    }

    #[test]
    fn Identifier_Works() {
      assert!( consumes!( Identifier, "abc" ) );
      assert!( consumes!( Identifier, "a" ) );
      assert!( consumes!( Identifier, "_" ) );
      assert!( consumes!( Identifier, "a123" ) );
      assert!( consumes!( Identifier, "a  \n" ) );

      assert!( !consumes!( Identifier, "1a" ) );
      assert!( !consumes!( Identifier, "1" ) );
      assert!( !consumes!( Identifier, "Ć" ) );
    }

    #[test]
    fn Literal_Works() {
      assert!( consumes!( Literal, "'abc'" ) );
      assert!( consumes!( Literal, r#""abc""# ) );
      assert!( consumes!( Literal, "'abc'  \n" ) );
      assert!( !consumes!( Literal, "'abc''bb'" ) );
    }

    #[test]
    fn Class_Works() {
      assert!( consumes!( Class, "[a-z]" ) );
      assert!( consumes!( Class, "[a-z]  \n" ) );
      assert!( consumes!( Class, "[abc]" ) );
      assert!( consumes!( Class, "[abc0-9g]" ) );
    }

    #[test]
    fn Range_Works() {
      assert!( consumes!( Range, "a-z" ) );
      assert!( consumes!( Range, "a" ) );
    }

    #[test]
    fn Char_Works() {
      assert!( consumes!( Char, r"\n" ) );
      assert!( consumes!( Char, r"\]" ) );
      assert!( consumes!( Char, r"\\" ) );
      assert!( consumes!( Char, r"\'" ) );
      assert!( consumes!( Char, "a" ) );
      assert!( consumes!( Char, "x" ) );
      assert!( consumes!( Char, "Ć" ) );
      assert!( consumes!( Char, "€" ) );
      assert!( consumes!( Char, r"\277" ) );
      assert!( consumes!( Char, r"\77" ) );
      assert!( consumes!( Char, r"\7" ) );

      assert!( !consumes!( Char, "aa" ) );
    }

    #[test]
    fn Spacing_Works() {
      assert!( consumes!( Spacing, "  \t #g\n" ) );
      assert!( consumes!( Spacing, "#a\n  #1\n" ) );

      // Spacing DOES match here because at the top level, it is a star
      // expression which can match consuming nothing.
      assert!( matches!( Spacing, "" ) );
      assert!( !consumes!( Spacing, "#" ) );
      assert!( !consumes!( Spacing, "a" ) );
    }

    #[test]
    fn Comment_Works() {
      assert!( consumes!( Comment, "#\n" ) );
      assert!( consumes!( Comment, "# foo! \n" ) );
      assert!( !matches!( Comment, "\n" ) );
      assert!( !matches!( Comment, "#" ) );
      assert!( !matches!( Comment, "a" ) );
    }

    #[test]
    fn Space_Works() {
      assert!( consumes!( Space, " " ) );
      assert!( consumes!( Space, "\t" ) );
      assert!( consumes!( Space, "\n" ) );
      assert!( !matches!( Space, "a" ) );
    }

    #[test]
    fn EndOfLine_Works() {
      assert!( consumes!( EndOfLine, "\n" ) );
      assert!( consumes!( EndOfLine, "\r" ) );
      assert!( consumes!( EndOfLine, "\r\n" ) );
      assert!( !matches!( EndOfLine, "a" ) );
    }

    #[test]
    fn EndOfFile_Works() {
      assert!( consumes!( EndOfFile, "" ) );
      assert!( !matches!( EndOfFile, "a" ) );
    }
  }
}
<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLSelectElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLSelectElementDerived;
use dom::bindings::codegen::UnionTypes::{HTMLElementOrLong, HTMLOptionElementOrHTMLOptGroupElement};
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLSelectElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::HTMLFormElement;
use dom::node::{Node, ElementNodeTypeId, window_from_node};
use dom::htmloptionelement::HTMLOptionElement;
use dom::validitystate::ValidityState;
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLSelectElement {
    pub htmlelement: HTMLElement
}

impl HTMLSelectElementDerived for EventTarget {
    fn is_htmlselectelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLSelectElementTypeId))
    }
}

impl HTMLSelectElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLSelectElement {
        HTMLSelectElement {
            htmlelement: HTMLElement::new_inherited(HTMLSelectElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLSelectElement> {
        let element = HTMLSelectElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLSelectElementBinding::Wrap)
    }
}

pub trait HTMLSelectElementMethods {
    fn Autofocus(&self) -> bool;
    fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult;
    fn Disabled(&self) -> bool;
    fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult;
    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>;
    fn Multiple(&self) -> bool;
    fn SetMultiple(&mut self, _multiple: bool) -> ErrorResult;
    fn Name(&self) -> DOMString;
    fn SetName(&mut self, _name: DOMString) -> ErrorResult;
    fn Required(&self) -> bool;
    fn SetRequired(&mut self, _multiple: bool) -> ErrorResult;
    fn Size(&self) -> u32;
    fn SetSize(&mut self, _size: u32) -> ErrorResult;
    fn Type(&self) -> DOMString;
    fn Length(&self) -> u32;
    fn SetLength(&mut self, _length: u32) -> ErrorResult;
    fn Item(&self, _index: u32) -> Option<Temporary<Element>>;
    fn NamedItem(&self, _name: DOMString) -> Option<Temporary<HTMLOptionElement>>;
    fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Temporary<Element>>;
    fn IndexedSetter(&mut self, _index: u32, _option: Option<JSRef<HTMLOptionElement>>) -> ErrorResult;
    fn Remove_(&self);
    fn Remove(&self, _index: i32);
    fn SelectedIndex(&self) -> i32;
    fn SetSelectedIndex(&mut self, _index: i32) -> ErrorResult;
    fn Value(&self) -> DOMString;
    fn SetValue(&mut self, _value: DOMString);
    fn WillValidate(&self) -> bool;
    fn SetWillValidate(&mut self, _will_validate: bool);
    fn Validity(&self) -> Temporary<ValidityState>;
    fn ValidationMessage(&self) -> DOMString;
    fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult;
    fn CheckValidity(&self) -> bool;
    fn SetCustomValidity(&mut self, _error: DOMString);
    fn Add(&self, _element: HTMLOptionElementOrHTMLOptGroupElement, _before: Option<HTMLElementOrLong>) -> ErrorResult;
}

impl<'a> HTMLSelectElementMethods for JSRef<'a, HTMLSelectElement> {
    fn Autofocus(&self) -> bool {
        false
    }

    fn SetAutofocus(&mut self, _autofocus: bool) -> ErrorResult {
        Ok(())
    }

    fn Disabled(&self) -> bool {
        false
    }

    fn SetDisabled(&mut self, _disabled: bool) -> ErrorResult {
        Ok(())
    }

    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> {
        None
    }

    fn Multiple(&self) -> bool {
        false
    }

    fn SetMultiple(&mut self, _multiple: bool) -> ErrorResult {
        Ok(())
    }

    fn Name(&self) -> DOMString {
        "".to_owned()
    }

    fn SetName(&mut self, _name: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Required(&self) -> bool {
        false
    }

    fn SetRequired(&mut self, _multiple: bool) -> ErrorResult {
        Ok(())
    }

    fn Size(&self) -> u32 {
        0
    }

    fn SetSize(&mut self, _size: u32) -> ErrorResult {
        Ok(())
    }

    fn Type(&self) -> DOMString {
        "".to_owned()
    }

    fn Length(&self) -> u32 {
        0
    }

    fn SetLength(&mut self, _length: u32) -> ErrorResult {
        Ok(())
    }

    fn Item(&self, _index: u32) -> Option<Temporary<Element>> {
        None
    }

    fn NamedItem(&self, _name: DOMString) -> Option<Temporary<HTMLOptionElement>> {
        None
    }

    fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Temporary<Element>> {
        None
    }

    fn IndexedSetter(&mut self, _index: u32, _option: Option<JSRef<HTMLOptionElement>>) -> ErrorResult {
        Ok(())
    }

    fn Remove_(&self) {
    }

    fn Remove(&self, _index: i32) {
    }

    fn SelectedIndex(&self) -> i32 {
        0
    }

    fn SetSelectedIndex(&mut self, _index: i32) -> ErrorResult {
        Ok(())
    }

    fn Value(&self) -> DOMString {
        "".to_owned()
    }

    fn SetValue(&mut self, _value: DOMString) {
    }

    fn WillValidate(&self) -> bool {
        false
    }

    fn SetWillValidate(&mut self, _will_validate: bool) {
    }

    fn Validity(&self) -> Temporary<ValidityState> {
        let window = window_from_node(self).root();
        ValidityState::new(&*window)
    }

    fn ValidationMessage(&self) -> DOMString {
        "".to_owned()
    }

    fn SetValidationMessage(&mut self, _message: DOMString) -> ErrorResult {
        Ok(())
    }

    fn CheckValidity(&self) -> bool {
        true
    }

    fn SetCustomValidity(&mut self, _error: DOMString) {
    }

    fn Add(&self, _element: HTMLOptionElementOrHTMLOptGroupElement, _before: Option<HTMLElementOrLong>) -> ErrorResult {
        Ok(())
    }
}
<commit_msg>Remove needless '&mut self' from HTMLSelectElementMethods.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use dom::bindings::codegen::BindingDeclarations::HTMLSelectElementBinding;
use dom::bindings::codegen::InheritTypes::HTMLSelectElementDerived;
use dom::bindings::codegen::UnionTypes::{HTMLElementOrLong, HTMLOptionElementOrHTMLOptGroupElement};
use dom::bindings::js::{JSRef, Temporary};
use dom::bindings::error::ErrorResult;
use dom::document::Document;
use dom::element::{Element, HTMLSelectElementTypeId};
use dom::eventtarget::{EventTarget, NodeTargetTypeId};
use dom::htmlelement::HTMLElement;
use dom::htmlformelement::HTMLFormElement;
use dom::node::{Node, ElementNodeTypeId, window_from_node};
use dom::htmloptionelement::HTMLOptionElement;
use dom::validitystate::ValidityState;
use servo_util::str::DOMString;

#[deriving(Encodable)]
pub struct HTMLSelectElement {
    pub htmlelement: HTMLElement
}

impl HTMLSelectElementDerived for EventTarget {
    fn is_htmlselectelement(&self) -> bool {
        self.type_id == NodeTargetTypeId(ElementNodeTypeId(HTMLSelectElementTypeId))
    }
}

impl HTMLSelectElement {
    pub fn new_inherited(localName: DOMString, document: &JSRef<Document>) -> HTMLSelectElement {
        HTMLSelectElement {
            htmlelement: HTMLElement::new_inherited(HTMLSelectElementTypeId, localName, document)
        }
    }

    pub fn new(localName: DOMString, document: &JSRef<Document>) -> Temporary<HTMLSelectElement> {
        let element = HTMLSelectElement::new_inherited(localName, document);
        Node::reflect_node(box element, document, HTMLSelectElementBinding::Wrap)
    }
}

pub trait HTMLSelectElementMethods {
    fn Autofocus(&self) -> bool;
    fn SetAutofocus(&self, _autofocus: bool) -> ErrorResult;
    fn Disabled(&self) -> bool;
    fn SetDisabled(&self, _disabled: bool) -> ErrorResult;
    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>>;
    fn Multiple(&self) -> bool;
    fn SetMultiple(&self, _multiple: bool) -> ErrorResult;
    fn Name(&self) -> DOMString;
    fn SetName(&self, _name: DOMString) -> ErrorResult;
    fn Required(&self) -> bool;
    fn SetRequired(&self, _multiple: bool) -> ErrorResult;
    fn Size(&self) -> u32;
    fn SetSize(&self, _size: u32) -> ErrorResult;
    fn Type(&self) -> DOMString;
    fn Length(&self) -> u32;
    fn SetLength(&self, _length: u32) -> ErrorResult;
    fn Item(&self, _index: u32) -> Option<Temporary<Element>>;
    fn NamedItem(&self, _name: DOMString) -> Option<Temporary<HTMLOptionElement>>;
    fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Temporary<Element>>;
    fn IndexedSetter(&self, _index: u32, _option: Option<JSRef<HTMLOptionElement>>) -> ErrorResult;
    fn Remove_(&self);
    fn Remove(&self, _index: i32);
    fn SelectedIndex(&self) -> i32;
    fn SetSelectedIndex(&self, _index: i32) -> ErrorResult;
    fn Value(&self) -> DOMString;
    fn SetValue(&self, _value: DOMString);
    fn WillValidate(&self) -> bool;
    fn SetWillValidate(&self, _will_validate: bool);
    fn Validity(&self) -> Temporary<ValidityState>;
    fn ValidationMessage(&self) -> DOMString;
    fn SetValidationMessage(&self, _message: DOMString) -> ErrorResult;
    fn CheckValidity(&self) -> bool;
    fn SetCustomValidity(&self, _error: DOMString);
    fn Add(&self, _element: HTMLOptionElementOrHTMLOptGroupElement, _before: Option<HTMLElementOrLong>) -> ErrorResult;
}

impl<'a> HTMLSelectElementMethods for JSRef<'a, HTMLSelectElement> {
    fn Autofocus(&self) -> bool {
        false
    }

    fn SetAutofocus(&self, _autofocus: bool) -> ErrorResult {
        Ok(())
    }

    fn Disabled(&self) -> bool {
        false
    }

    fn SetDisabled(&self, _disabled: bool) -> ErrorResult {
        Ok(())
    }

    fn GetForm(&self) -> Option<Temporary<HTMLFormElement>> {
        None
    }

    fn Multiple(&self) -> bool {
        false
    }

    fn SetMultiple(&self, _multiple: bool) -> ErrorResult {
        Ok(())
    }

    fn Name(&self) -> DOMString {
        "".to_owned()
    }

    fn SetName(&self, _name: DOMString) -> ErrorResult {
        Ok(())
    }

    fn Required(&self) -> bool {
        false
    }

    fn SetRequired(&self, _multiple: bool) -> ErrorResult {
        Ok(())
    }

    fn Size(&self) -> u32 {
        0
    }

    fn SetSize(&self, _size: u32) -> ErrorResult {
        Ok(())
    }

    fn Type(&self) -> DOMString {
        "".to_owned()
    }

    fn Length(&self) -> u32 {
        0
    }

    fn SetLength(&self, _length: u32) -> ErrorResult {
        Ok(())
    }

    fn Item(&self, _index: u32) -> Option<Temporary<Element>> {
        None
    }

    fn NamedItem(&self, _name: DOMString) -> Option<Temporary<HTMLOptionElement>> {
        None
    }

    fn IndexedGetter(&self, _index: u32, _found: &mut bool) -> Option<Temporary<Element>> {
        None
    }

    fn IndexedSetter(&self, _index: u32, _option: Option<JSRef<HTMLOptionElement>>) -> ErrorResult {
        Ok(())
    }

    fn Remove_(&self) {
    }

    fn Remove(&self, _index: i32) {
    }

    fn SelectedIndex(&self) -> i32 {
        0
    }

    fn SetSelectedIndex(&self, _index: i32) -> ErrorResult {
        Ok(())
    }

    fn Value(&self) -> DOMString {
        "".to_owned()
    }

    fn SetValue(&self, _value: DOMString) {
    }

    fn WillValidate(&self) -> bool {
        false
    }

    fn SetWillValidate(&self, _will_validate: bool) {
    }

    fn Validity(&self) -> Temporary<ValidityState> {
        let window = window_from_node(self).root();
        ValidityState::new(&*window)
    }

    fn ValidationMessage(&self) -> DOMString {
        "".to_owned()
    }

    fn SetValidationMessage(&self, _message: DOMString) -> ErrorResult {
        Ok(())
    }

    fn CheckValidity(&self) -> bool {
        true
    }

    fn SetCustomValidity(&self, _error: DOMString) {
    }

    fn Add(&self, _element: HTMLOptionElementOrHTMLOptGroupElement, _before: Option<HTMLElementOrLong>) -> ErrorResult {
        Ok(())
    }
}
<|endoftext|>


<commit_before>//! Utility class to communicate between agents
//!
//! This class provides three structs : IP, Ports and IPSender.

extern crate capnp;
#[allow(unused_imports)]
use std::io::Read;

use result;
use result::Result;

use std::collections::HashMap;
use std::mem;

use std::sync::mpsc::{Sender, Receiver, SyncSender};
use std::sync::mpsc::sync_channel;

use scheduler::CompMsg;

/// Represent an IP
pub struct IP {
    /// The capn'p representation
    pub vec: Vec<u8>,
    /// is the action of the IP
    pub action: String,
    reader: Option<capnp::message::Reader<capnp::serialize::OwnedSegments>>,
    builder: Option<capnp::message::Builder<capnp::message::HeapAllocator>>,
}

impl IP {
    /// Return a new IP
    ///
    /// # Example
    /// ```rust,ignore
    /// let ip = IP::new();
    /// ```
    pub fn new() -> Self {
        IP { vec: vec![],
             action: String::new(),
             reader: None,
             builder: None,
        }
    }

    /// Return a capnp `Reader`
    ///
    /// # Example
    ///
    /// ```rust,ignore
    /// let ip = an_initialized_ip;
    /// {
    ///     let reader: generic_text::Reader = try!(ip.read_schema());
    ///     let text = try!(reader.get_text());
    /// }
    /// ```
    pub fn read_schema<'a, T: capnp::traits::FromPointerReader<'a>>(&'a mut self) -> Result<T> {
        let msg = try!(capnp::serialize::read_message(&mut &self.vec[..], capnp::message::ReaderOptions::new()));
        self.reader = Some(msg);
        Ok(try!(self.reader.as_ref().unwrap().get_root()))
    }

    /// Return a capnp `Builder`
    ///
    /// # Example
    ///
    /// ```rust,ignore
    /// let mut ip = IP::new();
    /// // Initialize the IP
    /// {
    ///     let mut builder: generic_text::Builder = ip.build_schema();
    ///     builder.set_text("Hello Fractalide!");
    /// }
    /// ```
    pub fn build_schema<'a, T: capnp::traits::FromPointerBuilder<'a>>(&'a mut self) -> T {
        let msg = capnp::message::Builder::new_default();
        self.builder = Some(msg);
        self.builder.as_mut().unwrap().init_root()
    }

    /// Return a capnp `Builder` from a capnp `Reader`
    ///
    /// # Example
    ///
    /// ```rust,ignore
    /// let mut ip = an_initialized_ip;
    /// {
    ///     let mut builder = try!(edit_edge::<generic_text::Builder, generic_text::Reader>());
    ///     builder.set_text("Hello Fractalide!");
    /// }
    /// ```
    pub fn edit_schema<'a, T: capnp::traits::FromPointerBuilder<'a>,
                                 U: capnp::traits::FromPointerReader<'a> + capnp::traits::SetPointerBuilder<T>>
        (&'a mut self) -> Result<T> {
        let reader = try!(capnp::serialize::read_message(&mut &self.vec[..], capnp::message::ReaderOptions::new()));
        self.reader = Some(reader);
        let reader: U = try!(self.reader.as_ref().unwrap().get_root());

        let mut msg = capnp::message::Builder::new_default();
        try!(msg.set_root(reader));
        self.builder = Some(msg);
        Ok(try!(self.builder.as_mut().unwrap().get_root()))
    }

    /// Write a capnp `Builder` to a `Vec`
    ///
    /// # Example
    ///
    /// ```rust,ignore
    /// let mut ip = an_initialized_ip;
    /// {
    ///     let mut builder = try!(edit_edge::<generic_text::Builder, generic_text::Reader>());
    ///     builder.set_text("Hello Fractalide!");
    /// }
    /// try!(ip.before_send());
    /// ```
    pub fn before_send(&mut self) -> Result<()> {
        let mut build = mem::replace(&mut self.builder, None);
        if let Some(ref mut b) = build {
            self.vec.clear();
            try!(capnp::serialize::write_message(&mut self.vec, b))
        }
        Ok(())

    }
}

impl Clone for IP {
    fn clone(&self) -> Self {
        IP {
            vec: self.vec.clone(),
            action: self.action.clone(),
            reader: None,
            builder: None,
        }
    }
}

/// A wrapper around `SyncSender<IP>`
///
/// A specific `SyncSender` for the IP object. It also sends information to the scheduler.
#[derive(Clone)]
pub struct IPSender {
    /// The SyncSender, connected to a receiver in another agent
    pub sender: SyncSender<IP>,
    /// The name of the agent owning the receiver
    pub dest: String,
    /// A Sender to the scheduler, to signal that the receiver must be run
    pub sched: Sender<CompMsg>,
}

impl IPSender {
    /// Send an IP to the Receiver
    pub fn send(&self, mut ip: IP) -> Result<()> {
        try!(ip.before_send());
        try!(self.sender.send(ip));
        if self.dest != "" {
            try!(self.sched.send(CompMsg::Inc(self.dest.clone())));
        }
        Ok(())
    }
}

}

        } else {
        }
    }

pub struct IPReceiver {
    name: String,
    recv: Receiver<IP>,
    sched: Sender<CompMsg>,
    must_sched: bool,
}

impl IPReceiver {
    pub fn new(name: String, sched: Sender<CompMsg>, must_sched: bool) -> (IPReceiver, IPSender) {
        let (s, r) = sync_channel(25);
        let s = IPSender {
            sender: s,
            dest: if must_sched { name.clone() } else { "".into() },
            sched: sched.clone(),
        };
        let r = IPReceiver {
            recv: r,
            name: name,
            sched: sched,
            must_sched: must_sched,
        };
        (r, s)
    }

    pub fn recv(&self) -> Result<IP> {
        let ip = try!(self.recv.recv());
        if self.must_sched {
            try!(self.sched.send(CompMsg::Dec(self.name.clone())));
        }
        Ok(ip)
    }

    pub fn try_recv(&self) -> Result<IP> {
        let ip = self.recv.try_recv()?;
        if self.must_sched {
            try!(self.sched.send(CompMsg::Dec(self.name.clone())));
        }
        Ok(ip)
    }
}
<commit_msg>Add a trait `OutputSend`<commit_after>//! Utility class to communicate between agents
//!
//! This class provides three structs : IP, Ports and IPSender.

extern crate capnp;
#[allow(unused_imports)]
use std::io::Read;

use result;
use result::Result;

use std::collections::HashMap;
use std::mem;

use std::sync::mpsc::{Sender, Receiver, SyncSender};
use std::sync::mpsc::sync_channel;

use scheduler::CompMsg;

/// Represent an IP
pub struct IP {
    /// The capn'p representation
    pub vec: Vec<u8>,
    /// is the action of the IP
    pub action: String,
    reader: Option<capnp::message::Reader<capnp::serialize::OwnedSegments>>,
    builder: Option<capnp::message::Builder<capnp::message::HeapAllocator>>,
}

impl IP {
    /// Return a new IP
    ///
    /// # Example
    /// ```rust,ignore
    /// let ip = IP::new();
    /// ```
    pub fn new() -> Self {
        IP { vec: vec![],
             action: String::new(),
             reader: None,
             builder: None,
        }
    }

    /// Return a capnp `Reader`
    ///
    /// # Example
    ///
    /// ```rust,ignore
    /// let ip = an_initialized_ip;
    /// {
    ///     let reader: generic_text::Reader = try!(ip.read_schema());
    ///     let text = try!(reader.get_text());
    /// }
    /// ```
    pub fn read_schema<'a, T: capnp::traits::FromPointerReader<'a>>(&'a mut self) -> Result<T> {
        let msg = try!(capnp::serialize::read_message(&mut &self.vec[..], capnp::message::ReaderOptions::new()));
        self.reader = Some(msg);
        Ok(try!(self.reader.as_ref().unwrap().get_root()))
    }

    /// Return a capnp `Builder`
    ///
    /// # Example
    ///
    /// ```rust,ignore
    /// let mut ip = IP::new();
    /// // Initialize the IP
    /// {
    ///     let mut builder: generic_text::Builder = ip.build_schema();
    ///     builder.set_text("Hello Fractalide!");
    /// }
    /// ```
    pub fn build_schema<'a, T: capnp::traits::FromPointerBuilder<'a>>(&'a mut self) -> T {
        let msg = capnp::message::Builder::new_default();
        self.builder = Some(msg);
        self.builder.as_mut().unwrap().init_root()
    }

    /// Return a capnp `Builder` from a capnp `Reader`
    ///
    /// # Example
    ///
    /// ```rust,ignore
    /// let mut ip = an_initialized_ip;
    /// {
    ///     let mut builder = try!(edit_edge::<generic_text::Builder, generic_text::Reader>());
    ///     builder.set_text("Hello Fractalide!");
    /// }
    /// ```
    pub fn edit_schema<'a, T: capnp::traits::FromPointerBuilder<'a>,
                                 U: capnp::traits::FromPointerReader<'a> + capnp::traits::SetPointerBuilder<T>>
        (&'a mut self) -> Result<T> {
        let reader = try!(capnp::serialize::read_message(&mut &self.vec[..], capnp::message::ReaderOptions::new()));
        self.reader = Some(reader);
        let reader: U = try!(self.reader.as_ref().unwrap().get_root());

        let mut msg = capnp::message::Builder::new_default();
        try!(msg.set_root(reader));
        self.builder = Some(msg);
        Ok(try!(self.builder.as_mut().unwrap().get_root()))
    }

    /// Write a capnp `Builder` to a `Vec`
    ///
    /// # Example
    ///
    /// ```rust,ignore
    /// let mut ip = an_initialized_ip;
    /// {
    ///     let mut builder = try!(edit_edge::<generic_text::Builder, generic_text::Reader>());
    ///     builder.set_text("Hello Fractalide!");
    /// }
    /// try!(ip.before_send());
    /// ```
    pub fn before_send(&mut self) -> Result<()> {
        let mut build = mem::replace(&mut self.builder, None);
        if let Some(ref mut b) = build {
            self.vec.clear();
            try!(capnp::serialize::write_message(&mut self.vec, b))
        }
        Ok(())

    }
}

impl Clone for IP {
    fn clone(&self) -> Self {
        IP {
            vec: self.vec.clone(),
            action: self.action.clone(),
            reader: None,
            builder: None,
        }
    }
}

/// A wrapper around `SyncSender<IP>`
///
/// A specific `SyncSender` for the IP object. It also sends information to the scheduler.
#[derive(Clone)]
pub struct IPSender {
    /// The SyncSender, connected to a receiver in another agent
    pub sender: SyncSender<IP>,
    /// The name of the agent owning the receiver
    pub dest: String,
    /// A Sender to the scheduler, to signal that the receiver must be run
    pub sched: Sender<CompMsg>,
}

impl IPSender {
    /// Send an IP to the Receiver
    pub fn send(&self, mut ip: IP) -> Result<()> {
        try!(ip.before_send());
        try!(self.sender.send(ip));
        if self.dest != "" {
            try!(self.sched.send(CompMsg::Inc(self.dest.clone())));
        }
        Ok(())
    }
}

pub trait OutputSend {
    fn send(&self, ip:IP) -> Result<()>;
}

impl OutputSend for Option<IPSender> {
    fn send(&self, ip: IP) -> Result<()> {
        if let &Some(ref sender) = self {
            sender.send(ip)?;
            Ok(())
        } else {
            Err(result::Error::OutputNotConnected)
        }
    }
}

pub struct IPReceiver {
    name: String,
    recv: Receiver<IP>,
    sched: Sender<CompMsg>,
    must_sched: bool,
}

impl IPReceiver {
    pub fn new(name: String, sched: Sender<CompMsg>, must_sched: bool) -> (IPReceiver, IPSender) {
        let (s, r) = sync_channel(25);
        let s = IPSender {
            sender: s,
            dest: if must_sched { name.clone() } else { "".into() },
            sched: sched.clone(),
        };
        let r = IPReceiver {
            recv: r,
            name: name,
            sched: sched,
            must_sched: must_sched,
        };
        (r, s)
    }

    pub fn recv(&self) -> Result<IP> {
        let ip = try!(self.recv.recv());
        if self.must_sched {
            try!(self.sched.send(CompMsg::Dec(self.name.clone())));
        }
        Ok(ip)
    }

    pub fn try_recv(&self) -> Result<IP> {
        let ip = self.recv.try_recv()?;
        if self.must_sched {
            try!(self.sched.send(CompMsg::Dec(self.name.clone())));
        }
        Ok(ip)
    }
}
<|endoftext|>


<commit_before>use crate::spec::{LldFlavor, LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut pre_link_args = LinkArgs::new();
    pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec![
        "--build-id".to_string(),
        "--hash-style=gnu".to_string(),
        "--Bstatic".to_string(),
    ]);

    TargetOptions {
        linker: Some("rust-lld".to_owned()),
        executables: true,
        has_elf_tls: true,
        linker_is_gnu: true,
        pre_link_args,
        no_default_libraries: true,
        panic_strategy: PanicStrategy::Abort,
        position_independent_executables: true,
        relocation_model: "static".to_string(),
        target_family: None,
        tls_model: "initial-exec".to_string(),
        .. Default::default()
    }
}
<commit_msg>disable redzone<commit_after>use crate::spec::{LldFlavor, LinkArgs, LinkerFlavor, PanicStrategy, TargetOptions};
use std::default::Default;

pub fn opts() -> TargetOptions {
    let mut pre_link_args = LinkArgs::new();
    pre_link_args.insert(LinkerFlavor::Lld(LldFlavor::Ld), vec![
        "--build-id".to_string(),
        "--hash-style=gnu".to_string(),
        "--Bstatic".to_string(),
    ]);

    TargetOptions {
        disable_redzone: true,
        linker: Some("rust-lld".to_owned()),
        executables: true,
        has_elf_tls: true,
        linker_is_gnu: true,
        pre_link_args,
        no_default_libraries: true,
        panic_strategy: PanicStrategy::Abort,
        position_independent_executables: true,
        relocation_model: "static".to_string(),
        target_family: None,
        tls_model: "initial-exec".to_string(),
        .. Default::default()
    }
}
<|endoftext|>


<commit_before>extern crate rand;

use std::convert::From;
use std::default::Default;
use std::iter::{FromIterator, Iterator, repeat};
use std::collections::VecDeque;
use std::collections::vec_deque::{Iter, IterMut};
use self::rand::Rng;

/// a little implementation of a random-wheel.
pub struct RouletteWheel<T> {
    /// the sum of all probabilities in this wheel.
    proba_sum: f32,
    /// all the (probability, data) in a linked-list to pop easily.
    cards: VecDeque<(f32, T)>
}

impl<T: Clone> Clone for RouletteWheel<T> {
    fn clone(&self) -> RouletteWheel<T> {
        RouletteWheel {
            proba_sum: self.proba_sum,
            cards: self.cards.clone()
        }
    }
}

impl<T> Default for RouletteWheel<T> {
    fn default() -> RouletteWheel<T> {
        RouletteWheel {
            proba_sum: 0.0,
            cards: VecDeque::new()
        }
    }
}

impl<'a, T: Clone> From<&'a [T]> for RouletteWheel<T> {
    fn from(s: &'a [T]) -> RouletteWheel<T> {
        RouletteWheel {
            proba_sum: s.len() as f32,
            cards: VecDeque::from_iter(repeat(1.0).zip(s.iter().cloned()))
        }
    }
}

impl<'a, T: Clone> From<&'a [(f32, T)]> for RouletteWheel<T> {
    fn from(s: &'a [(f32, T)]) -> RouletteWheel<T> {
        for &(proba, _) in s {
            assert!(proba > 0.0, "proba {} is lower or equal to zero!", proba);
        }
        RouletteWheel {
            proba_sum: s.iter().fold(0.0, |acc, &(proba, _)| acc + proba),
            cards: VecDeque::from_iter(s.iter().cloned())
        }
    }
}

impl<T> RouletteWheel<T> {
    /// create a new empty random-wheel.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let rw: RouletteWheel<u8> = RouletteWheel::new();
    /// ```
    pub fn new() -> RouletteWheel<T> {
        RouletteWheel {
            proba_sum: 0.0,
            cards: VecDeque::new()
        }
    }

    /// Creates an empty RouletteWheel with space for at least n elements.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let numbers: Vec<_> = (0..20).collect();
    /// let rw: RouletteWheel<u8> = RouletteWheel::with_capacity(numbers.len());
    ///
    /// assert_eq!(rw.len(), 0);
    /// ```
    pub fn with_capacity(n: usize) -> RouletteWheel<T> {
        RouletteWheel {
            proba_sum: 0.0,
            cards: VecDeque::with_capacity(n)
        }
    }

    /// Reserves capacity for at least `additional` more elements to be inserted
    /// in the given `Ringbuf`.
    /// The collection may reserve more space to avoid frequent reallocations.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let rw: RouletteWheel<u8> = RouletteWheel::new();
    /// rw.reserve(20);
    ///
    /// assert_eq!(rw.len(), 0);
    /// ```
    pub fn reserve(&mut self, additional: usize) {
        self.cards.reserve(additional);
    }

    /// Returns the number of elements the RouletteWheel can hold without
    /// reallocating.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let rw: RouletteWheel<u8> = RouletteWheel::new();
    ///
    /// println!("actual capacity: {}", rw.capacity());
    /// ```
    pub fn capacity(&self) -> usize {
        self.cards.capacity()
    }

    /// returns the number of elements in the wheel.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// assert_eq!(rw.len(), 0);
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// assert_eq!(rw.len(), 3);
    /// ```
    pub fn len(&self) -> usize {
        self.cards.len()
    }

    /// returns `true` if empty else return `false`.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// assert_eq!(rw.is_empty(), true);
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// assert_eq!(rw.is_empty(), false);
    /// ```
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// remove all elements in this wheel.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// assert_eq!(rw.len(), 3);
    ///
    /// rw.clear();
    ///
    /// assert_eq!(rw.len(), 0);
    /// ```
    pub fn clear(&mut self) {
        self.cards.clear()
    }

    /// add an element associated with a probability.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// assert_eq!(rw.len(), 3);
    /// ```
    pub fn push(&mut self, proba: f32, data: T) {
        assert!(proba > 0.0, "proba {} is lower or equal to zero!", proba);
        self.cards.push_back((proba, data));
        self.proba_sum += proba;
        if self.proba_sum.is_infinite() {
            panic!("Probability sum reached an Inf value!");
        }
    }

    /// Will recompute the probabilities sum
    /// use it when you iterate through this vector and change proba values
    /// TODO check if proba become Inf too
    pub fn update_proba_sum(&mut self) {
        self.proba_sum = 0.0;
        for &(proba, _) in self.cards.iter() {
            assert!(proba > 0.0, "proba '{}' is lower or equal to zero!", proba);
            self.proba_sum += proba;
        }
        if self.proba_sum.is_infinite() {
            panic!("Probability sum reached an Inf value!");
        }
    }

    /// returns total of luck you pushed.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.5, 'r');
    /// rw.push(2., 'c');
    /// rw.push(3., 'a');
    ///
    /// assert_eq!(rw.proba_sum(), 6.5);
    /// ```
    pub fn proba_sum(&self) -> f32 {
        self.proba_sum
    }

    /// returns a random distance to browser between 0 and the probabilities sum.
    fn gen_random_dist(&self) -> f32 {
        match self.proba_sum {
            sum if sum > 0. => rand::thread_rng().gen_range(0., sum),
            _               => 0.
        }
    }

    /// returns a random index in self.cards.
    fn get_random_index(&self) -> Option<usize> {
        if self.is_empty() == false {
            let mut dist = self.gen_random_dist();
            for (id, &(ref proba, _)) in self.cards.iter().enumerate() {
                dist -= *proba;
                if dist <= 0. {
                    return Some(id);
                }
            }
            None
        }
        else { None }
    }

    /// returns a ref to the randomly peeked element with
    /// it's probality to be peeked.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    ///
    /// assert_eq!(rw.peek(), Some((1.0, &'r')));
    /// assert_eq!(rw.peek(), Some((1.0, &'r')));
    /// ```
    pub fn peek(&self) -> Option<(f32, &T)> {
        if let Some(index) = self.get_random_index() {
            if let Some(&(proba, ref data)) = self.cards.get(index) {
                Some((proba, data))
            }
            else { None }
        }
        else { None }
    }

    /// returns a mutable ref to the randomly peeked element with
    /// it's probality to be peeked.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    ///
    /// match rw.peek_mut() {
    ///     Some((_, val)) => *val = 'b',
    ///     None => {}
    /// }
    ///
    /// assert_eq!(rw.peek(), Some((1.0, &'b')));
    /// ```
    pub fn peek_mut(&mut self) -> Option<(f32, &mut T)> {
        if let Some(index) = self.get_random_index() {
            if let Some(&mut (proba, ref mut data)) = self.cards.get_mut(index) {
                Some((proba, data))
            }
            else { None }
        }
        else { None }
    }

    /// removes a randomly peeked element and return it with
    /// it's probality to be peeked.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    ///
    /// assert_eq!(rw.pop(), Some((1.0, 'r')));
    ///
    /// // once you pop the value, it doesn't exist anymore
    /// assert_eq!(rw.peek(), None);
    /// assert_eq!(rw.pop(), None);
    /// ```
    pub fn pop(&mut self) -> Option<(f32, T)> {
        if let Some(index) = self.get_random_index() {
            if let Some((proba, data)) = self.cards.remove(index) {
                self.proba_sum -= proba;
                Some((proba, data))
            }
            else { None }
        }
        else { None }
    }

    /// Returns an iterator over the slice, giving &(proba, elem).
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// let mut iter = rw.iter();
    ///
    /// assert_eq!(iter.next(), Some(&(1.0, 'r')));
    /// assert_eq!(iter.next(), Some(&(1.0, 'c')));
    /// assert_eq!(iter.next(), Some(&(1.0, 'a')));
    /// assert_eq!(iter.next(), None);
    /// ```
    pub fn iter(&self) -> Iter<(f32, T)> {
        self.cards.iter()
    }

    /// Returns a mutable iterator over the slice, giving &mut (proba, elem).
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// let mut iter = rw.iter();
    ///
    /// assert_eq!(iter.next(), Some(&(1.0, 'r')));
    /// assert_eq!(iter.next(), Some(&(1.0, 'c')));
    /// assert_eq!(iter.next(), Some(&(1.0, 'a')));
    /// assert_eq!(iter.next(), None);
    /// ```
    pub fn iter_mut(&mut self) -> IterMut<(f32, T)> {
        self.cards.iter_mut()
    }
}
<commit_msg>fixed reserve() example<commit_after>extern crate rand;

use std::convert::From;
use std::default::Default;
use std::iter::{FromIterator, Iterator, repeat};
use std::collections::VecDeque;
use std::collections::vec_deque::{Iter, IterMut};
use self::rand::Rng;

/// a little implementation of a random-wheel.
pub struct RouletteWheel<T> {
    /// the sum of all probabilities in this wheel.
    proba_sum: f32,
    /// all the (probability, data) in a linked-list to pop easily.
    cards: VecDeque<(f32, T)>
}

impl<T: Clone> Clone for RouletteWheel<T> {
    fn clone(&self) -> RouletteWheel<T> {
        RouletteWheel {
            proba_sum: self.proba_sum,
            cards: self.cards.clone()
        }
    }
}

impl<T> Default for RouletteWheel<T> {
    fn default() -> RouletteWheel<T> {
        RouletteWheel {
            proba_sum: 0.0,
            cards: VecDeque::new()
        }
    }
}

impl<'a, T: Clone> From<&'a [T]> for RouletteWheel<T> {
    fn from(s: &'a [T]) -> RouletteWheel<T> {
        RouletteWheel {
            proba_sum: s.len() as f32,
            cards: VecDeque::from_iter(repeat(1.0).zip(s.iter().cloned()))
        }
    }
}

impl<'a, T: Clone> From<&'a [(f32, T)]> for RouletteWheel<T> {
    fn from(s: &'a [(f32, T)]) -> RouletteWheel<T> {
        for &(proba, _) in s {
            assert!(proba > 0.0, "proba {} is lower or equal to zero!", proba);
        }
        RouletteWheel {
            proba_sum: s.iter().fold(0.0, |acc, &(proba, _)| acc + proba),
            cards: VecDeque::from_iter(s.iter().cloned())
        }
    }
}

impl<T> RouletteWheel<T> {
    /// create a new empty random-wheel.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let rw: RouletteWheel<u8> = RouletteWheel::new();
    /// ```
    pub fn new() -> RouletteWheel<T> {
        RouletteWheel {
            proba_sum: 0.0,
            cards: VecDeque::new()
        }
    }

    /// Creates an empty RouletteWheel with space for at least n elements.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let numbers: Vec<_> = (0..20).collect();
    /// let rw: RouletteWheel<u8> = RouletteWheel::with_capacity(numbers.len());
    ///
    /// assert_eq!(rw.len(), 0);
    /// ```
    pub fn with_capacity(n: usize) -> RouletteWheel<T> {
        RouletteWheel {
            proba_sum: 0.0,
            cards: VecDeque::with_capacity(n)
        }
    }

    /// Reserves capacity for at least `additional` more elements to be inserted
    /// in the given `Ringbuf`.
    /// The collection may reserve more space to avoid frequent reallocations.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw: RouletteWheel<u8> = RouletteWheel::new();
    /// rw.reserve(20);
    ///
    /// assert_eq!(rw.len(), 0);
    /// ```
    pub fn reserve(&mut self, additional: usize) {
        self.cards.reserve(additional);
    }

    /// Returns the number of elements the RouletteWheel can hold without
    /// reallocating.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let rw: RouletteWheel<u8> = RouletteWheel::new();
    ///
    /// println!("actual capacity: {}", rw.capacity());
    /// ```
    pub fn capacity(&self) -> usize {
        self.cards.capacity()
    }

    /// returns the number of elements in the wheel.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// assert_eq!(rw.len(), 0);
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// assert_eq!(rw.len(), 3);
    /// ```
    pub fn len(&self) -> usize {
        self.cards.len()
    }

    /// returns `true` if empty else return `false`.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// assert_eq!(rw.is_empty(), true);
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// assert_eq!(rw.is_empty(), false);
    /// ```
    pub fn is_empty(&self) -> bool {
        self.len() == 0
    }

    /// remove all elements in this wheel.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// assert_eq!(rw.len(), 3);
    ///
    /// rw.clear();
    ///
    /// assert_eq!(rw.len(), 0);
    /// ```
    pub fn clear(&mut self) {
        self.cards.clear()
    }

    /// add an element associated with a probability.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// assert_eq!(rw.len(), 3);
    /// ```
    pub fn push(&mut self, proba: f32, data: T) {
        assert!(proba > 0.0, "proba {} is lower or equal to zero!", proba);
        self.cards.push_back((proba, data));
        self.proba_sum += proba;
        if self.proba_sum.is_infinite() {
            panic!("Probability sum reached an Inf value!");
        }
    }

    /// Will recompute the probabilities sum
    /// use it when you iterate through this vector and change proba values
    /// TODO check if proba become Inf too
    pub fn update_proba_sum(&mut self) {
        self.proba_sum = 0.0;
        for &(proba, _) in self.cards.iter() {
            assert!(proba > 0.0, "proba '{}' is lower or equal to zero!", proba);
            self.proba_sum += proba;
        }
        if self.proba_sum.is_infinite() {
            panic!("Probability sum reached an Inf value!");
        }
    }

    /// returns total of luck you pushed.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.5, 'r');
    /// rw.push(2., 'c');
    /// rw.push(3., 'a');
    ///
    /// assert_eq!(rw.proba_sum(), 6.5);
    /// ```
    pub fn proba_sum(&self) -> f32 {
        self.proba_sum
    }

    /// returns a random distance to browser between 0 and the probabilities sum.
    fn gen_random_dist(&self) -> f32 {
        match self.proba_sum {
            sum if sum > 0. => rand::thread_rng().gen_range(0., sum),
            _               => 0.
        }
    }

    /// returns a random index in self.cards.
    fn get_random_index(&self) -> Option<usize> {
        if self.is_empty() == false {
            let mut dist = self.gen_random_dist();
            for (id, &(ref proba, _)) in self.cards.iter().enumerate() {
                dist -= *proba;
                if dist <= 0. {
                    return Some(id);
                }
            }
            None
        }
        else { None }
    }

    /// returns a ref to the randomly peeked element with
    /// it's probality to be peeked.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    ///
    /// assert_eq!(rw.peek(), Some((1.0, &'r')));
    /// assert_eq!(rw.peek(), Some((1.0, &'r')));
    /// ```
    pub fn peek(&self) -> Option<(f32, &T)> {
        if let Some(index) = self.get_random_index() {
            if let Some(&(proba, ref data)) = self.cards.get(index) {
                Some((proba, data))
            }
            else { None }
        }
        else { None }
    }

    /// returns a mutable ref to the randomly peeked element with
    /// it's probality to be peeked.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    ///
    /// match rw.peek_mut() {
    ///     Some((_, val)) => *val = 'b',
    ///     None => {}
    /// }
    ///
    /// assert_eq!(rw.peek(), Some((1.0, &'b')));
    /// ```
    pub fn peek_mut(&mut self) -> Option<(f32, &mut T)> {
        if let Some(index) = self.get_random_index() {
            if let Some(&mut (proba, ref mut data)) = self.cards.get_mut(index) {
                Some((proba, data))
            }
            else { None }
        }
        else { None }
    }

    /// removes a randomly peeked element and return it with
    /// it's probality to be peeked.
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    ///
    /// assert_eq!(rw.pop(), Some((1.0, 'r')));
    ///
    /// // once you pop the value, it doesn't exist anymore
    /// assert_eq!(rw.peek(), None);
    /// assert_eq!(rw.pop(), None);
    /// ```
    pub fn pop(&mut self) -> Option<(f32, T)> {
        if let Some(index) = self.get_random_index() {
            if let Some((proba, data)) = self.cards.remove(index) {
                self.proba_sum -= proba;
                Some((proba, data))
            }
            else { None }
        }
        else { None }
    }

    /// Returns an iterator over the slice, giving &(proba, elem).
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// let mut iter = rw.iter();
    ///
    /// assert_eq!(iter.next(), Some(&(1.0, 'r')));
    /// assert_eq!(iter.next(), Some(&(1.0, 'c')));
    /// assert_eq!(iter.next(), Some(&(1.0, 'a')));
    /// assert_eq!(iter.next(), None);
    /// ```
    pub fn iter(&self) -> Iter<(f32, T)> {
        self.cards.iter()
    }

    /// Returns a mutable iterator over the slice, giving &mut (proba, elem).
    /// # Example
    ///
    /// ```
    /// use roulette_wheel::RouletteWheel;
    ///
    /// let mut rw = RouletteWheel::new();
    ///
    /// rw.push(1.0, 'r');
    /// rw.push(1.0, 'c');
    /// rw.push(1.0, 'a');
    ///
    /// let mut iter = rw.iter();
    ///
    /// assert_eq!(iter.next(), Some(&(1.0, 'r')));
    /// assert_eq!(iter.next(), Some(&(1.0, 'c')));
    /// assert_eq!(iter.next(), Some(&(1.0, 'a')));
    /// assert_eq!(iter.next(), None);
    /// ```
    pub fn iter_mut(&mut self) -> IterMut<(f32, T)> {
        self.cards.iter_mut()
    }
}
<|endoftext|>


<commit_before>use crate::{Direction, Incoming};

use crate::visit::{
    Data, EdgeRef, GraphBase, GraphProp, GraphRef, IntoEdgeReferences, IntoEdges,
    IntoEdgesDirected, IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers,
    IntoNodeReferences, NodeCompactIndexable, NodeCount, NodeIndexable, Visitable,
};

/// An edge-reversing graph adaptor.
///
/// All edges have the opposite direction with `Reversed`.
#[derive(Copy, Clone, Debug)]
pub struct Reversed<G>(pub G);

impl<G: GraphBase> GraphBase for Reversed<G> {
    type NodeId = G::NodeId;
    type EdgeId = G::EdgeId;
}

impl<G: GraphRef> GraphRef for Reversed<G> {}

Data! {delegate_impl [[G], G, Reversed<G>, access0]}

impl<G> IntoNeighbors for Reversed<G>
where
    G: IntoNeighborsDirected,
{
    type Neighbors = G::NeighborsDirected;
    fn neighbors(self, n: G::NodeId) -> G::NeighborsDirected {
        self.0.neighbors_directed(n, Incoming)
    }
}

impl<G> IntoNeighborsDirected for Reversed<G>
where
    G: IntoNeighborsDirected,
{
    type NeighborsDirected = G::NeighborsDirected;
    fn neighbors_directed(self, n: G::NodeId, d: Direction) -> G::NeighborsDirected {
        self.0.neighbors_directed(n, d.opposite())
    }
}

impl<G> IntoEdges for Reversed<G>
where
    G: IntoEdgesDirected,
{
    type Edges = ReversedEdges<G::EdgesDirected>;
    fn edges(self, a: Self::NodeId) -> Self::Edges {
        ReversedEdges {
            iter: self.0.edges_directed(a, Incoming),
        }
    }
}

impl<G> IntoEdgesDirected for Reversed<G>
where
    G: IntoEdgesDirected,
{
    type EdgesDirected = ReversedEdges<G::EdgesDirected>;
    fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::Edges {
        ReversedEdges {
            iter: self.0.edges_directed(a, dir.opposite()),
        }
    }
}

impl<G: Visitable> Visitable for Reversed<G> {
    type Map = G::Map;
    fn visit_map(&self) -> G::Map {
        self.0.visit_map()
    }
    fn reset_map(&self, map: &mut Self::Map) {
        self.0.reset_map(map);
    }
}

/// A reversed edges iterator.
pub struct ReversedEdges<I> {
    iter: I,
}

impl<I> Iterator for ReversedEdges<I>
where
    I: Iterator,
    I::Item: EdgeRef,
{
    type Item = ReversedEdgeReference<I::Item>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next().map(ReversedEdgeReference)
    }
}

/// A reversed edge reference
#[derive(Copy, Clone, Debug)]
pub struct ReversedEdgeReference<R>(R);

/// An edge reference
impl<R> EdgeRef for ReversedEdgeReference<R>
where
    R: EdgeRef,
{
    type NodeId = R::NodeId;
    type EdgeId = R::EdgeId;
    type Weight = R::Weight;
    fn source(&self) -> Self::NodeId {
        self.0.target()
    }
    fn target(&self) -> Self::NodeId {
        self.0.source()
    }
    fn weight(&self) -> &Self::Weight {
        self.0.weight()
    }
    fn id(&self) -> Self::EdgeId {
        self.0.id()
    }
}

impl<G> IntoEdgeReferences for Reversed<G>
where
    G: IntoEdgeReferences,
{
    type EdgeRef = ReversedEdgeReference<G::EdgeRef>;
    type EdgeReferences = ReversedEdgeReferences<G::EdgeReferences>;
    fn edge_references(self) -> Self::EdgeReferences {
        ReversedEdgeReferences {
            iter: self.0.edge_references(),
        }
    }
}

/// A reversed edge references iterator.
pub struct ReversedEdgeReferences<I> {
    iter: I,
}

impl<I> Iterator for ReversedEdgeReferences<I>
where
    I: Iterator,
    I::Item: EdgeRef,
{
    type Item = ReversedEdgeReference<I::Item>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next().map(ReversedEdgeReference)
    }
}

macro_rules! access0 {
    ($e:expr) => {
        $e.0
    };
}

NodeIndexable! {delegate_impl [[G], G, Reversed<G>, access0]}
NodeCompactIndexable! {delegate_impl [[G], G, Reversed<G>, access0]}
IntoNodeIdentifiers! {delegate_impl [[G], G, Reversed<G>, access0]}
IntoNodeReferences! {delegate_impl [[G], G, Reversed<G>, access0]}
GraphProp! {delegate_impl [[G], G, Reversed<G>, access0]}
NodeCount! {delegate_impl [[G], G, Reversed<G>, access0]}
<commit_msg>[visit] access original edge reference from a reversed edge<commit_after>use crate::{Direction, Incoming};

use crate::visit::{
    Data, EdgeRef, GraphBase, GraphProp, GraphRef, IntoEdgeReferences, IntoEdges,
    IntoEdgesDirected, IntoNeighbors, IntoNeighborsDirected, IntoNodeIdentifiers,
    IntoNodeReferences, NodeCompactIndexable, NodeCount, NodeIndexable, Visitable,
};

/// An edge-reversing graph adaptor.
///
/// All edges have the opposite direction with `Reversed`.
#[derive(Copy, Clone, Debug)]
pub struct Reversed<G>(pub G);

impl<G: GraphBase> GraphBase for Reversed<G> {
    type NodeId = G::NodeId;
    type EdgeId = G::EdgeId;
}

impl<G: GraphRef> GraphRef for Reversed<G> {}

Data! {delegate_impl [[G], G, Reversed<G>, access0]}

impl<G> IntoNeighbors for Reversed<G>
where
    G: IntoNeighborsDirected,
{
    type Neighbors = G::NeighborsDirected;
    fn neighbors(self, n: G::NodeId) -> G::NeighborsDirected {
        self.0.neighbors_directed(n, Incoming)
    }
}

impl<G> IntoNeighborsDirected for Reversed<G>
where
    G: IntoNeighborsDirected,
{
    type NeighborsDirected = G::NeighborsDirected;
    fn neighbors_directed(self, n: G::NodeId, d: Direction) -> G::NeighborsDirected {
        self.0.neighbors_directed(n, d.opposite())
    }
}

impl<G> IntoEdges for Reversed<G>
where
    G: IntoEdgesDirected,
{
    type Edges = ReversedEdges<G::EdgesDirected>;
    fn edges(self, a: Self::NodeId) -> Self::Edges {
        ReversedEdges {
            iter: self.0.edges_directed(a, Incoming),
        }
    }
}

impl<G> IntoEdgesDirected for Reversed<G>
where
    G: IntoEdgesDirected,
{
    type EdgesDirected = ReversedEdges<G::EdgesDirected>;
    fn edges_directed(self, a: Self::NodeId, dir: Direction) -> Self::Edges {
        ReversedEdges {
            iter: self.0.edges_directed(a, dir.opposite()),
        }
    }
}

impl<G: Visitable> Visitable for Reversed<G> {
    type Map = G::Map;
    fn visit_map(&self) -> G::Map {
        self.0.visit_map()
    }
    fn reset_map(&self, map: &mut Self::Map) {
        self.0.reset_map(map);
    }
}

/// A reversed edges iterator.
pub struct ReversedEdges<I> {
    iter: I,
}

impl<I> Iterator for ReversedEdges<I>
where
    I: Iterator,
    I::Item: EdgeRef,
{
    type Item = ReversedEdgeReference<I::Item>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next().map(ReversedEdgeReference)
    }
}

/// A reversed edge reference
#[derive(Copy, Clone, Debug)]
pub struct ReversedEdgeReference<R>(R);

impl<R> ReversedEdgeReference<R> {
    /// Return the original, unreversed edge reference.
    pub fn as_unreversed(&self) -> &R { &self.0 }

    /// Consume `self` and return the original, unreversed edge reference.
    pub fn into_unreversed(self) -> R {
        self.0
    }
}

/// An edge reference
impl<R> EdgeRef for ReversedEdgeReference<R>
where
    R: EdgeRef,
{
    type NodeId = R::NodeId;
    type EdgeId = R::EdgeId;
    type Weight = R::Weight;
    fn source(&self) -> Self::NodeId {
        self.0.target()
    }
    fn target(&self) -> Self::NodeId {
        self.0.source()
    }
    fn weight(&self) -> &Self::Weight {
        self.0.weight()
    }
    fn id(&self) -> Self::EdgeId {
        self.0.id()
    }
}

impl<G> IntoEdgeReferences for Reversed<G>
where
    G: IntoEdgeReferences,
{
    type EdgeRef = ReversedEdgeReference<G::EdgeRef>;
    type EdgeReferences = ReversedEdgeReferences<G::EdgeReferences>;
    fn edge_references(self) -> Self::EdgeReferences {
        ReversedEdgeReferences {
            iter: self.0.edge_references(),
        }
    }
}

/// A reversed edge references iterator.
pub struct ReversedEdgeReferences<I> {
    iter: I,
}

impl<I> Iterator for ReversedEdgeReferences<I>
where
    I: Iterator,
    I::Item: EdgeRef,
{
    type Item = ReversedEdgeReference<I::Item>;
    fn next(&mut self) -> Option<Self::Item> {
        self.iter.next().map(ReversedEdgeReference)
    }
}

macro_rules! access0 {
    ($e:expr) => {
        $e.0
    };
}

NodeIndexable! {delegate_impl [[G], G, Reversed<G>, access0]}
NodeCompactIndexable! {delegate_impl [[G], G, Reversed<G>, access0]}
IntoNodeIdentifiers! {delegate_impl [[G], G, Reversed<G>, access0]}
IntoNodeReferences! {delegate_impl [[G], G, Reversed<G>, access0]}
GraphProp! {delegate_impl [[G], G, Reversed<G>, access0]}
NodeCount! {delegate_impl [[G], G, Reversed<G>, access0]}
<|endoftext|>


<commit_before>// Copyright 2013 The rust-gobject authors.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod extra;
extern mod gi;

use extra::getopts::*;
use std::os;
use std::util;

fn print_usage(program: &str, opts: &[Opt]) {
    util::ignore(opts);
    println!("Usage: {} [general-options] command [command-options] [command-arguments]", program);
    println("General options:");
    println("    -h, --help          Print usage and exit");
    println("    --version           Print version information and exit");
    println("\nCommands:");
    println("    help                Print usage for a command and exit");
    println("    generate            Generate Rust bindings for a GI namespace and optional version");
}

fn print_version_info() {
    println("0.1");
}

fn print_generate_usage(program: &str, general_opts: &[Opt], command_opts: &[Opt]) {
    util::ignore(general_opts);
    util::ignore(command_opts);
    println!("Usage: {} [general-options] generate [command-options] namespace output-module", program);
    println("Command options:");
    println("    -h, --help          Print usage and exit");
    println("    --version=VERS      (optional) Require version VERS of the namespace");
}

fn do_generate(program: &str, general_opts: &[Opt], args: ~[~str]) {
    let opts = ~[
        optflag("h"),
        optflag("help"),
        optopt("version")
    ];

    let matches = match getopts(args.tail(), opts) {
        Err(f) => {
            println!("Error: {}", f.to_err_msg());
            os::set_exit_status(1);
            return;
        },
        Ok(m) => m
    };

    if matches.opt_present("h") || matches.opt_present("help") {
        print_generate_usage(program, general_opts, opts);
        return;
    }

    if matches.free.len() == 0 {
        println("Error: No GI namespace");
        os::set_exit_status(1);
        return;
    } else if matches.free.len() == 1 {
        println("Error: No output module name");
        os::set_exit_status(1);
        return;
    }

    let opt_version = matches.opt_str("version");
    let namespace = matches.free[0];

    let repository = gi::Repository::default();

    // TODO: `opt_version.as_ref()`
    let require_res = repository.require(namespace, opt_version.map(|s| s.as_slice()), []);
    match require_res {
        Err(error) => {
            println!("Error: Failed to load namespace '{}': {}", namespace, error.message());
        },
        Ok(typelib) => {
        }
    }
}

fn main() {
    let args = os::args();
    let program = args[0].clone();

    let opts = ~[
        optflag("h"),
        optflag("help"),
        optflag("version")
    ];

    let matches = match getopts(args.tail(), opts) {
        Err(f) => {
            println!("Error: {}", f.to_err_msg());
            os::set_exit_status(1);
            return;
        },
        Ok(m) => m
    };

    if matches.opt_present("h") || matches.opt_present("help") {
        print_usage(program, opts);
        return;
    }

    if matches.opt_present("version") {
        print_version_info();
        return;
    }

    if matches.free.len() == 0 {
        println("Error: No command");
        os::set_exit_status(1);
        return;
    }

    let command = matches.free[0].clone();

    if command == ~"gen" || command == ~"generate" {
        do_generate(program, opts, matches.free.clone());
    } else {
        println!("Error: Unknown command '{}'", command);
        os::set_exit_status(1);
        return;
    }
}
<commit_msg>Start work on a 'dump' command<commit_after>// Copyright 2013 The rust-gobject authors.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

extern mod extra;
extern mod gi;
extern mod glib;

use extra::getopts::*;
use std::os;
use std::util;

fn print_usage(program: &str, opts: &[Opt]) {
    util::ignore(opts);
    println!("Usage: {} [general-options] command -- [command-options] [command-arguments]", program);
    println("General options:");
    println("    -h, --help          Print usage and exit");
    println("    --version           Print version information and exit");
    println("\nCommands:");
    println("    help                Print usage for a command and exit");
    println("    dump                Dump a GI namespace");
    println("    generate            Generate Rust bindings for a GI namespace");
}

fn print_version_info() {
    println("0.1");
}

fn print_dump_usage(program: &str, general_opts: &[Opt], command_opts: &[Opt]) {
    util::ignore(general_opts);
    util::ignore(command_opts);
    println!("Usage: {} [general-options] dump -- [command-options] namespace", program);
    println("Command options:");
    println("    -h, --help          Print usage and exit");
    println("    --version=VERS      (optional) Require version VERS of the namespace");
}

fn do_dump(program: &str, general_opts: &[Opt], args: ~[~str]) {
    let opts = ~[
        optflag("h"),
        optflag("help"),
        optopt("version")
    ];

    let matches = match getopts(args.tail(), opts) {
        Err(f) => {
            println!("Error: {}", f.to_err_msg());
            os::set_exit_status(1);
            return;
        },
        Ok(m) => m
    };

    if matches.opt_present("h") || matches.opt_present("help") {
        print_dump_usage(program, general_opts, opts);
        return;
    }

    if matches.free.len() == 0 {
        println("Error: No GI namespace");
        os::set_exit_status(1);
        return;
    }

    let opt_version = matches.opt_str("version");
    let namespace = matches.free[0];

    let repository = gi::Repository::default();

    // TODO: `opt_version.as_ref()`
    let require_res = repository.require(namespace, opt_version.map(|s| s.as_slice()), []);
    let typelib = match require_res {
        Err(error) => {
            match opt_version {
                None => println!("Error: Failed to load namespace '{}': {}", namespace, error.message()),
                Some(version) => println!("Error: Failed to load namespace '{}' at version {}: {}", namespace, version, error.message())
            }
            os::set_exit_status(1);
            return;
        },
        Ok(typelib) => typelib
    };
    util::ignore(typelib);

    let namespace_cstring = namespace.to_c_str();
    let n_infos = repository.n_infos(&namespace_cstring);
    println!("n_infos = {}", n_infos);
    let mut i: glib::gint = 0;
    while i < n_infos {
        let info = repository.info(&namespace_cstring, i);
        let info_type = info.type_();
        let opt_name = info.name();
        match opt_name {
            None => println!("\n{}: ({})", i, info_type.to_str()),
            Some(name) => println!("\n{}: {} ({})", i, name, info_type.to_str()),
        }
        for (name, value) in info.attribute_iter() {
            println!("{} => {}", name, value);
        }
        i = i + 1;
    }
}

fn main() {
    let args = os::args();
    let program = args[0].clone();

    let opts = ~[
        optflag("h"),
        optflag("help"),
        optflag("version")
    ];

    let matches = match getopts(args.tail(), opts) {
        Err(f) => {
            println!("Error: {}", f.to_err_msg());
            os::set_exit_status(1);
            return;
        },
        Ok(m) => m
    };

    if matches.opt_present("h") || matches.opt_present("help") {
        print_usage(program, opts);
        return;
    }

    if matches.opt_present("version") {
        print_version_info();
        return;
    }

    if matches.free.len() == 0 {
        println("Error: No command");
        os::set_exit_status(1);
        return;
    }

    let command = matches.free[0].clone();

    if command == ~"help" {
        println("Error: The 'help' command is unimplemented.");
        os::set_exit_status(1);
        return;
    } else if command == ~"dump" {
        do_dump(program, opts, matches.free.clone());
    } else if command == ~"gen" || command == ~"generate" {
        println("Error: The 'generate' command is unimplemented.");
        os::set_exit_status(1);
        return;
    } else {
        println!("Error: Unknown command '{}'", command);
        os::set_exit_status(1);
        return;
    }
}
<|endoftext|>


<commit_before>
// https://users.rust-lang.org/t/what-am-i-doing-wrong-go-program-is-12x-faster-than-rust/5692/13
// https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/index.html
// https://serde.rs/codegen-hybrid.html

// FIXME: Use https://github.com/nox/serde_urlencoded
// FIXME: Make sure that all structs above Issue are not using `String`s instead of `Enum`s.
// FIXME: Harmonize the different state enums (e.g. IssueState, MergeRequestState, Authors)
// FIXME: Move all enums here (ListingOrderBy, ListingSort, etc.)
// FIXME: Use a type for sha1
// FIXME: Use chrono crate for dates
// FIXME: Use unsigned integers where it makes sense (id, iid, etc.)
// FIXME: Verify all `match` in push_str() in build_query(): They should contain all members.
// FIXME: Get rid of build_query(), use serde's Serialize instead.
// FIXME: Write nicer wrappers, getting rid of Listing.

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum ListingSort {
    #[serde(rename = "asc")]
    Asc,
    #[serde(rename = "desc")]
    Desc,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum ListingVisibility {
    #[serde(rename = "public")]
    Public,
    #[serde(rename = "internal")]
    Internal,
    #[serde(rename = "private")]
    Private,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Version {
    pub version: String,
    pub revision: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Group {
    pub id: i64,
    pub name: String,
    pub path: String,
    pub description: String,
    pub visibility_level: i64,
    pub lfs_enabled: bool,
    pub avatar_url: Option<String>,
    pub web_url: String,
    pub request_access_enabled: bool,
}

pub type Groups = Vec<Group>;

#[derive(Debug, Serialize, Deserialize)]
pub struct ProjectOwner {
    pub name: String,
    pub username: String,
    pub id: i64,
    pub state: String,
    pub avatar_url: String,
    pub web_url: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectNamespaceAvatar {
    url: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectNamespace {
    id: i64,
    name: String,
    path: String,
    owner_id: Option<i64>,  // FIXME: Why would a project not have this?
    created_at: String,  // FIXME: Date instead?
    updated_at: String,  // FIXME: Date instead?
    description: String,
    avatar: Option<ProjectNamespaceAvatar>,
    membership_lock: Option<bool>,
    share_with_group_lock: bool,
    visibility_level: i64,
    request_access_enabled: bool,
    ldap_sync_status: Option<String>,
    ldap_sync_error: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_update_at: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_successful_update_at: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_sync_at: Option<String>,  // FIXME: Is String the proper type?
    deleted_at: Option<String>,  // FIXME: Is String the proper type?
    lfs_enabled: Option<String>,  // FIXME: Is String the proper type?
    repository_size_limit: Option<String>  // FIXME: Is String the proper type?
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectForkedFrom {
    id: i64,
    http_url_to_repo: String,
    web_url: String,
    name: String,
    name_with_namespace: String,
    path: String,
    path_with_namespace: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectAccess {
    access_level: i64,
    notification_level: i64,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectPermissions {
    project_access: Option<ProjectAccess>,
    group_access: Option<ProjectAccess>,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectSharedWithGroup {
    group_id: i64,
    group_name: String,
    group_access_level: i64,
}

// https://users.rust-lang.org/t/what-am-i-doing-wrong-go-program-is-12x-faster-than-rust/5692/13
// https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/index.html
#[derive(Debug, Serialize, Deserialize)]
pub struct Project {
    id: i64,
    description: String,
    default_branch: Option<String>,
    tag_list: Vec<String>,
    public: bool,
    archived: bool,
    visibility_level: i64,
    ssh_url_to_repo: String,
    http_url_to_repo: String,
    web_url: String,
    // owner: Option<ProjectOwner>,  // FIXME: Why would a project not have an owner?
    name: String,
    name_with_namespace: String,
    path: String,
    path_with_namespace: String,
    container_registry_enabled: Option<bool>,
    issues_enabled: bool,
    merge_requests_enabled: bool,
    wiki_enabled: bool,
    builds_enabled: bool,
    snippets_enabled: bool,
    created_at: String,  // FIXME: Date instead?
    last_activity_at: String,  // FIXME: Date instead?
    shared_runners_enabled: bool,
    lfs_enabled: bool,
    creator_id: i64,
    namespace: ProjectNamespace,
    forked_from_project: Option<ProjectForkedFrom>,
    avatar_url: Option<String>,
    star_count: i64,
    forks_count: i64,
    open_issues_count: i64,
    runners_token: Option<String>,
    public_builds: bool,
    shared_with_groups: Vec<ProjectSharedWithGroup>,
    only_allow_merge_if_build_succeeds: bool,
    request_access_enabled: bool,
    only_allow_merge_if_all_discussions_are_resolved: Option<bool>,  // FIXME: Is bool the proper type?
    approvals_before_merge: Option<i64>,
    permissions: ProjectPermissions,
}

pub type Projects = Vec<Project>;

#[derive(Debug, Serialize, Deserialize)]
enum IssueState {
    #[serde(rename = "opened")]
    Opened,

    #[serde(rename = "closed")]
    Closed,
}

#[derive(Debug, Serialize, Deserialize)]
enum UserState {
    #[serde(rename = "active")]
    Active,

    #[serde(rename = "blocked")]
    Blocked,
}

#[derive(Debug, Serialize, Deserialize)]
enum MilestoneState {
    #[serde(rename = "active")]
    Active,

    #[serde(rename = "closed")]
    Closed,
}

#[derive(Debug, Serialize, Deserialize)]
struct Milestone {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: MilestoneState,
    created_at: String,  // FIXME: Use date type?
    updated_at: String,  // FIXME: Use date type?
    due_date: Option<String>  // FIXME: Use date type?
}

#[derive(Debug, Serialize, Deserialize)]
struct User {
    name: String,
    username: String,
    id: i64,
    state: UserState,
    avatar_url: Option<String>,
    web_url: Option<String>
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Issue {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: IssueState,
    created_at: String,  // FIXME: Use date type?
    updated_at: String,  // FIXME: Use date type?
    labels: Vec<String>,
    milestone: Option<Milestone>,
    assignee: Option<User>,
    author: User,
    subscribed: bool,
    user_notes_count: i64,
    upvotes: i64,
    downvotes: i64,
    due_date: Option<String>,  // FIXME: Use date type?
    confidential: bool,
    web_url: Option<String>
}

pub type Issues = Vec<Issue>;

#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum MergeRequestState {
    #[serde(rename = "merged")]
    Merged,
    #[serde(rename = "opened")]
    Opened,
    #[serde(rename = "closed")]
    Closed,
    #[serde(rename = "all")]
    All,
}

#[derive(Debug, Serialize, Deserialize)]
enum MergeRequestStatus {
    #[serde(rename = "can_be_merged")]
    CanBeMerged,
    #[serde(rename = "cannot_be_merged")]
    CannotBeMerged,
    #[serde(rename = "unchecked")]
    Unchecked,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct MergeRequest {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: MergeRequestState,
    created_at: String,  // FIXME: Use chrono crate
    updated_at: String,  // FIXME: Use chrono crate
    target_branch: String,
    source_branch: String,
    upvotes: i64,
    downvotes: i64,
    author: User,
    assignee: Option<User>,
    source_project_id: i64,
    target_project_id: i64,
    labels: Vec<String>,
    work_in_progress: bool,
    milestone: Option<Milestone>,
    merge_when_build_succeeds: bool,
    merge_status: MergeRequestStatus,
    sha: String,
    merge_commit_sha: Option<String>,
    subscribed: bool,
    user_notes_count: i64,
    should_remove_source_branch: Option<bool>,
    force_remove_source_branch: Option<bool>,
    web_url: String
}

pub type MergeRequests = Vec<MergeRequest>;
<commit_msg>Move enum at the top<commit_after>
// https://users.rust-lang.org/t/what-am-i-doing-wrong-go-program-is-12x-faster-than-rust/5692/13
// https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/index.html
// https://serde.rs/codegen-hybrid.html

// FIXME: Use https://github.com/nox/serde_urlencoded
// FIXME: Make sure that all structs above Issue are not using `String`s instead of `Enum`s.
// FIXME: Harmonize the different state enums (e.g. IssueState, MergeRequestState, Authors)
// FIXME: Move all enums here (ListingOrderBy, ListingSort, etc.)
// FIXME: Use a type for sha1
// FIXME: Use chrono crate for dates
// FIXME: Use unsigned integers where it makes sense (id, iid, etc.)
// FIXME: Verify all `match` in push_str() in build_query(): They should contain all members.
// FIXME: Get rid of build_query(), use serde's Serialize instead.
// FIXME: Write nicer wrappers, getting rid of Listing.

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum ListingSort {
    #[serde(rename = "asc")]
    Asc,
    #[serde(rename = "desc")]
    Desc,
}

#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub enum ListingVisibility {
    #[serde(rename = "public")]
    Public,
    #[serde(rename = "internal")]
    Internal,
    #[serde(rename = "private")]
    Private,
}

#[derive(Debug, Serialize, Deserialize)]
enum IssueState {
    #[serde(rename = "opened")]
    Opened,

    #[serde(rename = "closed")]
    Closed,
}

#[derive(Debug, Serialize, Deserialize)]
enum UserState {
    #[serde(rename = "active")]
    Active,

    #[serde(rename = "blocked")]
    Blocked,
}

#[derive(Debug, Serialize, Deserialize)]
enum MilestoneState {
    #[serde(rename = "active")]
    Active,

    #[serde(rename = "closed")]
    Closed,
}

#[derive(Debug, Copy, Clone, Serialize, Deserialize)]
pub enum MergeRequestState {
    #[serde(rename = "merged")]
    Merged,
    #[serde(rename = "opened")]
    Opened,
    #[serde(rename = "closed")]
    Closed,
    #[serde(rename = "all")]
    All,
}

#[derive(Debug, Serialize, Deserialize)]
enum MergeRequestStatus {
    #[serde(rename = "can_be_merged")]
    CanBeMerged,
    #[serde(rename = "cannot_be_merged")]
    CannotBeMerged,
    #[serde(rename = "unchecked")]
    Unchecked,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Version {
    pub version: String,
    pub revision: String,
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Group {
    pub id: i64,
    pub name: String,
    pub path: String,
    pub description: String,
    pub visibility_level: i64,
    pub lfs_enabled: bool,
    pub avatar_url: Option<String>,
    pub web_url: String,
    pub request_access_enabled: bool,
}

pub type Groups = Vec<Group>;

#[derive(Debug, Serialize, Deserialize)]
pub struct ProjectOwner {
    pub name: String,
    pub username: String,
    pub id: i64,
    pub state: String,
    pub avatar_url: String,
    pub web_url: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectNamespaceAvatar {
    url: Option<String>,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectNamespace {
    id: i64,
    name: String,
    path: String,
    owner_id: Option<i64>,  // FIXME: Why would a project not have this?
    created_at: String,  // FIXME: Date instead?
    updated_at: String,  // FIXME: Date instead?
    description: String,
    avatar: Option<ProjectNamespaceAvatar>,
    membership_lock: Option<bool>,
    share_with_group_lock: bool,
    visibility_level: i64,
    request_access_enabled: bool,
    ldap_sync_status: Option<String>,
    ldap_sync_error: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_update_at: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_successful_update_at: Option<String>,  // FIXME: Is String the proper type?
    ldap_sync_last_sync_at: Option<String>,  // FIXME: Is String the proper type?
    deleted_at: Option<String>,  // FIXME: Is String the proper type?
    lfs_enabled: Option<String>,  // FIXME: Is String the proper type?
    repository_size_limit: Option<String>  // FIXME: Is String the proper type?
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectForkedFrom {
    id: i64,
    http_url_to_repo: String,
    web_url: String,
    name: String,
    name_with_namespace: String,
    path: String,
    path_with_namespace: String,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectAccess {
    access_level: i64,
    notification_level: i64,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectPermissions {
    project_access: Option<ProjectAccess>,
    group_access: Option<ProjectAccess>,
}

#[derive(Debug, Serialize, Deserialize)]
struct ProjectSharedWithGroup {
    group_id: i64,
    group_name: String,
    group_access_level: i64,
}

// https://users.rust-lang.org/t/what-am-i-doing-wrong-go-program-is-12x-faster-than-rust/5692/13
// https://doc.rust-lang.org/rustc-serialize/rustc_serialize/json/index.html
#[derive(Debug, Serialize, Deserialize)]
pub struct Project {
    id: i64,
    description: String,
    default_branch: Option<String>,
    tag_list: Vec<String>,
    public: bool,
    archived: bool,
    visibility_level: i64,
    ssh_url_to_repo: String,
    http_url_to_repo: String,
    web_url: String,
    // owner: Option<ProjectOwner>,  // FIXME: Why would a project not have an owner?
    name: String,
    name_with_namespace: String,
    path: String,
    path_with_namespace: String,
    container_registry_enabled: Option<bool>,
    issues_enabled: bool,
    merge_requests_enabled: bool,
    wiki_enabled: bool,
    builds_enabled: bool,
    snippets_enabled: bool,
    created_at: String,  // FIXME: Date instead?
    last_activity_at: String,  // FIXME: Date instead?
    shared_runners_enabled: bool,
    lfs_enabled: bool,
    creator_id: i64,
    namespace: ProjectNamespace,
    forked_from_project: Option<ProjectForkedFrom>,
    avatar_url: Option<String>,
    star_count: i64,
    forks_count: i64,
    open_issues_count: i64,
    runners_token: Option<String>,
    public_builds: bool,
    shared_with_groups: Vec<ProjectSharedWithGroup>,
    only_allow_merge_if_build_succeeds: bool,
    request_access_enabled: bool,
    only_allow_merge_if_all_discussions_are_resolved: Option<bool>,  // FIXME: Is bool the proper type?
    approvals_before_merge: Option<i64>,
    permissions: ProjectPermissions,
}

pub type Projects = Vec<Project>;

#[derive(Debug, Serialize, Deserialize)]
struct Milestone {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: MilestoneState,
    created_at: String,  // FIXME: Use date type?
    updated_at: String,  // FIXME: Use date type?
    due_date: Option<String>  // FIXME: Use date type?
}

#[derive(Debug, Serialize, Deserialize)]
struct User {
    name: String,
    username: String,
    id: i64,
    state: UserState,
    avatar_url: Option<String>,
    web_url: Option<String>
}

#[derive(Debug, Serialize, Deserialize)]
pub struct Issue {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: IssueState,
    created_at: String,  // FIXME: Use date type?
    updated_at: String,  // FIXME: Use date type?
    labels: Vec<String>,
    milestone: Option<Milestone>,
    assignee: Option<User>,
    author: User,
    subscribed: bool,
    user_notes_count: i64,
    upvotes: i64,
    downvotes: i64,
    due_date: Option<String>,  // FIXME: Use date type?
    confidential: bool,
    web_url: Option<String>
}

pub type Issues = Vec<Issue>;

#[derive(Debug, Serialize, Deserialize)]
pub struct MergeRequest {
    id: i64,
    iid: i64,
    project_id: i64,
    title: String,
    description: String,
    state: MergeRequestState,
    created_at: String,  // FIXME: Use chrono crate
    updated_at: String,  // FIXME: Use chrono crate
    target_branch: String,
    source_branch: String,
    upvotes: i64,
    downvotes: i64,
    author: User,
    assignee: Option<User>,
    source_project_id: i64,
    target_project_id: i64,
    labels: Vec<String>,
    work_in_progress: bool,
    milestone: Option<Milestone>,
    merge_when_build_succeeds: bool,
    merge_status: MergeRequestStatus,
    sha: String,
    merge_commit_sha: Option<String>,
    subscribed: bool,
    user_notes_count: i64,
    should_remove_source_branch: Option<bool>,
    force_remove_source_branch: Option<bool>,
    web_url: String
}

pub type MergeRequests = Vec<MergeRequest>;
<|endoftext|>