<commit_before>//! This module lets us be more flexible wiht logging.
//! It provides different types of loggers for different purposes, if run in tui or
//! somewhere (maybe a syslog log).
use env_logger;
use flexi_logger;
use syslog::{self, Facility, Formatter3164};

pub enum Log {
    Console,
    File,
    System,
}

/// The logger for all log-types: warn, info, trace, error, debug
pub struct Logit {}

/// The very practical logger. It can use 3 types of logging yet.
///  - system logger
///  - console logging
///  - file logging (used)
impl Logit {
    pub fn init(which: Log) {
        match which {
            Log::System => {
                let formatter = Formatter3164 {
                    facility: Facility::LOG_USER,
                    hostname: None,
                    process: env!("CARGO_PKG_NAME").into(),
                    pid: 42,
                };

                match syslog::unix(formatter) {
                    Err(e) => {
                        env_logger::init();
                        error!("impossible to connect to syslog: {:?}", e);
                    }
                    Ok(mut writer) => {
                        writer
                            .err("Logit init and test!")
                            .expect("could not write error message");
                    }
                }
            }
            Log::Console => {
                env_logger::init();
            }
            Log::File => {
                // todo: fix this for binary and see for default!
                //       from console good is now:
                //       RUST_LOG=audiobookfinder=trace,adbflib=trace
                // see:
                // https://rust-lang-nursery.github.io/rust-cookbook/development_tools/debugging/config_log.html
                flexi_logger::Logger::with_env_or_str("adbflib=debug, adbflib=warn")
                    .log_to_file()
                    .directory(".")
                    .format(flexi_logger::with_thread) // colored_with_thread
                    .suppress_timestamp()
                    .suffix("log")
                    .start()
                    .unwrap_or_else(|e| panic!("Logger initialization failed with {}", e));
            }
        }
    }
}
<commit_msg>[logging] disable default logging, use RUST_LOG, give examples<commit_after>//! This module lets us be more flexible wiht logging.
//! It provides different types of loggers for different purposes, if run in tui or
//! somewhere (maybe a syslog log).
use env_logger;
use flexi_logger;
use syslog::{self, Facility, Formatter3164};

pub enum Log {
    Console,
    File,
    System,
}

/// The logger for all log-types: warn, info, trace, error, debug
pub struct Logit {}

/// The very practical logger. It can use 3 types of logging yet.
///  - system logger
///  - console logging
///  - file logging (used)
impl Logit {
    pub fn init(which: Log) {
        match which {
            Log::System => {
                let formatter = Formatter3164 {
                    facility: Facility::LOG_USER,
                    hostname: None,
                    process: env!("CARGO_PKG_NAME").into(),
                    pid: 42,
                };

                match syslog::unix(formatter) {
                    Err(e) => {
                        env_logger::init();
                        error!("impossible to connect to syslog: {:?}", e);
                    }
                    Ok(mut writer) => {
                        writer
                            .err("Logit init and test!")
                            .expect("could not write error message");
                    }
                }
            }
            Log::Console => {
                env_logger::init();
            }
            Log::File => {
                // now only from console, good is now:
                //       RUST_LOG=audiobookfinder=trace,adbflib=trace
                //       or
                //         RUST_LOG=adbflib=trace
                //         RUST_LOG=adbflib::net=trace
                //         RUST_LOG=audiobookfinder=trace,adbflib=trace
                // see:
                // https://rust-lang-nursery.github.io/rust-cookbook/development_tools/debugging/config_log.html
                flexi_logger::Logger::with_env()
                    .log_to_file()
                    .directory(".")
                    .format(flexi_logger::with_thread) // colored_with_thread
                    .suppress_timestamp()
                    .suffix("log")
                    .start()
                    .unwrap_or_else(|e| panic!("Logger initialization failed with {}", e));
            }
        }
    }
}
<|endoftext|>


<commit_before>#![crate_name="json_macros"]
#![crate_type="dylib"]
#![feature(phase, plugin_registrar, macro_rules, quote)]

#[phase(plugin, link)] extern crate log;
extern crate rustc;
extern crate syntax;
extern crate "rustc-serialize" as rustc_serialize;

use syntax::ast::TokenTree;
use syntax::codemap::Span;
use syntax::ptr::P;

use syntax::ast;
use syntax::ext::base::{ExtCtxt, MacResult, MacExpr, DummyResult};
use syntax::parse::token;
use syntax::print::pprust;
use rustc::plugin::Registry;

type PExpr = P<ast::Expr>;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("json", expand);
}

fn expand<'cx>(cx: &'cx mut ExtCtxt, sp: Span,
               tts: &[TokenTree]) -> Box<MacResult + 'cx> {
    debug!("JSON token tree {}", tts);

    let tt = match tts.get(0) {
        Some(tt) => tt,
        None => {
            cx.span_err(sp, "expected JSON literal");
            return DummyResult::expr(sp);
        }
    };

    let expr = match tt_to_expr(cx, tt) {
        Some(e) => e,
        None => return DummyResult::expr(sp)
    };
    MacExpr::new(expr)
}

fn tt_to_expr(cx: &ExtCtxt, tt: &TokenTree) -> Option<PExpr> {
    use syntax::ext::build::AstBuilder;

    match *tt {
        ast::TtToken(sp, ref tok) => token_to_expr(cx, sp, tok),
        ast::TtDelimited(sp, ref d) => {
            let ref toks = d.tts;
            match d.delim {
                // array
                token::Bracket => {
                    let exprs = match parse_array(cx, sp, toks.as_slice()) {
                        Some(e) => e,
                        None => return None
                    };
                    let exprs = cx.expr_vec(sp, exprs);
                    Some(quote_expr!(cx, {
                        {
                            use std::slice::BoxedSliceExt;
                            let xs: ::std::boxed::Box<[_]> = box $exprs;
                            ::rustc_serialize::json::Json::Array(xs.into_vec())
                        }
                    }))
                }
                // object
                token::Brace => {
                    let items = match parse_object(cx, sp, toks.as_slice()) {
                        Some(i) => i,
                        None => return None
                    };
                    let ob = quote_expr!(cx, _ob);
                    let mut stmts = vec![];
                    for &(ref key, ref value) in items.iter() {
                        stmts.push(quote_stmt!(cx, $ob.insert($key, $value)));
                    }

                    Some(quote_expr!(cx, {
                        {
                            let mut $ob = ::std::collections::BTreeMap::new();
                            $stmts;
                            ::rustc_serialize::json::Json::Object($ob)
                        }
                    }))
                }
                token::Paren => {
                    let mut parser = cx.new_parser_from_tts(toks.as_slice());
                    let expr = parser.parse_expr();

                    Some(quote_expr!(cx, {
                        use rustc_serialize::json::ToJson;
                        ($expr).to_json()
                    }))
                }
            }
        }
        ast::TtSequence(sp, _) => {
            cx.span_err(sp, "`json!` unexpected TtSequence");
            None
        }
    }
}

fn parse_array(cx: &ExtCtxt, sp: Span, tts: &[TokenTree]) -> Option<Vec<PExpr>> {
    let mut exprs = Vec::with_capacity(tts.len() / 2);
    for (i, tt) in tts.iter().enumerate() {
        if i % 2 == 1 {
            match tt {
                &ast::TtToken(_, token::Comma) => {
                    continue;
                }
                _ => {
                    expected_but_found(cx, sp, "`,`", tt);
                    return None;
                }
            }
        }
        let expr = tt_to_expr(cx, tt);
        let expr = match expr {
            Some(e) => e,
            None => return None,
        };
        exprs.push(expr);
    }
    Some(exprs)
}

fn parse_object(cx: &ExtCtxt, sp: Span, tts: &[TokenTree]) -> Option<Vec<(PExpr, PExpr)>> {
    use syntax::ast::TtToken;

    macro_rules! comma {
        () => {
            ::syntax::ast::TtToken(_, ::syntax::parse::token::Comma)
        }
    }

    macro_rules! colon {
        () => {
            ::syntax::ast::TtToken(_, ::syntax::parse::token::Colon)
        };
        ($sp:ident) => {
            ::syntax::ast::TtToken($sp, ::syntax::parse::token::Colon)
        }
    }

    let mut items = Vec::with_capacity(tts.len() / 4);
    if tts.len() == 0 {
        return Some(items);
    }

    // horrible
    for entry in tts.chunks(4) {
        use syntax::parse::token::{Lit, Literal};
        let item = match entry {
            // "foo": VALUE | "foo": VALUE,
            [TtToken(_, Literal(Lit::Str_(ref n), _)), colon!(), ref v] |
            [TtToken(_, Literal(Lit::Str_(ref n), _)), colon!(), ref v, comma!()] => {
                let k = n.as_str();
                let v = tt_to_expr(cx, v);
                if v.is_none() {
                    return None;
                }
                let k = quote_expr!(cx, $k.into_string());
                let v = quote_expr!(cx, $v);
                (k, v)
            }
            // "foo": VALUE X
            [TtToken(_, Literal(Lit::Str_(_), _)), colon!(), _, ref tt] => {
                expected_but_found(cx, sp, "`,`", tt);
                return None;
            }
            [TtToken(_, Literal(Lit::Str_(_), _)), colon!(sp)] => {
                cx.span_err(sp, "found `:` but no value afterwards");
                return None;
            }
            [TtToken(_, Literal(Lit::Str_(_) ,_)), ref tt, ..] => {
                expected_but_found(cx, sp, "`:`", tt);
                return None;
            }
            [TtToken(sp, Literal(Lit::Str_(_), _))] => {
                cx.span_err(sp, "found name but no colon-value afterwards");
                return None;
            }
            [ref tt, ..] => {
                expected_but_found(cx, sp, "string literal", tt);
                return None;
            }
            [] => unreachable!(), // chunks() never returns an empty slice
        };
        items.push(item);
    }

    Some(items)
}

fn token_to_expr(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> Option<PExpr> {
    use syntax::print::pprust;
    use syntax::parse::token::{Lit, Literal};

    match *tok {
        Literal(Lit::Str_(ref n), _) => {
            let s = n.as_str();
            Some(quote_expr!(cx, {
                ::rustc_serialize::json::Json::String($s.into_string())
            }))
        }
        // FIXME: handle suffixed literals (i.e. u64) correctly
        // FIXME: handle negative numbers
        Literal(Lit::Integer(_), _)=> {
            let tt = ast::TtToken(sp, tok.clone());
            Some(quote_expr!(cx, {
                ::rustc_serialize::json::Json::I64($tt as i64)
            }))
        }
        Literal(Lit::Float(_), _) => {
            let tt = ast::TtToken(sp, tok.clone());
            Some(quote_expr!(cx, {
                ::rustc_serialize::json::Json::F64($tt)
            }))
        }
        token::Ident(ref id, token::Plain) if id.as_str() == "null" => {
            Some(quote_expr!(cx, {
                ::rustc_serialize::json::Json::Null
            }))
        }
        ref t @ token::Ident(..) if t.is_keyword(token::keywords::True) => {
            Some(quote_expr!(cx, { ::rustc_serialize::json::Json::Boolean(true) }))
        }
        ref t @ token::Ident(..) if t.is_keyword(token::keywords::False) => {
            Some(quote_expr!(cx, { ::rustc_serialize::json::Json::Boolean(false) }))
        }
        _ => {
            let tt = ast::TtToken(sp, tok.clone());
            let s = pprust::tt_to_string(&tt);
            cx.span_err(sp, format!("unexpected `{}` in JSON", s).as_slice());
            None
        }
    }
}

fn best_span(sp: Span, tt: &TokenTree) -> Span {
    let sp = match *tt {
        ast::TtToken(tok_sp, _) => tok_sp,
        _ => sp // the span passed into the function!
    };
    sp
}

fn expected_but_found(cx: &ExtCtxt, sp: Span, expected: &str, found: &TokenTree) {
    let pp = pprust::tt_to_string(found);
    let err = format!("expected {} but found: `{}`", expected, pp);
    cx.span_err(best_span(sp, found), err.as_slice());
}
<commit_msg>Only log when not ndebug<commit_after>#![crate_name="json_macros"]
#![crate_type="dylib"]
#![feature(phase, plugin_registrar, macro_rules, quote)]

#[cfg(not(ndebug))] #[phase(plugin, link)] extern crate log;
extern crate rustc;
extern crate syntax;
extern crate "rustc-serialize" as rustc_serialize;

use syntax::ast::TokenTree;
use syntax::codemap::Span;
use syntax::ptr::P;

use syntax::ast;
use syntax::ext::base::{ExtCtxt, MacResult, MacExpr, DummyResult};
use syntax::parse::token;
use syntax::print::pprust;
use rustc::plugin::Registry;

type PExpr = P<ast::Expr>;

#[plugin_registrar]
pub fn plugin_registrar(reg: &mut Registry) {
    reg.register_macro("json", expand);
}

#[cfg(not(ndebug))]
fn log_tree(tts: &[TokenTree]) {
    debug!("JSON token tree {}", tts);
}

#[cfg(ndebug)]
fn log_tree(_: &[TokenTree]) { }

fn expand<'cx>(cx: &'cx mut ExtCtxt, sp: Span,
               tts: &[TokenTree]) -> Box<MacResult + 'cx> {
    log_tree(tts);

    let tt = match tts.get(0) {
        Some(tt) => tt,
        None => {
            cx.span_err(sp, "expected JSON literal");
            return DummyResult::expr(sp);
        }
    };

    let expr = match tt_to_expr(cx, tt) {
        Some(e) => e,
        None => return DummyResult::expr(sp)
    };
    MacExpr::new(expr)
}

fn tt_to_expr(cx: &ExtCtxt, tt: &TokenTree) -> Option<PExpr> {
    use syntax::ext::build::AstBuilder;

    match *tt {
        ast::TtToken(sp, ref tok) => token_to_expr(cx, sp, tok),
        ast::TtDelimited(sp, ref d) => {
            let ref toks = d.tts;
            match d.delim {
                // array
                token::Bracket => {
                    let exprs = match parse_array(cx, sp, toks.as_slice()) {
                        Some(e) => e,
                        None => return None
                    };
                    let exprs = cx.expr_vec(sp, exprs);
                    Some(quote_expr!(cx, {
                        {
                            use std::slice::BoxedSliceExt;
                            let xs: ::std::boxed::Box<[_]> = box $exprs;
                            ::rustc_serialize::json::Json::Array(xs.into_vec())
                        }
                    }))
                }
                // object
                token::Brace => {
                    let items = match parse_object(cx, sp, toks.as_slice()) {
                        Some(i) => i,
                        None => return None
                    };
                    let ob = quote_expr!(cx, _ob);
                    let mut stmts = vec![];
                    for &(ref key, ref value) in items.iter() {
                        stmts.push(quote_stmt!(cx, $ob.insert($key, $value)));
                    }

                    Some(quote_expr!(cx, {
                        {
                            let mut $ob = ::std::collections::BTreeMap::new();
                            $stmts;
                            ::rustc_serialize::json::Json::Object($ob)
                        }
                    }))
                }
                token::Paren => {
                    let mut parser = cx.new_parser_from_tts(toks.as_slice());
                    let expr = parser.parse_expr();

                    Some(quote_expr!(cx, {
                        use rustc_serialize::json::ToJson;
                        ($expr).to_json()
                    }))
                }
            }
        }
        ast::TtSequence(sp, _) => {
            cx.span_err(sp, "`json!` unexpected TtSequence");
            None
        }
    }
}

fn parse_array(cx: &ExtCtxt, sp: Span, tts: &[TokenTree]) -> Option<Vec<PExpr>> {
    let mut exprs = Vec::with_capacity(tts.len() / 2);
    for (i, tt) in tts.iter().enumerate() {
        if i % 2 == 1 {
            match tt {
                &ast::TtToken(_, token::Comma) => {
                    continue;
                }
                _ => {
                    expected_but_found(cx, sp, "`,`", tt);
                    return None;
                }
            }
        }
        let expr = tt_to_expr(cx, tt);
        let expr = match expr {
            Some(e) => e,
            None => return None,
        };
        exprs.push(expr);
    }
    Some(exprs)
}

fn parse_object(cx: &ExtCtxt, sp: Span, tts: &[TokenTree]) -> Option<Vec<(PExpr, PExpr)>> {
    use syntax::ast::TtToken;

    macro_rules! comma {
        () => {
            ::syntax::ast::TtToken(_, ::syntax::parse::token::Comma)
        }
    }

    macro_rules! colon {
        () => {
            ::syntax::ast::TtToken(_, ::syntax::parse::token::Colon)
        };
        ($sp:ident) => {
            ::syntax::ast::TtToken($sp, ::syntax::parse::token::Colon)
        }
    }

    let mut items = Vec::with_capacity(tts.len() / 4);
    if tts.len() == 0 {
        return Some(items);
    }

    // horrible
    for entry in tts.chunks(4) {
        use syntax::parse::token::{Lit, Literal};
        let item = match entry {
            // "foo": VALUE | "foo": VALUE,
            [TtToken(_, Literal(Lit::Str_(ref n), _)), colon!(), ref v] |
            [TtToken(_, Literal(Lit::Str_(ref n), _)), colon!(), ref v, comma!()] => {
                let k = n.as_str();
                let v = tt_to_expr(cx, v);
                if v.is_none() {
                    return None;
                }
                let k = quote_expr!(cx, $k.into_string());
                let v = quote_expr!(cx, $v);
                (k, v)
            }
            // "foo": VALUE X
            [TtToken(_, Literal(Lit::Str_(_), _)), colon!(), _, ref tt] => {
                expected_but_found(cx, sp, "`,`", tt);
                return None;
            }
            [TtToken(_, Literal(Lit::Str_(_), _)), colon!(sp)] => {
                cx.span_err(sp, "found `:` but no value afterwards");
                return None;
            }
            [TtToken(_, Literal(Lit::Str_(_) ,_)), ref tt, ..] => {
                expected_but_found(cx, sp, "`:`", tt);
                return None;
            }
            [TtToken(sp, Literal(Lit::Str_(_), _))] => {
                cx.span_err(sp, "found name but no colon-value afterwards");
                return None;
            }
            [ref tt, ..] => {
                expected_but_found(cx, sp, "string literal", tt);
                return None;
            }
            [] => unreachable!(), // chunks() never returns an empty slice
        };
        items.push(item);
    }

    Some(items)
}

fn token_to_expr(cx: &ExtCtxt, sp: Span, tok: &token::Token) -> Option<PExpr> {
    use syntax::print::pprust;
    use syntax::parse::token::{Lit, Literal};

    match *tok {
        Literal(Lit::Str_(ref n), _) => {
            let s = n.as_str();
            Some(quote_expr!(cx, {
                ::rustc_serialize::json::Json::String($s.into_string())
            }))
        }
        // FIXME: handle suffixed literals (i.e. u64) correctly
        // FIXME: handle negative numbers
        Literal(Lit::Integer(_), _)=> {
            let tt = ast::TtToken(sp, tok.clone());
            Some(quote_expr!(cx, {
                ::rustc_serialize::json::Json::I64($tt as i64)
            }))
        }
        Literal(Lit::Float(_), _) => {
            let tt = ast::TtToken(sp, tok.clone());
            Some(quote_expr!(cx, {
                ::rustc_serialize::json::Json::F64($tt)
            }))
        }
        token::Ident(ref id, token::Plain) if id.as_str() == "null" => {
            Some(quote_expr!(cx, {
                ::rustc_serialize::json::Json::Null
            }))
        }
        ref t @ token::Ident(..) if t.is_keyword(token::keywords::True) => {
            Some(quote_expr!(cx, { ::rustc_serialize::json::Json::Boolean(true) }))
        }
        ref t @ token::Ident(..) if t.is_keyword(token::keywords::False) => {
            Some(quote_expr!(cx, { ::rustc_serialize::json::Json::Boolean(false) }))
        }
        _ => {
            let tt = ast::TtToken(sp, tok.clone());
            let s = pprust::tt_to_string(&tt);
            cx.span_err(sp, format!("unexpected `{}` in JSON", s).as_slice());
            None
        }
    }
}

fn best_span(sp: Span, tt: &TokenTree) -> Span {
    let sp = match *tt {
        ast::TtToken(tok_sp, _) => tok_sp,
        _ => sp // the span passed into the function!
    };
    sp
}

fn expected_but_found(cx: &ExtCtxt, sp: Span, expected: &str, found: &TokenTree) {
    let pp = pprust::tt_to_string(found);
    let err = format!("expected {} but found: `{}`", expected, pp);
    cx.span_err(best_span(sp, found), err.as_slice());
}
<|endoftext|>


<commit_before>#![feature(rustc_attrs, rustc_private, step_trait)]

#[macro_use] extern crate rustc_data_structures;
extern crate rustc_serialize;

use rustc_data_structures::indexed_vec::Idx;

newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA });

use std::mem::size_of;

fn main() {
    assert_eq!(size_of::<MyIdx>(), 4);
    assert_eq!(size_of::<Option<MyIdx>>(), 4);
    assert_eq!(size_of::<Option<Option<MyIdx>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<MyIdx>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<MyIdx>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<MyIdx>>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<Option<MyIdx>>>>>>>(), 8);
}
<commit_msg>Use sysroot libserialize in newtype_index test<commit_after>#![feature(rustc_attrs, rustc_private, step_trait)]

#[macro_use] extern crate rustc_data_structures;
extern crate serialize as rustc_serialize;

use rustc_data_structures::indexed_vec::Idx;

newtype_index!(struct MyIdx { MAX = 0xFFFF_FFFA });

use std::mem::size_of;

fn main() {
    assert_eq!(size_of::<MyIdx>(), 4);
    assert_eq!(size_of::<Option<MyIdx>>(), 4);
    assert_eq!(size_of::<Option<Option<MyIdx>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<MyIdx>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<MyIdx>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<MyIdx>>>>>>(), 4);
    assert_eq!(size_of::<Option<Option<Option<Option<Option<Option<MyIdx>>>>>>>(), 8);
}
<|endoftext|>


<commit_before>use std::hash::Hash;
use std::iter::Iterator;

use ::{Graph, Target};
use ::hidden::base::{Arc, ArcId, StateId, Vertex};

/// Immutable handle to a graph vertex ("node handle").
///
/// This zipper-like type enables traversal of a graph along the vertex's
/// incoming and outgoing edges.
pub struct Node<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: StateId,
}

/// Creates a new `Node` for the given graph and gamestate. This method is not
/// exported by the crate because it exposes implementation details. It is used
/// to provide a public cross-module interface for creating new `Node`s.
pub fn make_node<'a, T, S, A>(graph: &'a Graph<T, S, A>, id: StateId) -> Node<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        Node { graph: graph, id: id, }
    }

impl<'a, T, S, A> Node<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    fn children(&self) -> &'a [ArcId] {
        &self.graph.get_vertex(self.id).children
    }

    /// Returns an immutable ID that is guaranteed to identify this vertex
    /// uniquely within its graph. This ID may change when the graph is mutated.
    pub fn get_id(&self) -> usize {
        self.id.as_usize()
    }

    fn parents(&self) -> &'a [ArcId] {
        &self.graph.get_vertex(self.id).parents
    }

    /// Returns the data at this vertex.
    pub fn get_data(&self) -> &'a S {
        &self.graph.get_vertex(self.id).data
    }

    /// Returns true iff this vertex has no outgoing edges (regardless of
    /// whether they are expanded).
    pub fn is_leaf(&self) -> bool {
        self.children().is_empty()
    }

    /// Returns true iff this vertex has no incoming edges.
    pub fn is_root(&self) -> bool {
        self.parents().is_empty()
    }

    /// Returns a traversible list of outgoing edges.
    pub fn get_child_list(&self) -> ChildList<'a, T, S, A> {
        ChildList { graph: self.graph, id: self.id, }
    }

    /// Returns a traversible list of incoming edges.
    pub fn get_parent_list(&self) -> ParentList<'a, T, S, A> {
        ParentList { graph: self.graph, id: self.id, }
    }
}

/// A traversible list of a vertex's outgoing edges.
pub struct ChildList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: StateId,
}

/// Creates a new `ChildList` for the given graph and gamestate. This method is
/// not exported by the crate because it exposes implementation details. It is
/// used to provide a public cross-module interface for creating new
/// `ChildList`s.
pub fn make_child_list<'a, T, S, A>(graph: &'a Graph<T, S, A>, id: StateId) -> ChildList<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        ChildList { graph: graph, id: id, }
    }

impl<'a, T, S, A> ChildList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    fn vertex(&self) -> &'a Vertex<S> {
        self.graph.get_vertex(self.id)
    }

    /// Returns the number of edges.
    pub fn len(&self) -> usize {
        self.vertex().children.len()
    }

    /// Returns true iff there are no outgoing edges.
    pub fn is_empty(&self) -> bool {
        self.vertex().children.is_empty()
    }

    /// Returns a node handle for the vertex these edges originate from.
    pub fn get_source_node(&self) -> Node<'a, T, S, A> {
        Node { graph: self.graph, id: self.id, }
    }

    /// Returns an edge handle for the `i`th edge.
    pub fn get_edge(&self, i: usize) -> Edge<'a, T, S, A> {
        Edge { graph: self.graph, id: self.vertex().children[i], }
    }

    /// Returns an iterator over child edges.
    pub fn iter(&self) -> ChildListIter<'a, T, S, A> {
        ChildListIter { graph: self.graph, id: self.id, i: 0, }
    }
}

pub struct ChildListIter<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: StateId,
    i: usize,
}

impl <'a, T, S, A> ChildListIter<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        fn children(&self) -> &'a [ArcId] {
            &self.graph.get_vertex(self.id).children
        }
    }

impl<'a, T, S, A> Iterator for ChildListIter<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        type Item = Edge<'a, T, S, A>;

        fn next(&mut self) -> Option<Edge<'a, T, S, A>> {
            let cs = self.children();
            if self.i >= cs.len() {
                None
            } else {
                let e = make_edge(self.graph, cs[self.i]);
                self.i += 1;
                Some(e)
            }
        }

        fn size_hint(&self) -> (usize, Option<usize>) {
            let l = self.children().len();
            if l <= self.i {
                (0, Some(0))
            } else {
                (l - self.i, Some(l - self.i))
            }
        }
    }

/// A traversible list of a vertex's incoming edges.
pub struct ParentList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: StateId,
}

/// Creates a new `ParentList` for the given graph and gamestate. This method is
/// not exported by the crate because it exposes implementation details. It is
/// used to provide a public cross-module interface for creating new
/// `ParentList`s.
pub fn make_parent_list<'a, T, S, A>(graph: &'a Graph<T, S, A>, id: StateId) -> ParentList<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        ParentList { graph: graph, id: id, }
    }

impl<'a, T, S, A> ParentList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    fn vertex(&self) -> &'a Vertex<S> {
        self.graph.get_vertex(self.id)
    }

    /// Returns the number of edges.
    pub fn len(&self) -> usize {
        self.vertex().parents.len()
    }

    /// Returns true iff there are no incoming edges.
    pub fn is_empty(&self) -> bool {
        self.vertex().parents.is_empty()
    }

    /// Returns a node handle for the vertex these edges point to.
    pub fn target_node(&self) -> Node<'a, T, S, A> {
        Node { graph: self.graph, id: self.id, }
    }

    /// Returns an edge handle for the `i`th edge.
    pub fn get_edge(&self, i: usize) -> Edge<'a, T, S, A> {
        Edge { graph: self.graph, id: self.vertex().parents[i] }
    }

    /// Returns an iterator over parent edges.
    pub fn iter(&self) -> ParentListIter<'a, T, S, A> {
        ParentListIter { graph: self.graph, id: self.id, i: 0, }
    }
}

pub struct ParentListIter<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: StateId,
    i: usize,
}

impl<'a, T, S, A> ParentListIter<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    fn parents(&self) -> &'a [ArcId] {
        &self.graph.get_vertex(self.id).parents
    }
}

impl<'a, T, S, A> Iterator for ParentListIter<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        type Item = Edge<'a, T, S, A>;

        fn next(&mut self) -> Option<Edge<'a, T, S, A>> {
            let ps = self.parents();
            if self.i >= ps.len() {
                None
            } else {
                let e = make_edge(self.graph, ps[self.i]);
                self.i += 1;
                Some(e)
            }
        }

        fn size_hint(&self) -> (usize, Option<usize>) {
            let l = self.parents().len();
            if l <= self.i {
                (0, Some(0))
            } else {
                (l - self.i, Some(l - self.i))
            }
        }
    }

/// Immutable handle to a graph edge ("edge handle").
///
/// This zipper-like type enables traversal of a graph along the edge's source
/// and target vertices.
pub struct Edge<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: ArcId,
}

/// Creates a new `Edge` for the given graph and gamestate. This method is not
/// exported by the crate because it exposes implementation details. It is used
/// to provide a public cross-module interface for creating new `Edge`s.
pub fn make_edge<'a, T, S, A>(graph: &'a Graph<T, S, A>, id: ArcId) -> Edge<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        Edge { graph: graph, id: id, }
    }

impl<'a, T, S, A> Edge<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    fn arc(&self) -> &'a Arc<A> {
        self.graph.get_arc(self.id)
    }

    /// Returns an immutable ID that is guaranteed to identify this edge
    /// uniquely within its graph.  This ID may change when the graph is
    /// mutated.
    pub fn get_id(&self) -> usize {
        self.id.as_usize()
    }

    /// Returns the data at this edge.
    pub fn get_data(&self) -> &'a A {
        &self.arc().data
    }

    /// Returns a node handle for this edge's source vertex.
    pub fn get_source(&self) -> Node<'a, T, S, A> {
        Node { graph: self.graph, id: self.arc().source, }
    }

    /// Returns the target of this edge. If the edge is unexpanded, no data will
    /// be available. If it is expanded, a node handle will be available.
    pub fn get_target(&self) -> Target<Node<'a, T, S, A>, ()> {
        match self.arc().target {
            Target::Unexpanded(_) => Target::Unexpanded(()),
            Target::Expanded(id) => Target::Expanded(Node { graph: self.graph, id: id, }),
        }
    }
}
<commit_msg>Add missing comments for nav parent/child iters.<commit_after>use std::hash::Hash;
use std::iter::Iterator;

use ::{Graph, Target};
use ::hidden::base::{Arc, ArcId, StateId, Vertex};

/// Immutable handle to a graph vertex ("node handle").
///
/// This zipper-like type enables traversal of a graph along the vertex's
/// incoming and outgoing edges.
pub struct Node<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: StateId,
}

/// Creates a new `Node` for the given graph and gamestate. This method is not
/// exported by the crate because it exposes implementation details. It is used
/// to provide a public cross-module interface for creating new `Node`s.
pub fn make_node<'a, T, S, A>(graph: &'a Graph<T, S, A>, id: StateId) -> Node<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        Node { graph: graph, id: id, }
    }

impl<'a, T, S, A> Node<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    fn children(&self) -> &'a [ArcId] {
        &self.graph.get_vertex(self.id).children
    }

    /// Returns an immutable ID that is guaranteed to identify this vertex
    /// uniquely within its graph. This ID may change when the graph is mutated.
    pub fn get_id(&self) -> usize {
        self.id.as_usize()
    }

    fn parents(&self) -> &'a [ArcId] {
        &self.graph.get_vertex(self.id).parents
    }

    /// Returns the data at this vertex.
    pub fn get_data(&self) -> &'a S {
        &self.graph.get_vertex(self.id).data
    }

    /// Returns true iff this vertex has no outgoing edges (regardless of
    /// whether they are expanded).
    pub fn is_leaf(&self) -> bool {
        self.children().is_empty()
    }

    /// Returns true iff this vertex has no incoming edges.
    pub fn is_root(&self) -> bool {
        self.parents().is_empty()
    }

    /// Returns a traversible list of outgoing edges.
    pub fn get_child_list(&self) -> ChildList<'a, T, S, A> {
        ChildList { graph: self.graph, id: self.id, }
    }

    /// Returns a traversible list of incoming edges.
    pub fn get_parent_list(&self) -> ParentList<'a, T, S, A> {
        ParentList { graph: self.graph, id: self.id, }
    }
}

/// A traversible list of a vertex's outgoing edges.
pub struct ChildList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: StateId,
}

/// Creates a new `ChildList` for the given graph and gamestate. This method is
/// not exported by the crate because it exposes implementation details. It is
/// used to provide a public cross-module interface for creating new
/// `ChildList`s.
pub fn make_child_list<'a, T, S, A>(graph: &'a Graph<T, S, A>, id: StateId) -> ChildList<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        ChildList { graph: graph, id: id, }
    }

impl<'a, T, S, A> ChildList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    fn vertex(&self) -> &'a Vertex<S> {
        self.graph.get_vertex(self.id)
    }

    /// Returns the number of edges.
    pub fn len(&self) -> usize {
        self.vertex().children.len()
    }

    /// Returns true iff there are no outgoing edges.
    pub fn is_empty(&self) -> bool {
        self.vertex().children.is_empty()
    }

    /// Returns a node handle for the vertex these edges originate from.
    pub fn get_source_node(&self) -> Node<'a, T, S, A> {
        Node { graph: self.graph, id: self.id, }
    }

    /// Returns an edge handle for the `i`th edge.
    pub fn get_edge(&self, i: usize) -> Edge<'a, T, S, A> {
        Edge { graph: self.graph, id: self.vertex().children[i], }
    }

    /// Returns an iterator over child edges.
    pub fn iter(&self) -> ChildListIter<'a, T, S, A> {
        ChildListIter { graph: self.graph, id: self.id, i: 0, }
    }
}

/// Iterator over a vertex's child edges.
pub struct ChildListIter<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: StateId,
    i: usize,
}

impl <'a, T, S, A> ChildListIter<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        fn children(&self) -> &'a [ArcId] {
            &self.graph.get_vertex(self.id).children
        }
    }

impl<'a, T, S, A> Iterator for ChildListIter<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        type Item = Edge<'a, T, S, A>;

        fn next(&mut self) -> Option<Edge<'a, T, S, A>> {
            let cs = self.children();
            if self.i >= cs.len() {
                None
            } else {
                let e = make_edge(self.graph, cs[self.i]);
                self.i += 1;
                Some(e)
            }
        }

        fn size_hint(&self) -> (usize, Option<usize>) {
            let l = self.children().len();
            if l <= self.i {
                (0, Some(0))
            } else {
                (l - self.i, Some(l - self.i))
            }
        }
    }

/// A traversible list of a vertex's incoming edges.
pub struct ParentList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: StateId,
}

/// Creates a new `ParentList` for the given graph and gamestate. This method is
/// not exported by the crate because it exposes implementation details. It is
/// used to provide a public cross-module interface for creating new
/// `ParentList`s.
pub fn make_parent_list<'a, T, S, A>(graph: &'a Graph<T, S, A>, id: StateId) -> ParentList<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        ParentList { graph: graph, id: id, }
    }

impl<'a, T, S, A> ParentList<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    fn vertex(&self) -> &'a Vertex<S> {
        self.graph.get_vertex(self.id)
    }

    /// Returns the number of edges.
    pub fn len(&self) -> usize {
        self.vertex().parents.len()
    }

    /// Returns true iff there are no incoming edges.
    pub fn is_empty(&self) -> bool {
        self.vertex().parents.is_empty()
    }

    /// Returns a node handle for the vertex these edges point to.
    pub fn target_node(&self) -> Node<'a, T, S, A> {
        Node { graph: self.graph, id: self.id, }
    }

    /// Returns an edge handle for the `i`th edge.
    pub fn get_edge(&self, i: usize) -> Edge<'a, T, S, A> {
        Edge { graph: self.graph, id: self.vertex().parents[i] }
    }

    /// Returns an iterator over parent edges.
    pub fn iter(&self) -> ParentListIter<'a, T, S, A> {
        ParentListIter { graph: self.graph, id: self.id, i: 0, }
    }
}

/// Iterator over a vertex's parent edges.
pub struct ParentListIter<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: StateId,
    i: usize,
}

impl<'a, T, S, A> ParentListIter<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    fn parents(&self) -> &'a [ArcId] {
        &self.graph.get_vertex(self.id).parents
    }
}

impl<'a, T, S, A> Iterator for ParentListIter<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        type Item = Edge<'a, T, S, A>;

        fn next(&mut self) -> Option<Edge<'a, T, S, A>> {
            let ps = self.parents();
            if self.i >= ps.len() {
                None
            } else {
                let e = make_edge(self.graph, ps[self.i]);
                self.i += 1;
                Some(e)
            }
        }

        fn size_hint(&self) -> (usize, Option<usize>) {
            let l = self.parents().len();
            if l <= self.i {
                (0, Some(0))
            } else {
                (l - self.i, Some(l - self.i))
            }
        }
    }

/// Immutable handle to a graph edge ("edge handle").
///
/// This zipper-like type enables traversal of a graph along the edge's source
/// and target vertices.
pub struct Edge<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    graph: &'a Graph<T, S, A>,
    id: ArcId,
}

/// Creates a new `Edge` for the given graph and gamestate. This method is not
/// exported by the crate because it exposes implementation details. It is used
/// to provide a public cross-module interface for creating new `Edge`s.
pub fn make_edge<'a, T, S, A>(graph: &'a Graph<T, S, A>, id: ArcId) -> Edge<'a, T, S, A>
    where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
        Edge { graph: graph, id: id, }
    }

impl<'a, T, S, A> Edge<'a, T, S, A> where T: Hash + Eq + Clone + 'a, S: 'a, A: 'a {
    fn arc(&self) -> &'a Arc<A> {
        self.graph.get_arc(self.id)
    }

    /// Returns an immutable ID that is guaranteed to identify this edge
    /// uniquely within its graph.  This ID may change when the graph is
    /// mutated.
    pub fn get_id(&self) -> usize {
        self.id.as_usize()
    }

    /// Returns the data at this edge.
    pub fn get_data(&self) -> &'a A {
        &self.arc().data
    }

    /// Returns a node handle for this edge's source vertex.
    pub fn get_source(&self) -> Node<'a, T, S, A> {
        Node { graph: self.graph, id: self.arc().source, }
    }

    /// Returns the target of this edge. If the edge is unexpanded, no data will
    /// be available. If it is expanded, a node handle will be available.
    pub fn get_target(&self) -> Target<Node<'a, T, S, A>, ()> {
        match self.arc().target {
            Target::Unexpanded(_) => Target::Unexpanded(()),
            Target::Expanded(id) => Target::Expanded(Node { graph: self.graph, id: id, }),
        }
    }
}
<|endoftext|>


<commit_before>use core::ops::{Add, Mul};
use core::num::Wrapping;

/// Defines an additive identity element for `Self`.
pub trait Zero: Sized + Add<Self, Output = Self> {
    /// Returns the additive identity element of `Self`, `0`.
    ///
    /// # Laws
    ///
    /// ```{.text}
    /// a + 0 = a       ∀ a ∈ Self
    /// 0 + a = a       ∀ a ∈ Self
    /// ```
    ///
    /// # Purity
    ///
    /// This function should return the same result at all times regardless of
    /// external mutable state, for example values stored in TLS or in
    /// `static mut`s.
    // FIXME (#5527): This should be an associated constant
    fn zero() -> Self;

    /// Returns `true` if `self` is equal to the additive identity.
    #[inline]
    fn is_zero(&self) -> bool;
}

macro_rules! zero_impl {
    ($t:ty, $v:expr) => {
        impl Zero for $t {
            #[inline]
            fn zero() -> $t { $v }
            #[inline]
            fn is_zero(&self) -> bool { *self == $v }
        }
    }
}

zero_impl!(usize, 0usize);
zero_impl!(u8,    0u8);
zero_impl!(u16,   0u16);
zero_impl!(u32,   0u32);
zero_impl!(u64,   0u64);

zero_impl!(isize, 0isize);
zero_impl!(i8,    0i8);
zero_impl!(i16,   0i16);
zero_impl!(i32,   0i32);
zero_impl!(i64,   0i64);

zero_impl!(f32, 0.0f32);
zero_impl!(f64, 0.0f64);

impl<T: Zero> Zero for Wrapping<T> where Wrapping<T>: Add<Output=Wrapping<T>> {
    fn is_zero(&self) -> bool {
        self.0.is_zero()
    }
    fn zero() -> Self {
        Wrapping(T::zero())
    }
}

/// Defines a multiplicative identity element for `Self`.
pub trait One: Sized + Mul<Self, Output = Self> {
    /// Returns the multiplicative identity element of `Self`, `1`.
    ///
    /// # Laws
    ///
    /// ```{.text}
    /// a * 1 = a       ∀ a ∈ Self
    /// 1 * a = a       ∀ a ∈ Self
    /// ```
    ///
    /// # Purity
    ///
    /// This function should return the same result at all times regardless of
    /// external mutable state, for example values stored in TLS or in
    /// `static mut`s.
    // FIXME (#5527): This should be an associated constant
    fn one() -> Self;
}

macro_rules! one_impl {
    ($t:ty, $v:expr) => {
        impl One for $t {
            #[inline]
            fn one() -> $t { $v }
        }
    }
}

one_impl!(usize, 1usize);
one_impl!(u8,    1u8);
one_impl!(u16,   1u16);
one_impl!(u32,   1u32);
one_impl!(u64,   1u64);

one_impl!(isize, 1isize);
one_impl!(i8,    1i8);
one_impl!(i16,   1i16);
one_impl!(i32,   1i32);
one_impl!(i64,   1i64);

one_impl!(f32, 1.0f32);
one_impl!(f64, 1.0f64);

impl<T: One> One for Wrapping<T> where Wrapping<T>: Mul<Output=Wrapping<T>> {
    fn one() -> Self {
        Wrapping(T::one())
    }
}

// Some helper functions provided for backwards compatibility.

/// Returns the additive identity, `0`.
#[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() }

/// Returns the multiplicative identity, `1`.
#[inline(always)] pub fn one<T: One>() -> T { One::one() }

#[test]
fn wrapping_identities() {
    macro_rules! test_wrapping_identities {
        ($($t:ty)+) => {
            $(
                assert_eq!(zero::<$t>(), zero::<Wrapping<$t>>().0);
                assert_eq!(one::<$t>(), one::<Wrapping<$t>>().0);
                assert_eq!((0 as $t).is_zero(), Wrapping(0 as $t).is_zero());
                assert_eq!((1 as $t).is_zero(), Wrapping(1 as $t).is_zero());
            )+
        };
    }

    test_wrapping_identities!(isize i8 i16 i32 i64 usize u8 u16 u32 u64);
}

#[test]
fn wrapping_is_zero() {
    fn require_zero<T: Zero>(_: &T) {}
    require_zero(&Wrapping(42));
}
#[test]
fn wrapping_is_one() {
    fn require_one<T: One>(_: &T) {}
    require_one(&Wrapping(42));
}
<commit_msg>Add is_one.<commit_after>use core::ops::{Add, Mul};
use core::num::Wrapping;

/// Defines an additive identity element for `Self`.
pub trait Zero: Sized + Add<Self, Output = Self> {
    /// Returns the additive identity element of `Self`, `0`.
    ///
    /// # Laws
    ///
    /// ```{.text}
    /// a + 0 = a       ∀ a ∈ Self
    /// 0 + a = a       ∀ a ∈ Self
    /// ```
    ///
    /// # Purity
    ///
    /// This function should return the same result at all times regardless of
    /// external mutable state, for example values stored in TLS or in
    /// `static mut`s.
    // FIXME (#5527): This should be an associated constant
    fn zero() -> Self;

    /// Returns `true` if `self` is equal to the additive identity.
    #[inline]
    fn is_zero(&self) -> bool;
}

macro_rules! zero_impl {
    ($t:ty, $v:expr) => {
        impl Zero for $t {
            #[inline]
            fn zero() -> $t { $v }
            #[inline]
            fn is_zero(&self) -> bool { *self == $v }
        }
    }
}

zero_impl!(usize, 0usize);
zero_impl!(u8,    0u8);
zero_impl!(u16,   0u16);
zero_impl!(u32,   0u32);
zero_impl!(u64,   0u64);

zero_impl!(isize, 0isize);
zero_impl!(i8,    0i8);
zero_impl!(i16,   0i16);
zero_impl!(i32,   0i32);
zero_impl!(i64,   0i64);

zero_impl!(f32, 0.0f32);
zero_impl!(f64, 0.0f64);

impl<T: Zero> Zero for Wrapping<T> where Wrapping<T>: Add<Output=Wrapping<T>> {
    fn is_zero(&self) -> bool {
        self.0.is_zero()
    }
    fn zero() -> Self {
        Wrapping(T::zero())
    }
}

/// Defines a multiplicative identity element for `Self`.
pub trait One: Sized + Mul<Self, Output = Self> {
    /// Returns the multiplicative identity element of `Self`, `1`.
    ///
    /// # Laws
    ///
    /// ```{.text}
    /// a * 1 = a       ∀ a ∈ Self
    /// 1 * a = a       ∀ a ∈ Self
    /// ```
    ///
    /// # Purity
    ///
    /// This function should return the same result at all times regardless of
    /// external mutable state, for example values stored in TLS or in
    /// `static mut`s.
    // FIXME (#5527): This should be an associated constant
    fn one() -> Self;

    /// Returns `true` if `self` is equal to the multiplicative identity.
    ///
    /// Compatibility note: this method will be a requirement to implement in the future; new
    /// implementors should provide it for future-compatibility.
    fn is_one(&self) -> bool where Self: PartialEq {
        *self == Self::one()
    }
}

macro_rules! one_impl {
    ($t:ty, $v:expr) => {
        impl One for $t {
            #[inline]
            fn one() -> $t { $v }
        }
    }
}

one_impl!(usize, 1usize);
one_impl!(u8,    1u8);
one_impl!(u16,   1u16);
one_impl!(u32,   1u32);
one_impl!(u64,   1u64);

one_impl!(isize, 1isize);
one_impl!(i8,    1i8);
one_impl!(i16,   1i16);
one_impl!(i32,   1i32);
one_impl!(i64,   1i64);

one_impl!(f32, 1.0f32);
one_impl!(f64, 1.0f64);

impl<T: One> One for Wrapping<T> where Wrapping<T>: Mul<Output=Wrapping<T>> {
    fn one() -> Self {
        Wrapping(T::one())
    }
}

// Some helper functions provided for backwards compatibility.

/// Returns the additive identity, `0`.
#[inline(always)] pub fn zero<T: Zero>() -> T { Zero::zero() }

/// Returns the multiplicative identity, `1`.
#[inline(always)] pub fn one<T: One>() -> T { One::one() }

#[test]
fn wrapping_identities() {
    macro_rules! test_wrapping_identities {
        ($($t:ty)+) => {
            $(
                assert_eq!(zero::<$t>(), zero::<Wrapping<$t>>().0);
                assert_eq!(one::<$t>(), one::<Wrapping<$t>>().0);
                assert_eq!((0 as $t).is_zero(), Wrapping(0 as $t).is_zero());
                assert_eq!((1 as $t).is_zero(), Wrapping(1 as $t).is_zero());
            )+
        };
    }

    test_wrapping_identities!(isize i8 i16 i32 i64 usize u8 u16 u32 u64);
}

#[test]
fn wrapping_is_zero() {
    fn require_zero<T: Zero>(_: &T) {}
    require_zero(&Wrapping(42));
}
#[test]
fn wrapping_is_one() {
    fn require_one<T: One>(_: &T) {}
    require_one(&Wrapping(42));
}
<|endoftext|>


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

//! Miscellaneous helpers for common patterns.

use cast;
use ptr;
use prelude::*;
use unstable::intrinsics;

/// The identity function.
#[inline]
pub fn id<T>(x: T) -> T { x }

/// Ignores a value.
#[inline]
pub fn ignore<T>(_x: T) { }

/// Sets `*ptr` to `new_value`, invokes `op()`, and then restores the
/// original value of `*ptr`.
///
/// NB: This function accepts `@mut T` and not `&mut T` to avoid
/// an obvious borrowck hazard. Typically passing in `&mut T` will
/// cause borrow check errors because it freezes whatever location
/// that `&mut T` is stored in (either statically or dynamically).
#[inline]
pub fn with<T,R>(
    ptr: @mut T,
    value: T,
    op: &fn() -> R) -> R
{
    let prev = replace(ptr, value);
    let result = op();
    *ptr = prev;
    return result;
}

/**
 * Swap the values at two mutable locations of the same type, without
 * deinitialising or copying either one.
 */
#[inline]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut tmp: T = intrinsics::uninit();
        let t: *mut T = &mut tmp;

        // Perform the swap, `&mut` pointers never alias
        let x_raw: *mut T = x;
        let y_raw: *mut T = y;
        ptr::copy_nonoverlapping_memory(t, x_raw, 1);
        ptr::copy_nonoverlapping_memory(x, y_raw, 1);
        ptr::copy_nonoverlapping_memory(y, t, 1);

        // y and t now point to the same thing, but we need to completely forget `tmp`
        // because it's no longer relevant.
        cast::forget(tmp);
    }
}

/**
 * Replace the value at a mutable location with a new one, returning the old
 * value, without deinitialising or copying either one.
 */
#[inline]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
}

/// A non-copyable dummy type.
#[deriving(Eq, TotalEq, Ord, TotalOrd)]
#[unsafe_no_drop_flag]
pub struct NonCopyable;

impl NonCopyable {
    // FIXME(#8233) should not be necessary
    /// Create a new noncopyable token.
    pub fn new() -> NonCopyable { NonCopyable }
}

impl Drop for NonCopyable {
    fn drop(&mut self) { }
}

/// A type with no inhabitants
pub enum Void { }

impl Void {
    /// A utility function for ignoring this uninhabited type
    pub fn uninhabited(self) -> ! {
        match self {
            // Nothing to match on
        }
    }
}

/**
A utility function for indicating unreachable code. It will fail if
executed. This is occasionally useful to put after loops that never
terminate normally, but instead directly return from a function.

# Example

~~~ {.rust}
fn choose_weighted_item(v: &[Item]) -> Item {
    assert!(!v.is_empty());
    let mut so_far = 0u;
    for v.each |item| {
        so_far += item.weight;
        if so_far > 100 {
            return item;
        }
    }
    // The above loop always returns, so we must hint to the
    // type checker that it isn't possible to get down here
    util::unreachable();
}
~~~

*/
pub fn unreachable() -> ! {
    fail!("internal error: entered unreachable code");
}

#[cfg(test)]
mod tests {
    use super::*;

    use clone::Clone;
    use option::{None, Some};
    use either::{Either, Left, Right};
    use sys::size_of;
    use kinds::Drop;

    #[test]
    fn identity_crisis() {
        // Writing a test for the identity function. How did it come to this?
        let x = ~[(5, false)];
        //FIXME #3387 assert!(x.eq(id(x.clone())));
        let y = x.clone();
        assert!(x.eq(&id(y)));
    }

    #[test]
    fn test_swap() {
        let mut x = 31337;
        let mut y = 42;
        swap(&mut x, &mut y);
        assert_eq!(x, 42);
        assert_eq!(y, 31337);
    }

    #[test]
    fn test_replace() {
        let mut x = Some(NonCopyable);
        let y = replace(&mut x, None);
        assert!(x.is_none());
        assert!(y.is_some());
    }

    #[test]
    fn test_uninhabited() {
        let could_only_be_coin : Either <Void, ()> = Right (());
        match could_only_be_coin {
            Right (coin) => coin,
            Left (is_void) => is_void.uninhabited ()
        }
    }

    #[test]
    fn test_noncopyable() {
        assert_eq!(size_of::<NonCopyable>(), 0);

        // verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct

        static mut did_run: bool = false;

        struct Foo { five: int }

        impl Drop for Foo {
            fn drop(&mut self) {
                assert_eq!(self.five, 5);
                unsafe {
                    did_run = true;
                }
            }
        }

        {
            let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
        }

        unsafe { assert_eq!(did_run, true); }
    }
}

/// Completely miscellaneous language-construct benchmarks.
#[cfg(test)]
mod bench {

    use extra::test::BenchHarness;
    use option::{Some,None};

    // Static/dynamic method dispatch

    struct Struct {
        field: int
    }

    trait Trait {
        fn method(&self) -> int;
    }

    impl Trait for Struct {
        fn method(&self) -> int {
            self.field
        }
    }

    #[bench]
    fn trait_vtable_method_call(bh: &mut BenchHarness) {
        let s = Struct { field: 10 };
        let t = &s as &Trait;
        do bh.iter {
            t.method();
        }
    }

    #[bench]
    fn trait_static_method_call(bh: &mut BenchHarness) {
        let s = Struct { field: 10 };
        do bh.iter {
            s.method();
        }
    }

    // Overhead of various match forms

    #[bench]
    fn match_option_some(bh: &mut BenchHarness) {
        let x = Some(10);
        do bh.iter {
            let _q = match x {
                Some(y) => y,
                None => 11
            };
        }
    }

    #[bench]
    fn match_vec_pattern(bh: &mut BenchHarness) {
        let x = [1,2,3,4,5,6];
        do bh.iter {
            let _q = match x {
                [1,2,3,.._] => 10,
                _ => 11
            };
        }
    }
}
<commit_msg>util: remove unused `with` function<commit_after>// Copyright 2012-2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Miscellaneous helpers for common patterns.

use cast;
use ptr;
use prelude::*;
use unstable::intrinsics;

/// The identity function.
#[inline]
pub fn id<T>(x: T) -> T { x }

/// Ignores a value.
#[inline]
pub fn ignore<T>(_x: T) { }

/**
 * Swap the values at two mutable locations of the same type, without
 * deinitialising or copying either one.
 */
#[inline]
pub fn swap<T>(x: &mut T, y: &mut T) {
    unsafe {
        // Give ourselves some scratch space to work with
        let mut tmp: T = intrinsics::uninit();
        let t: *mut T = &mut tmp;

        // Perform the swap, `&mut` pointers never alias
        let x_raw: *mut T = x;
        let y_raw: *mut T = y;
        ptr::copy_nonoverlapping_memory(t, x_raw, 1);
        ptr::copy_nonoverlapping_memory(x, y_raw, 1);
        ptr::copy_nonoverlapping_memory(y, t, 1);

        // y and t now point to the same thing, but we need to completely forget `tmp`
        // because it's no longer relevant.
        cast::forget(tmp);
    }
}

/**
 * Replace the value at a mutable location with a new one, returning the old
 * value, without deinitialising or copying either one.
 */
#[inline]
pub fn replace<T>(dest: &mut T, mut src: T) -> T {
    swap(dest, &mut src);
    src
}

/// A non-copyable dummy type.
#[deriving(Eq, TotalEq, Ord, TotalOrd)]
#[unsafe_no_drop_flag]
pub struct NonCopyable;

impl NonCopyable {
    // FIXME(#8233) should not be necessary
    /// Create a new noncopyable token.
    pub fn new() -> NonCopyable { NonCopyable }
}

impl Drop for NonCopyable {
    fn drop(&mut self) { }
}

/// A type with no inhabitants
pub enum Void { }

impl Void {
    /// A utility function for ignoring this uninhabited type
    pub fn uninhabited(self) -> ! {
        match self {
            // Nothing to match on
        }
    }
}

/**
A utility function for indicating unreachable code. It will fail if
executed. This is occasionally useful to put after loops that never
terminate normally, but instead directly return from a function.

# Example

~~~ {.rust}
fn choose_weighted_item(v: &[Item]) -> Item {
    assert!(!v.is_empty());
    let mut so_far = 0u;
    for v.each |item| {
        so_far += item.weight;
        if so_far > 100 {
            return item;
        }
    }
    // The above loop always returns, so we must hint to the
    // type checker that it isn't possible to get down here
    util::unreachable();
}
~~~

*/
pub fn unreachable() -> ! {
    fail!("internal error: entered unreachable code");
}

#[cfg(test)]
mod tests {
    use super::*;

    use clone::Clone;
    use option::{None, Some};
    use either::{Either, Left, Right};
    use sys::size_of;
    use kinds::Drop;

    #[test]
    fn identity_crisis() {
        // Writing a test for the identity function. How did it come to this?
        let x = ~[(5, false)];
        //FIXME #3387 assert!(x.eq(id(x.clone())));
        let y = x.clone();
        assert!(x.eq(&id(y)));
    }

    #[test]
    fn test_swap() {
        let mut x = 31337;
        let mut y = 42;
        swap(&mut x, &mut y);
        assert_eq!(x, 42);
        assert_eq!(y, 31337);
    }

    #[test]
    fn test_replace() {
        let mut x = Some(NonCopyable);
        let y = replace(&mut x, None);
        assert!(x.is_none());
        assert!(y.is_some());
    }

    #[test]
    fn test_uninhabited() {
        let could_only_be_coin : Either <Void, ()> = Right (());
        match could_only_be_coin {
            Right (coin) => coin,
            Left (is_void) => is_void.uninhabited ()
        }
    }

    #[test]
    fn test_noncopyable() {
        assert_eq!(size_of::<NonCopyable>(), 0);

        // verify that `#[unsafe_no_drop_flag]` works as intended on a zero-size struct

        static mut did_run: bool = false;

        struct Foo { five: int }

        impl Drop for Foo {
            fn drop(&mut self) {
                assert_eq!(self.five, 5);
                unsafe {
                    did_run = true;
                }
            }
        }

        {
            let _a = (NonCopyable, Foo { five: 5 }, NonCopyable);
        }

        unsafe { assert_eq!(did_run, true); }
    }
}

/// Completely miscellaneous language-construct benchmarks.
#[cfg(test)]
mod bench {

    use extra::test::BenchHarness;
    use option::{Some,None};

    // Static/dynamic method dispatch

    struct Struct {
        field: int
    }

    trait Trait {
        fn method(&self) -> int;
    }

    impl Trait for Struct {
        fn method(&self) -> int {
            self.field
        }
    }

    #[bench]
    fn trait_vtable_method_call(bh: &mut BenchHarness) {
        let s = Struct { field: 10 };
        let t = &s as &Trait;
        do bh.iter {
            t.method();
        }
    }

    #[bench]
    fn trait_static_method_call(bh: &mut BenchHarness) {
        let s = Struct { field: 10 };
        do bh.iter {
            s.method();
        }
    }

    // Overhead of various match forms

    #[bench]
    fn match_option_some(bh: &mut BenchHarness) {
        let x = Some(10);
        do bh.iter {
            let _q = match x {
                Some(y) => y,
                None => 11
            };
        }
    }

    #[bench]
    fn match_vec_pattern(bh: &mut BenchHarness) {
        let x = [1,2,3,4,5,6];
        do bh.iter {
            let _q = match x {
                [1,2,3,.._] => 10,
                _ => 11
            };
        }
    }
}
<|endoftext|>


<commit_before>use core::cmp;
use core::mem;
use core::ops::{Deref, DerefMut};

use io::{Read, Write, Result};

use thread::WaitQueue;

use cell::{GlobalCell, GlobalCellMutRef};

use hal::xen::sched::yield_cpu;
use hal::xen::event::{dispatcher, send};
use hal::xen::defs::{ConsoleInterface, ConsRingIdx, EvtchnPort};

use hal::intrinsics::wmb;

static CONSOLE: GlobalCell<Console> = GlobalCell::new();

pub fn console<'a>() -> GlobalCellMutRef<'a, Console> {
    CONSOLE.as_mut()
}

pub unsafe fn init(interface: *mut ConsoleInterface, port: EvtchnPort) {
    CONSOLE.set(Console::new(interface, port));
}

pub struct Console {
    interface: *mut ConsoleInterface,
    port: EvtchnPort,
    queue: WaitQueue,
}

unsafe impl Sync for Console {}

impl Console {
    pub unsafe fn new(interface: *mut ConsoleInterface,
                      port: EvtchnPort) -> Self {
        Console {
            interface: interface,
            port: port,
            queue: WaitQueue::new(),
        }
    }

    fn console_callback(port: EvtchnPort, data: *mut u8) {
        let console = unsafe { &mut *(data as *mut Console) };
        let cons = console.in_cons;
        let prod = console.in_prod;

        if prod - cons > 0 {
            console.queue.unblock();
        }

        send(port);
    }

    pub unsafe fn init_input(&mut self) {
        dispatcher().bind_port(self.port, Self::console_callback,
                               self as *mut Self as *mut u8);
        dispatcher().unmask_event(self.port);
        send(self.port);
    }

    fn is_output_full(&self) -> bool {
        let data: ConsRingIdx;

        data = self.out_prod - self.out_cons;

        // size_of output field
        (data as usize) >= mem::size_of::<[u8; 2048]>()
    }

    fn out_idx(&self) -> usize {
        let size_of_output = (mem::size_of::<[u8; 2048]>() - 1) as u32;

        (self.out_prod & size_of_output) as usize
    }

    fn in_idx(&self) -> usize {
        let size_of_input = (mem::size_of::<[u8; 1024]>() - 1) as u32;

        (self.in_cons & size_of_input) as usize
    }
}

impl Deref for Console {
    type Target = ConsoleInterface;

    #[inline]
    fn deref(&self) -> &ConsoleInterface {
        // This isn't totally safe. If the interface has not been initialized
        // this would cause some problems. For this to be safe, the console
        // MUST be initialized before being used
        unsafe {
            &(*self.interface)
        }
    }
}

impl DerefMut for Console {
    #[inline]
    fn deref_mut(&mut self) -> &mut ConsoleInterface {
        // See deref
        unsafe {
            &mut (*self.interface)
        }
    }
}

impl Read for Console {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        // More locked or atomic checks of the condition are not necessary
        // here. Indeed this Console is a "raw" console which means that it is
        // not thread safe. This safety will be guaranteed by the stdio
        // functions such as stdin, stdout, ...
        wait_event!(self.queue, self.in_cons - self.in_prod > 0);

        let i = 0;

        let size = cmp::min((self.in_cons - self.in_prod) as usize, buf.len());

        while i < buf.len() && self.in_cons < self.in_prod {
            let index = self.in_idx();

            buf[i] = self.input[index];

            self.in_cons += 1;

            wmb();
        }

        Ok(size)
    }
}

impl Write for Console {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        for c in buf {
            while self.is_output_full() {
                send(self.port);
            }

            let index = self.out_idx();

            self.output[index] = *c;
            wmb();

            self.out_prod += 1;
        }

        send(self.port);

        Ok(buf.len())
    }

    fn flush(&mut self) -> Result<()> {
        while self.out_cons < self.out_prod {
            yield_cpu();
        }

        Ok(())
    }
}
<commit_msg>xen/console: Fix bug on read() implementation<commit_after>use core::cmp;
use core::mem;
use core::ops::{Deref, DerefMut};

use io::{Read, Write, Result};

use thread::WaitQueue;

use cell::{GlobalCell, GlobalCellMutRef};

use hal::xen::sched::yield_cpu;
use hal::xen::event::{dispatcher, send};
use hal::xen::defs::{ConsoleInterface, ConsRingIdx, EvtchnPort};

use hal::intrinsics::wmb;

static CONSOLE: GlobalCell<Console> = GlobalCell::new();

pub fn console<'a>() -> GlobalCellMutRef<'a, Console> {
    CONSOLE.as_mut()
}

pub unsafe fn init(interface: *mut ConsoleInterface, port: EvtchnPort) {
    CONSOLE.set(Console::new(interface, port));
}

pub struct Console {
    interface: *mut ConsoleInterface,
    port: EvtchnPort,
    queue: WaitQueue,
}

unsafe impl Sync for Console {}

impl Console {
    pub unsafe fn new(interface: *mut ConsoleInterface,
                      port: EvtchnPort) -> Self {
        Console {
            interface: interface,
            port: port,
            queue: WaitQueue::new(),
        }
    }

    fn console_callback(port: EvtchnPort, data: *mut u8) {
        let console = unsafe { &mut *(data as *mut Console) };
        let cons = console.in_cons;
        let prod = console.in_prod;

        if prod - cons > 0 {
            console.queue.unblock();
        }

        send(port);
    }

    pub unsafe fn init_input(&mut self) {
        dispatcher().bind_port(self.port, Self::console_callback,
                               self as *mut Self as *mut u8);
        dispatcher().unmask_event(self.port);
        send(self.port);
    }

    fn is_output_full(&self) -> bool {
        let data: ConsRingIdx;

        data = self.out_prod - self.out_cons;

        // size_of output field
        (data as usize) >= mem::size_of::<[u8; 2048]>()
    }

    fn out_idx(&self) -> usize {
        let size_of_output = (mem::size_of::<[u8; 2048]>() - 1) as u32;

        (self.out_prod & size_of_output) as usize
    }

    fn in_idx(&self) -> usize {
        let size_of_input = (mem::size_of::<[u8; 1024]>() - 1) as u32;

        (self.in_cons & size_of_input) as usize
    }
}

impl Deref for Console {
    type Target = ConsoleInterface;

    #[inline]
    fn deref(&self) -> &ConsoleInterface {
        // This isn't totally safe. If the interface has not been initialized
        // this would cause some problems. For this to be safe, the console
        // MUST be initialized before being used
        unsafe {
            &(*self.interface)
        }
    }
}

impl DerefMut for Console {
    #[inline]
    fn deref_mut(&mut self) -> &mut ConsoleInterface {
        // See deref
        unsafe {
            &mut (*self.interface)
        }
    }
}

impl Read for Console {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        // More locked or atomic checks of the condition are not necessary
        // here. Indeed this Console is a "raw" console which means that it is
        // not thread safe. This safety will be guaranteed by the stdio
        // functions such as stdin, stdout, ...
        wait_event!(self.queue, self.in_prod > self.in_cons);

        let i = 0;

        let size = cmp::min((self.in_prod - self.in_cons) as usize, buf.len());

        while i < buf.len() && self.in_cons < self.in_prod {
            let index = self.in_idx();

            buf[i] = self.input[index];

            self.in_cons += 1;

            wmb();
        }

        Ok(size)
    }
}

impl Write for Console {
    fn write(&mut self, buf: &[u8]) -> Result<usize> {
        for c in buf {
            while self.is_output_full() {
                send(self.port);
            }

            let index = self.out_idx();

            self.output[index] = *c;
            wmb();

            self.out_prod += 1;
        }

        send(self.port);

        Ok(buf.len())
    }

    fn flush(&mut self) -> Result<()> {
        while self.out_cons < self.out_prod {
            yield_cpu();
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>use std::cell::Cell;

use cairo::{self, MatrixTrait};
use markup5ever::local_name;

use crate::bbox::BoundingBox;
use crate::coord_units::CoordUnits;
use crate::drawing_ctx::DrawingCtx;
use crate::error::RenderingError;
use crate::node::{CascadedValues, NodeDraw, NodeResult, NodeTrait, RsvgNode};
use crate::parsers::ParseValue;
use crate::property_bag::PropertyBag;

coord_units!(ClipPathUnits, CoordUnits::UserSpaceOnUse);

#[derive(Default)]
pub struct NodeClipPath {
    units: Cell<ClipPathUnits>,
}

impl NodeClipPath {
    pub fn get_units(&self) -> ClipPathUnits {
        self.units.get()
    }

    pub fn to_cairo_context(
        &self,
        node: &RsvgNode,
        draw_ctx: &mut DrawingCtx,
        bbox: &BoundingBox,
    ) -> Result<(), RenderingError> {
        let clip_units = self.units.get();

        if clip_units == ClipPathUnits(CoordUnits::ObjectBoundingBox) && bbox.rect.is_none() {
            // The node being clipped is empty / doesn't have a
            // bounding box, so there's nothing to clip!
            return Ok(());
        }

        let cascaded = CascadedValues::new_from_node(node);

        draw_ctx.with_saved_matrix(&mut |dc| {
            let cr = dc.get_cairo_context();

            if clip_units == ClipPathUnits(CoordUnits::ObjectBoundingBox) {
                let bbox_rect = bbox.rect.as_ref().unwrap();

                cr.transform(cairo::Matrix::new(
                    bbox_rect.width,
                    0.0,
                    0.0,
                    bbox_rect.height,
                    bbox_rect.x,
                    bbox_rect.y,
                ))
            }

            // here we don't push a layer because we are clipping
            let res = node.draw_children(&cascaded, dc, true);

            cr.clip();
            res
        })
    }
}

impl NodeTrait for NodeClipPath {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            match attr {
                local_name!("clipPathUnits") => self.units.set(attr.parse(value)?),
                _ => (),
            }
        }

        Ok(())
    }
}
<commit_msg>clip_path: remove interior mutability<commit_after>use cairo::{self, MatrixTrait};
use markup5ever::local_name;

use crate::bbox::BoundingBox;
use crate::coord_units::CoordUnits;
use crate::drawing_ctx::DrawingCtx;
use crate::error::RenderingError;
use crate::node::{CascadedValues, NodeDraw, NodeResult, NodeTrait, RsvgNode};
use crate::parsers::ParseValue;
use crate::property_bag::PropertyBag;

coord_units!(ClipPathUnits, CoordUnits::UserSpaceOnUse);

#[derive(Default)]
pub struct NodeClipPath {
    units: ClipPathUnits,
}

impl NodeClipPath {
    pub fn get_units(&self) -> ClipPathUnits {
        self.units
    }

    pub fn to_cairo_context(
        &self,
        node: &RsvgNode,
        draw_ctx: &mut DrawingCtx,
        bbox: &BoundingBox,
    ) -> Result<(), RenderingError> {
        if self.units == ClipPathUnits(CoordUnits::ObjectBoundingBox) && bbox.rect.is_none() {
            // The node being clipped is empty / doesn't have a
            // bounding box, so there's nothing to clip!
            return Ok(());
        }

        let cascaded = CascadedValues::new_from_node(node);

        draw_ctx.with_saved_matrix(&mut |dc| {
            let cr = dc.get_cairo_context();

            if self.units == ClipPathUnits(CoordUnits::ObjectBoundingBox) {
                let bbox_rect = bbox.rect.as_ref().unwrap();

                cr.transform(cairo::Matrix::new(
                    bbox_rect.width,
                    0.0,
                    0.0,
                    bbox_rect.height,
                    bbox_rect.x,
                    bbox_rect.y,
                ))
            }

            // here we don't push a layer because we are clipping
            let res = node.draw_children(&cascaded, dc, true);

            cr.clip();
            res
        })
    }
}

impl NodeTrait for NodeClipPath {
    fn set_atts(&mut self, _: Option<&RsvgNode>, pbag: &PropertyBag<'_>) -> NodeResult {
        for (attr, value) in pbag.iter() {
            match attr {
                local_name!("clipPathUnits") => self.units = attr.parse(value)?,
                _ => (),
            }
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>use error::Error;
use super::conn;

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Feed {
    pub id:           String,
    pub subscribers:  Option<i64>,
    pub title:        Option<String>,
    pub description:  Option<String>,
    pub language:     Option<String>,
    pub velocity:     Option<f64>,
    pub website:      Option<String>,
    pub topics:       Option<Vec<String>>,
    pub status:       Option<String>,
    pub curated:      Option<bool>,
    pub featured:     Option<bool>,
    pub last_updated: Option<i64>,

    pub visual_url:   Option<String>,
    pub icon_url:     Option<String>,
    pub cover_url:    Option<String>,
}

impl Feed {
    pub fn find_by_id(id: String) -> Result<Feed, Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, subscribers, title, description, language, velocity, website, status, curated, featured, last_updated, visual_url, icon_url, cover_url FROM feeds WHERE id = $1").unwrap();
        for row in stmt.query(&[&id]).unwrap().iter() {
            return Ok(Feed {
                    id: row.get(0),
           subscribers: row.get(1),
                 title: row.get(2),
           description: row.get(3),
              language: row.get(4),
              velocity: row.get(5),
               website: row.get(6),
                topics: None,
                status: row.get(7),
               curated: row.get(8),
              featured: row.get(9),
          last_updated: row.get(10),
            visual_url: row.get(11),
              icon_url: row.get(12),
             cover_url: row.get(13),
            });
        }
        return Err(Error::NotFound)
    }

    pub fn find_all() -> Vec<Feed> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("SELECT id, subscribers, title, description, language, velocity, website, status, curated, featured, last_updated, visual_url, icon_url, cover_url FROM feeds").unwrap();
        let mut feeds = Vec::new();
        for row in stmt.query(&[]).unwrap().iter() {
            feeds.push(Feed {
                    id: row.get(0),
           subscribers: row.get(1),
                 title: row.get(2),
           description: row.get(3),
              language: row.get(4),
              velocity: row.get(5),
               website: row.get(6),
                topics: None,
                status: row.get(7),
               curated: row.get(8),
              featured: row.get(9),
          last_updated: row.get(10),
            visual_url: row.get(11),
              icon_url: row.get(12),
             cover_url: row.get(13),
            })
        }
        return feeds
    }

    pub fn create(feed: Feed) -> Result<(), Error> {
        let conn = conn().unwrap();
        let stmt = conn.prepare("INSERT INTO feeds (id, u) VALUES ($1)").unwrap();
        let _ = try!(stmt.query(&[
            &feed.id,
            &feed.subscribers,
            &feed.title,
            &feed.description,
            &feed.language,
            &feed.velocity,
            &feed.website,
            &feed.topics,
            &feed.status,
            &feed.curated,
            &feed.featured,
            &feed.last_updated,
            &feed.visual_url,
            &feed.icon_url,
            &feed.cover_url,
        ]));
        Ok(())
    }
}
<commit_msg>Implement Feed struct<commit_after>use postgres;
use uuid::Uuid;
use error::Error;
use chrono::{NaiveDateTime, UTC};
use super::{conn, Model, Entry};
use model::state::State;
use rss;

static PROPS: [&'static str; 15]  = ["id",
                                     "url",
                                     "title",
                                     "description",
                                     "language",
                                     "velocity",
                                     "website",
                                     "state",
                                     "last_updated",
                                     "crawled",
                                     "visual_url",
                                     "icon_url",
                                     "cover_url",
                                     "created_at",
                                     "updated_at"];

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct Feed {
    pub id:           Uuid,
    pub url:          String,
    pub title:        String,
    pub description:  Option<String>,
    pub language:     Option<String>,
    pub velocity:     f64,
    pub website:      Option<String>,
    pub state:        State,
    pub last_updated: NaiveDateTime,
    pub crawled:      NaiveDateTime,

    pub visual_url:   Option<String>,
    pub icon_url:     Option<String>,
    pub cover_url:    Option<String>,

    pub created_at:   NaiveDateTime,
    pub updated_at:   NaiveDateTime,
}

impl<'a> Model<'a> for Feed {
    fn table_name() -> String {
        "feeds".to_string()
    }
    fn props_str(prefix: &str) -> String {
        PROPS
            .iter()
            .map(|&p| format!("{}{}", prefix, p))
            .collect::<Vec<String>>().join(",")
    }
    fn rows_to_items(rows: postgres::rows::Rows) -> Vec<Feed> {
        let mut feeds = Vec::new();
        for row in rows.iter() {
            feeds.push(Feed {
                id:           row.get(0),
                url:          row.get(1),
                title:        row.get(2),
                description:  row.get(3),
                language:     row.get(4),
                velocity:     row.get(5),
                website:      row.get(6),
                state:        State::new(row.get(7)),
                last_updated: row.get(8),
                crawled:      row.get(9),

                visual_url:   row.get(10),
                icon_url:     row.get(11),
                cover_url:    row.get(12),

                created_at:   row.get(13),
                updated_at:   row.get(14),
            })
        }
        feeds
    }
    fn create(&self) -> Result<Feed, Error> {
        let conn = try!(conn());
        let stmt = try!(conn.prepare("INSERT INTO feeds (id, u) VALUES ($1)"));
        let rows = try!(stmt.query(&[
            &self.id,
            &self.url,
            &self.title,
            &self.description,
            &self.language,
            &self.velocity,
            &self.website,
            &self.state.to_string(),
            &self.last_updated,
            &self.crawled,
            &self.visual_url,
            &self.icon_url,
            &self.cover_url,
            &self.created_at,
            &self.updated_at,
        ]));
        let mut feed = self.clone();
        for row in rows.iter() {
            feed.id = row.get(0);
        }
        Ok(feed)
    }
    fn save(&mut self) -> Result<(), Error> {
        self.updated_at = UTC::now().naive_utc();
        let conn = try!(conn());
        let stmt = try!(conn.prepare("UPDATE feeds SET
                                   url          = $2,
                                   title        = $3,
                                   description  = $4,
                                   language     = $5,
                                   velocity     = $6,
                                   website      = $7,
                                   state        = $8,
                                   last_updated = $9,
                                   crawled      = $10,
                                   visual_url   = $11,
                                   icon_url     = $12,
                                   cover_url    = $13,
                                   created_at   = $14,
                                   updated_at   = $15
                                 WHERE id = $1"));
        let result = stmt.query(&[&self.id,
                                  &self.url,
                                  &self.title,
                                  &self.description,
                                  &self.language,
                                  &self.velocity,
                                  &self.website,
                                  &self.state.to_string(),
                                  &self.last_updated,
                                  &self.crawled,
                                  &self.visual_url,
                                  &self.icon_url,
                                  &self.cover_url,
                                  &self.created_at,
                                  &self.updated_at]);
        try!(result);
        Ok(())
    }
}

impl Feed {
    pub fn find_by_url(url: &str) -> Result<Feed, Error> {
        let conn = try!(conn());
        let stmt = try!(conn.prepare(
            &format!("SELECT {} FROM feeds
                        WHERE url = $1", Self::props_str(""))));
        let rows = try!(stmt.query(&[&url]));
        let feeds = Feed::rows_to_items(rows);
        if feeds.len() > 0 {
            return Ok(feeds[0].clone());
        }
        return Err(Error::NotFound)
    }

    pub fn find_or_create_by_url(url: String) -> Result<Feed, Error> {
        match Feed::find_by_url(&url) {
            Ok(feed) => Ok(feed),
            Err(_)   => Feed::create_by_url(url)
        }
    }

    pub fn create_by_url(url: String) -> Result<Feed, Error> {
        let conn = try!(conn());
        let stmt = try!(conn.prepare("INSERT INTO feeds (url) VALUES ($1) RETURNING id"));
        let rows = try!(stmt.query(&[&url]));
        for row in rows.iter() {
            let feed = Feed {
                id:           row.get(0),
                url:          url,
                title:        "".to_string(),
                description:  None,
                language:     None,
                velocity:     0.0,
                website:      None,
                state:        State::Alive,
                last_updated: UTC::now().naive_utc(),
                crawled:      UTC::now().naive_utc(),
                visual_url:   None,
                icon_url:     None,
                cover_url:    None,
                created_at:   UTC::now().naive_utc(),
                updated_at:   UTC::now().naive_utc(),
            };
            return Ok(feed);
        }
        Err(Error::Unexpected)
    }

    pub fn fetch_props(&mut self) -> Result<(), Error> {
        let rss_feed      = try!(rss::fetch(&self.url));
        let now           = UTC::now().naive_utc();
        self.title        = rss_feed.title.unwrap_or("".to_string());
        self.description  = rss_feed.description;
        self.language     = rss_feed.language;
        self.website      = rss_feed.website;
        self.last_updated = rss_feed.last_updated.unwrap_or(now);
        self.crawled      = now;

        self.visual_url   = rss_feed.visual_url;
        self.icon_url     = rss_feed.icon_url;
        self.cover_url    = rss_feed.cover_url;
        Ok(())
    }

    pub fn crawl(&mut self) -> Result<Vec<Entry>, Error> {
        let rss_feed      = try!(rss::fetch(&self.url));
        let mut entries   = vec![];
        for entry in rss_feed.entries {
            if entry.alternate.len() == 0 {
                continue;
            }
            let alt = entry.alternate.first().unwrap();
            if let Ok(_) = Entry::find_by_url(&alt.href) {
                continue;
            }
            match Entry::create_by_url(alt.href.to_string()) {
                Ok(mut e) => {
                    println!("Found new entry: {}", e.url);
                    e.update_with_feed_entry(&entry);
                    e.feed_id = Some(self.id);
                    try!(e.save());
                    let _ = e.playlistify();
                    if let Ok(_) = e.save() {
                        entries.push(e);
                    }
                },
                Err(_) => (),
            }
        }
        Ok(entries)
    }
}
<|endoftext|>


<commit_before>pub use api::oauth::{OAuthApp, CreateApp, make_client};
<commit_msg>remove unused code<commit_after><|endoftext|>