<commit_before>#[macro_use]
extern crate quote;
extern crate reqwest;
extern crate serde_json;
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate lazy_static;
extern crate linked_hash_map;
extern crate inflector;

use std::fs::File;
use serde_json::{ Value };
use std::collections::{ HashSet };
use quote::{ Tokens, Ident, ToTokens };
use std::ascii::AsciiExt;
use linked_hash_map::LinkedHashMap;
use inflector::Inflector;

mod util;
mod inference;

use util::*;
use inference::*;

mod errors {
    error_chain! {
        types {
            Error, ErrorKind, ResultExt, Result;
        }

        links {
        }

        foreign_links {
            ReqwestError(::reqwest::Error);
            JsonError(::serde_json::Error);
            IoError(::std::io::Error);
        }

        errors {
            MissingSource {
                description("No source for sample specified")
            }
            ExistingType(t: String) {
                display("No code generated, JSON matches existing type {}", t)
            }
        }
    }
}

pub use errors::*;

const RUST_KEYWORDS_ARR: &'static [&'static str] = &["abstract", "alignof", "as", "become", "box",
    "break", "const", "continue", "crate", "do", "else", "enum", "extern", "false", "final", "fn",
    "for", "if", "impl", "in", "let", "loop", "macro", "match", "mod", "move", "mut", "offsetof",
    "override", "priv", "proc", "pub", "pure", "ref", "return", "Self", "self", "sizeof", "static",
    "struct", "super", "trait", "true", "type", "typeof", "unsafe", "unsized", "use", "virtual",
    "where", "while", "yield"];

lazy_static! {
    static ref RUST_KEYWORDS: HashSet<&'static str> = {
        RUST_KEYWORDS_ARR.iter().cloned().collect()
    };
}

pub enum SampleSource<'a> {
    Url(&'a str),
    File(&'a str),
    Text(&'a str),
}

#[derive(Debug, PartialEq)]
pub enum MissingFields {
    Fail,
    UseDefault,
}

#[derive(Clone)]
pub enum Visibility {
    Private,
    Pub,
    PubRestricted(String)
}

impl ToTokens for Visibility {
    fn to_tokens(&self, tokens: &mut Tokens) {
        use Visibility::*;
        match *self {
            Private => {},
            Pub => {
                tokens.append("pub");
            }
            PubRestricted(ref path) => {
                tokens.append("pub(");
                tokens.append(path);
                tokens.append(")");
            }
        }
    }
}

pub enum FieldVisibility {
    Inherited,
    Specified(Visibility)
}

pub struct Options {
    pub extern_crate: bool,
    pub runnable: bool,
    pub missing_fields: MissingFields,
    pub deny_unknown_fields: bool,
    pub allow_option_vec: bool,
    pub type_visibility: Visibility,
    pub field_visibility: FieldVisibility,
}

impl Default for Options {
    fn default() -> Options {
        Options {
            extern_crate: false,
            runnable: false,
            missing_fields: MissingFields::Fail,
            deny_unknown_fields: false,
            allow_option_vec: false,
            type_visibility: Visibility::Private,
            field_visibility: FieldVisibility::Inherited,
        }
    }
}

struct Ctxt {
    options: Options,
    type_names: HashSet<String>,
    types: Vec<Tokens>,
}

macro_rules! some_if {
    ($cond:expr, $then:expr) => ({
        if $cond {
            Some($then)
        } else {
            None
        }
    })
}

pub fn from_str_with_defaults(name: &str, json: &str) -> Result<Tokens> {
    codegen(name, &SampleSource::Text(json), Options::default())
}

pub fn codegen(name: &str, source: &SampleSource, options: Options) -> Result<Tokens> {
    let sample = get_and_parse_sample(source)?;
    let mut ctxt = Ctxt {
        options: options,
        type_names: HashSet::new(),
        types: Vec::new(),
    };
    let inferred = infer_type_from_value(&sample);
    let type_name = generate_type_from_inferred(&mut ctxt, name, &inferred);

    let example = some_if!(ctxt.options.runnable, {
        ctxt.options.extern_crate = true;
        usage_example(&type_name)
    });

    let crates = some_if!(ctxt.options.extern_crate, quote! {
        #[macro_use]
        extern crate serde_derive;
        extern crate serde_json;
    });

    let defs = ctxt.types.iter().rev();

    Ok(quote! {
        #crates

        #(#defs)*

        #example
    })
}

fn usage_example(type_id: &Tokens) -> Tokens {
    let var_id = Ident::from(snake_case(type_id.as_str()));

    quote! {
        fn main() {
            let #var_id: #type_id = Default::default();

            let serialized = serde_json::to_string(&#var_id).unwrap();

            println!("serialized = {}", serialized);

            let deserialized: #type_id = serde_json::from_str(&serialized).unwrap();

            println!("deserialized = {:?}", deserialized);
        }
    }
}

fn generate_type_from_inferred(ctxt: &mut Ctxt, path: &str, inferred: &InferredType) -> Tokens {
    use InferredType::*;
    match *inferred {
        Null | Any => quote! { ::serde_json::Value },
        Bool => quote! { bool },
        StringT => quote! { String },
        Integer => quote! { i64 },
        Floating => quote! { f64 },
        EmptyVec => quote! { Vec<::serde_json::Value> },
        VecT { elem_type: ref e } => {
            let singular = path.to_singular();
            let inner = generate_type_from_inferred(ctxt, &singular, e);
            quote! { Vec<#inner> }
        }
        Struct { fields: ref map } => {
            generate_struct_from_inferred_fields(ctxt, path, map)
        }
        Optional(ref e) => {
            let inner = generate_type_from_inferred(ctxt, path, e);
            match ctxt.options.missing_fields {
                MissingFields::Fail => quote! { Option<#inner> },
                MissingFields::UseDefault => quote! { #inner },
            }
        }
    }
}

fn field_name(name: &str, _type: &InferredType, used_names: &HashSet<String>) -> String {
    let name = name.trim();
    let mut field_name = if let Some(c) = name.chars().next() {
        if c.is_ascii() && c.is_numeric() {
            let temp = String::from("n") + name;
            snake_case(&temp)
        } else {
            snake_case(name)
        }
    } else {
        snake_case(name)
    };
    if RUST_KEYWORDS.contains::<str>(&field_name) {
        field_name.push_str("_field");
    }
    if field_name == "" {
        // TODO: Use type to get nicer name
        field_name.push_str("field");
    }
    if !used_names.contains(&field_name) {
        return field_name;
    }
    for n in 1.. {
        let temp = format!("{}_{}", field_name, n);
        if !used_names.contains(&temp) {
            return temp;
        }
    }
    unreachable!()
}

fn collapse_option_vec<'a>(ctxt: &mut Ctxt,
                           typ: &'a InferredType)
                           -> (Option<Tokens>, &'a InferredType) {
    if !ctxt.options.allow_option_vec && ctxt.options.missing_fields != MissingFields::UseDefault {
        if let InferredType::Optional(ref inner) = *typ {
            match **inner {
                InferredType::EmptyVec | InferredType::VecT { .. } => {
                    return (Some(quote! { #[serde(default)] }), &**inner);
                }
                _ => {}
            }
        }
    }
    (None, typ)
}

fn generate_struct_from_inferred_fields(
        ctxt: &mut Ctxt,
        path: &str,
        map: &LinkedHashMap<String, InferredType>) -> Tokens {
    // TODO: Avoid type name collisions
    let type_name = type_case(path);
    let ident = Ident::from(type_name);
    let visibility = ctxt.options.type_visibility.clone();
    let field_visibility = match ctxt.options.field_visibility {
        FieldVisibility::Inherited => visibility.clone(),
        FieldVisibility::Specified(ref v) => v.clone(),
    };

    let mut field_names = HashSet::new();

    let fields: Vec<Tokens> = map.iter()
        .map(|(name, typ)| {
            let field_name = field_name(name, typ, &field_names);
            field_names.insert(field_name.clone());
            let rename = some_if!(&field_name != name,
                quote! { #[serde(rename = #name)] });
            let field_ident = Ident::from(field_name);
            let (default, collapsed) = collapse_option_vec(ctxt, typ);
            let field_type = generate_type_from_inferred(ctxt, name, collapsed);
            quote! {
                #rename
                #default
                #field_visibility #field_ident: #field_type
            }
        })
        .collect();

    let derives = quote! { #[derive(Default, Debug, Clone, Serialize, Deserialize)] };

    let unknown_fields = some_if!(ctxt.options.deny_unknown_fields,
        quote! { #[serde(deny_unknown_fields)] });

    let use_defaults = some_if!(ctxt.options.missing_fields == MissingFields::UseDefault,
        quote! { #[serde(default)] });

    let code = quote! {
        #derives
        #unknown_fields
        #use_defaults
        #visibility struct #ident {
            #(#fields),*
        }
    };

    ctxt.types.push(code);
    quote! { #ident }
}

pub fn infer_source_type(s: &str) -> SampleSource {
    let s = s.trim();
    if s.starts_with('{') || s.starts_with('[') {
        return SampleSource::Text(s);
    }
    if s.starts_with("http://") || s.starts_with("https://") {
        return SampleSource::Url(s);
    }
    SampleSource::File(s)
}

fn get_and_parse_sample(source: &SampleSource) -> Result<Value> {
    let parse_result = match *source {
        SampleSource::Url(url) => serde_json::de::from_reader(reqwest::get(url)?),
        SampleSource::File(path) => serde_json::de::from_reader(File::open(path)?),
        SampleSource::Text(text) => serde_json::from_str(text),
    };
    Ok(parse_result.chain_err(|| "Unable to parse JSON sample")?)
}
<commit_msg>shared: Prevent blank or duplicate type names<commit_after>#[macro_use]
extern crate quote;
extern crate reqwest;
extern crate serde_json;
#[macro_use]
extern crate error_chain;
#[macro_use]
extern crate lazy_static;
extern crate linked_hash_map;
extern crate inflector;

use std::fs::File;
use serde_json::{ Value };
use std::collections::{ HashSet };
use quote::{ Tokens, Ident, ToTokens };
use std::ascii::AsciiExt;
use linked_hash_map::LinkedHashMap;
use inflector::Inflector;

mod util;
mod inference;

use util::*;
use inference::*;

mod errors {
    error_chain! {
        types {
            Error, ErrorKind, ResultExt, Result;
        }

        links {
        }

        foreign_links {
            ReqwestError(::reqwest::Error);
            JsonError(::serde_json::Error);
            IoError(::std::io::Error);
        }

        errors {
            MissingSource {
                description("No source for sample specified")
            }
            ExistingType(t: String) {
                display("No code generated, JSON matches existing type {}", t)
            }
        }
    }
}

pub use errors::*;

const RUST_KEYWORDS_ARR: &'static [&'static str] = &["abstract", "alignof", "as", "become", "box",
    "break", "const", "continue", "crate", "do", "else", "enum", "extern", "false", "final", "fn",
    "for", "if", "impl", "in", "let", "loop", "macro", "match", "mod", "move", "mut", "offsetof",
    "override", "priv", "proc", "pub", "pure", "ref", "return", "Self", "self", "sizeof", "static",
    "struct", "super", "trait", "true", "type", "typeof", "unsafe", "unsized", "use", "virtual",
    "where", "while", "yield"];

lazy_static! {
    static ref RUST_KEYWORDS: HashSet<&'static str> = {
        RUST_KEYWORDS_ARR.iter().cloned().collect()
    };
}

pub enum SampleSource<'a> {
    Url(&'a str),
    File(&'a str),
    Text(&'a str),
}

#[derive(Debug, PartialEq)]
pub enum MissingFields {
    Fail,
    UseDefault,
}

#[derive(Clone)]
pub enum Visibility {
    Private,
    Pub,
    PubRestricted(String)
}

impl ToTokens for Visibility {
    fn to_tokens(&self, tokens: &mut Tokens) {
        use Visibility::*;
        match *self {
            Private => {},
            Pub => {
                tokens.append("pub");
            }
            PubRestricted(ref path) => {
                tokens.append("pub(");
                tokens.append(path);
                tokens.append(")");
            }
        }
    }
}

pub enum FieldVisibility {
    Inherited,
    Specified(Visibility)
}

pub struct Options {
    pub extern_crate: bool,
    pub runnable: bool,
    pub missing_fields: MissingFields,
    pub deny_unknown_fields: bool,
    pub allow_option_vec: bool,
    pub type_visibility: Visibility,
    pub field_visibility: FieldVisibility,
}

impl Default for Options {
    fn default() -> Options {
        Options {
            extern_crate: false,
            runnable: false,
            missing_fields: MissingFields::Fail,
            deny_unknown_fields: false,
            allow_option_vec: false,
            type_visibility: Visibility::Private,
            field_visibility: FieldVisibility::Inherited,
        }
    }
}

struct Ctxt {
    options: Options,
    type_names: HashSet<String>,
    types: Vec<Tokens>,
}

macro_rules! some_if {
    ($cond:expr, $then:expr) => ({
        if $cond {
            Some($then)
        } else {
            None
        }
    })
}

pub fn from_str_with_defaults(name: &str, json: &str) -> Result<Tokens> {
    codegen(name, &SampleSource::Text(json), Options::default())
}

pub fn codegen(name: &str, source: &SampleSource, options: Options) -> Result<Tokens> {
    let sample = get_and_parse_sample(source)?;
    let mut ctxt = Ctxt {
        options: options,
        type_names: HashSet::new(),
        types: Vec::new(),
    };
    let inferred = infer_type_from_value(&sample);
    let type_name = generate_type_from_inferred(&mut ctxt, name, &inferred);

    let example = some_if!(ctxt.options.runnable, {
        ctxt.options.extern_crate = true;
        usage_example(&type_name)
    });

    let crates = some_if!(ctxt.options.extern_crate, quote! {
        #[macro_use]
        extern crate serde_derive;
        extern crate serde_json;
    });

    let defs = ctxt.types.iter().rev();

    Ok(quote! {
        #crates

        #(#defs)*

        #example
    })
}

fn usage_example(type_id: &Tokens) -> Tokens {
    let var_id = Ident::from(snake_case(type_id.as_str()));

    quote! {
        fn main() {
            let #var_id: #type_id = Default::default();

            let serialized = serde_json::to_string(&#var_id).unwrap();

            println!("serialized = {}", serialized);

            let deserialized: #type_id = serde_json::from_str(&serialized).unwrap();

            println!("deserialized = {:?}", deserialized);
        }
    }
}

fn generate_type_from_inferred(ctxt: &mut Ctxt, path: &str, inferred: &InferredType) -> Tokens {
    use InferredType::*;
    match *inferred {
        Null | Any => quote! { ::serde_json::Value },
        Bool => quote! { bool },
        StringT => quote! { String },
        Integer => quote! { i64 },
        Floating => quote! { f64 },
        EmptyVec => quote! { Vec<::serde_json::Value> },
        VecT { elem_type: ref e } => {
            let singular = path.to_singular();
            let inner = generate_type_from_inferred(ctxt, &singular, e);
            quote! { Vec<#inner> }
        }
        Struct { fields: ref map } => {
            generate_struct_from_inferred_fields(ctxt, path, map)
        }
        Optional(ref e) => {
            let inner = generate_type_from_inferred(ctxt, path, e);
            match ctxt.options.missing_fields {
                MissingFields::Fail => quote! { Option<#inner> },
                MissingFields::UseDefault => quote! { #inner },
            }
        }
    }
}

fn field_name(name: &str, used_names: &HashSet<String>) -> String {
    type_or_field_name(name, used_names, "field", snake_case)
}

fn type_name(name: &str, used_names: &HashSet<String>) -> String {
    type_or_field_name(name, used_names, "GeneratedType", type_case)
}

fn type_or_field_name(name: &str,
                      used_names: &HashSet<String>,
                      default_name: &str,
                      case_fn: fn(&str) -> String)
                      -> String {
    let name = name.trim();
    let mut output_name = if let Some(c) = name.chars().next() {
        if c.is_ascii() && c.is_numeric() {
            let temp = String::from("n") + name;
            case_fn(&temp)
        } else {
            case_fn(name)
        }
    } else {
        case_fn(name)
    };
    if RUST_KEYWORDS.contains::<str>(&output_name) {
        output_name.push_str("_field");
    }
    if output_name == "" {
        output_name.push_str(default_name);
    }
    if !used_names.contains(&output_name) {
        return output_name;
    }
    for n in 2.. {
        let temp = format!("{}{}", output_name, n);
        if !used_names.contains(&temp) {
            return temp;
        }
    }
    unreachable!()
}

fn collapse_option_vec<'a>(ctxt: &mut Ctxt,
                           typ: &'a InferredType)
                           -> (Option<Tokens>, &'a InferredType) {
    if !ctxt.options.allow_option_vec && ctxt.options.missing_fields != MissingFields::UseDefault {
        if let InferredType::Optional(ref inner) = *typ {
            match **inner {
                InferredType::EmptyVec | InferredType::VecT { .. } => {
                    return (Some(quote! { #[serde(default)] }), &**inner);
                }
                _ => {}
            }
        }
    }
    (None, typ)
}

fn generate_struct_from_inferred_fields(
        ctxt: &mut Ctxt,
        path: &str,
        map: &LinkedHashMap<String, InferredType>) -> Tokens {
    let type_name = type_name(path, &ctxt.type_names);
    ctxt.type_names.insert(type_name.clone());
    let ident = Ident::from(type_name);
    let visibility = ctxt.options.type_visibility.clone();
    let field_visibility = match ctxt.options.field_visibility {
        FieldVisibility::Inherited => visibility.clone(),
        FieldVisibility::Specified(ref v) => v.clone(),
    };

    let mut field_names = HashSet::new();

    let fields: Vec<Tokens> = map.iter()
        .map(|(name, typ)| {
            let field_name = field_name(name, &field_names);
            field_names.insert(field_name.clone());
            let rename = some_if!(&field_name != name,
                quote! { #[serde(rename = #name)] });
            let field_ident = Ident::from(field_name);
            let (default, collapsed) = collapse_option_vec(ctxt, typ);
            let field_type = generate_type_from_inferred(ctxt, name, collapsed);
            quote! {
                #rename
                #default
                #field_visibility #field_ident: #field_type
            }
        })
        .collect();

    let derives = quote! { #[derive(Default, Debug, Clone, Serialize, Deserialize)] };

    let unknown_fields = some_if!(ctxt.options.deny_unknown_fields,
        quote! { #[serde(deny_unknown_fields)] });

    let use_defaults = some_if!(ctxt.options.missing_fields == MissingFields::UseDefault,
        quote! { #[serde(default)] });

    let code = quote! {
        #derives
        #unknown_fields
        #use_defaults
        #visibility struct #ident {
            #(#fields),*
        }
    };

    ctxt.types.push(code);
    quote! { #ident }
}

pub fn infer_source_type(s: &str) -> SampleSource {
    let s = s.trim();
    if s.starts_with('{') || s.starts_with('[') {
        return SampleSource::Text(s);
    }
    if s.starts_with("http://") || s.starts_with("https://") {
        return SampleSource::Url(s);
    }
    SampleSource::File(s)
}

fn get_and_parse_sample(source: &SampleSource) -> Result<Value> {
    let parse_result = match *source {
        SampleSource::Url(url) => serde_json::de::from_reader(reqwest::get(url)?),
        SampleSource::File(path) => serde_json::de::from_reader(File::open(path)?),
        SampleSource::Text(text) => serde_json::from_str(text),
    };
    Ok(parse_result.chain_err(|| "Unable to parse JSON sample")?)
}
<|endoftext|>


<commit_before>// Copyright 2012 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.

//  based on:
//  http://shootout.alioth.debian.org/
//   u64q/program.php?test=mandelbrot&lang=python3&id=2
//
//  takes 2 optional args:
//   square image size, defaults to 80_u
//   output path, default is "" (no output), "-" means stdout
//
//  in the shootout, they use 16000 as image size
//
//  writes pbm image to output path

extern mod std;
use io::WriterUtil;
use std::map::HashMap;

struct cmplx {
    re: f64,
    im: f64
}

impl cmplx : ops::Mul<cmplx,cmplx> {
    pure fn mul(&self, x: &cmplx) -> cmplx {
        cmplx {
            re: self.re*(*x).re - self.im*(*x).im,
            im: self.re*(*x).im + self.im*(*x).re
        }
    }
}

impl cmplx : ops::Add<cmplx,cmplx> {
    pure fn add(&self, x: &cmplx) -> cmplx {
        cmplx {
            re: self.re + (*x).re,
            im: self.im + (*x).im
        }
    }
}

struct Line {i: uint, b: ~[u8]}

pure fn cabs(x: cmplx) -> f64
{
    x.re*x.re + x.im*x.im
}

fn mb(x: cmplx) -> bool
{
    let mut z = cmplx {re: 0f64, im: 0f64};
    let mut i = 0;
    let mut in = true;
    while i < 50 {
        z = z*z + x;
        if cabs(z) >= 4f64 {
            in = false;
            break;
        }
        i += 1;
    }
    in
}

fn fillbyte(x: cmplx, incr: f64) -> u8 {
    let mut rv = 0_u8;
    let mut i = 0_u8;
    while i < 8_u8 {
        let z = cmplx {re: x.re + (i as f64)*incr, im: x.im};
        if mb(z) {
            rv += 1_u8 << (7_u8 - i);
        }
        i += 1_u8;
    }
    rv
}

fn chanmb(i: uint, size: uint, ch: oldcomm::Chan<Line>) -> ()
{
    let mut crv = ~[];
    let incr = 2f64/(size as f64);
    let y = incr*(i as f64) - 1f64;
    let xincr = 8f64*incr;
    for uint::range(0_u, size/8_u) |j| {
        let x = cmplx {re: xincr*(j as f64) - 1.5f64, im: y};
        crv.push(fillbyte(x, incr));
    };
    oldcomm::send(ch, Line {i:i, b: move crv});
}

type devnull = {dn: int};

impl devnull: io::Writer {
    fn write(&self, _b: &[const u8]) {}
    fn seek(&self, _i: int, _s: io::SeekStyle) {}
    fn tell(&self) -> uint {0_u}
    fn flush(&self) -> int {0}
    fn get_type(&self) -> io::WriterType { io::File }
}

fn writer(path: ~str, writech: oldcomm::Chan<oldcomm::Chan<Line>>, size: uint)
{
    let p: oldcomm::Port<Line> = oldcomm::Port();
    let ch = oldcomm::Chan(&p);
    oldcomm::send(writech, ch);
    let cout: io::Writer = match path {
        ~"" => {
            {dn: 0} as io::Writer
        }
        ~"-" => {
            io::stdout()
        }
        _ => {
            result::get(
                &io::file_writer(&Path(path),
                ~[io::Create, io::Truncate]))
        }
    };
    cout.write_line(~"P4");
    cout.write_line(fmt!("%u %u", size, size));
    let lines: HashMap<uint, ~[u8]> = HashMap();
    let mut done = 0_u;
    let mut i = 0_u;
    while i < size {
        let aline = oldcomm::recv(p);
        if aline.i == done {
            debug!("W %u", aline.i);
            cout.write(aline.b);
            done += 1_u;
            let mut prev = done;
            while prev <= i {
                if lines.contains_key(prev) {
                    debug!("WS %u", prev);
                    cout.write(lines.get(prev));
                    done += 1_u;
                    lines.remove(prev);
                    prev += 1_u;
                }
                else {
                    break
                }
            };
        }
        else {
            debug!("S %u", aline.i);
            lines.insert(aline.i, copy aline.b);    // FIXME: bad for perf
        };
        i += 1_u;
    }
}

fn main() {
    let args = os::args();
    let args = if os::getenv(~"RUST_BENCH").is_some() {
        ~[~"", ~"4000"]
    } else {
        args
    };

    let path = if vec::len(args) < 3_u { ~"" }
    else { copy args[2] };  // FIXME: bad for perf

    let size = if vec::len(args) < 2_u { 80_u }
    else { uint::from_str(args[1]).get() };

    let writep = oldcomm::Port();
    let writech = oldcomm::Chan(&writep);
    do task::spawn |move path| {
        writer(copy path, writech, size);
    };
    let ch = oldcomm::recv(writep);
    for uint::range(0_u, size) |j| {
        do task::spawn { chanmb(j, size, ch) };
    };
}
<commit_msg>really update mandelbrot to pipes<commit_after>// Copyright 2012 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.

//  based on:
//  http://shootout.alioth.debian.org/
//   u64q/program.php?test=mandelbrot&lang=python3&id=2
//
//  takes 2 optional args:
//   square image size, defaults to 80_u
//   output path, default is "" (no output), "-" means stdout
//
//  in the shootout, they use 16000 as image size
//
//  writes pbm image to output path

extern mod std;
use io::WriterUtil;
use std::map::HashMap;

struct cmplx {
    re: f64,
    im: f64
}

impl cmplx : ops::Mul<cmplx,cmplx> {
    pure fn mul(&self, x: &cmplx) -> cmplx {
        cmplx {
            re: self.re*(*x).re - self.im*(*x).im,
            im: self.re*(*x).im + self.im*(*x).re
        }
    }
}

impl cmplx : ops::Add<cmplx,cmplx> {
    pure fn add(&self, x: &cmplx) -> cmplx {
        cmplx {
            re: self.re + (*x).re,
            im: self.im + (*x).im
        }
    }
}

struct Line {i: uint, b: ~[u8]}

pure fn cabs(x: cmplx) -> f64
{
    x.re*x.re + x.im*x.im
}

fn mb(x: cmplx) -> bool
{
    let mut z = cmplx {re: 0f64, im: 0f64};
    let mut i = 0;
    let mut in = true;
    while i < 50 {
        z = z*z + x;
        if cabs(z) >= 4f64 {
            in = false;
            break;
        }
        i += 1;
    }
    in
}

fn fillbyte(x: cmplx, incr: f64) -> u8 {
    let mut rv = 0_u8;
    let mut i = 0_u8;
    while i < 8_u8 {
        let z = cmplx {re: x.re + (i as f64)*incr, im: x.im};
        if mb(z) {
            rv += 1_u8 << (7_u8 - i);
        }
        i += 1_u8;
    }
    rv
}

fn chanmb(i: uint, size: uint) -> Line
{
    let mut crv = ~[];
    let incr = 2f64/(size as f64);
    let y = incr*(i as f64) - 1f64;
    let xincr = 8f64*incr;
    for uint::range(0_u, size/8_u) |j| {
        let x = cmplx {re: xincr*(j as f64) - 1.5f64, im: y};
        crv.push(fillbyte(x, incr));
    };
    Line {i:i, b:crv}
}

type devnull = {dn: int};

impl devnull: io::Writer {
    fn write(&self, _b: &[const u8]) {}
    fn seek(&self, _i: int, _s: io::SeekStyle) {}
    fn tell(&self) -> uint {0_u}
    fn flush(&self) -> int {0}
    fn get_type(&self) -> io::WriterType { io::File }
}

fn writer(path: ~str, pport: pipes::Port<Line>, size: uint)
{
    let cout: io::Writer = match path {
        ~"" => {
            {dn: 0} as io::Writer
        }
        ~"-" => {
            io::stdout()
        }
        _ => {
            result::get(
                &io::file_writer(&Path(path),
                ~[io::Create, io::Truncate]))
        }
    };
    cout.write_line(~"P4");
    cout.write_line(fmt!("%u %u", size, size));
    let lines: HashMap<uint, ~[u8]> = HashMap();
    let mut done = 0_u;
    let mut i = 0_u;
    while i < size {
        let aline = pport.recv();
        if aline.i == done {
            debug!("W %u", aline.i);
            cout.write(aline.b);
            done += 1_u;
            let mut prev = done;
            while prev <= i {
                if lines.contains_key(prev) {
                    debug!("WS %u", prev);
                    cout.write(lines.get(prev));
                    done += 1_u;
                    lines.remove(prev);
                    prev += 1_u;
                }
                else {
                    break
                }
            };
        }
        else {
            debug!("S %u", aline.i);
            lines.insert(aline.i, copy aline.b);    // FIXME: bad for perf
        };
        i += 1_u;
    }
}

fn main() {
    let args = os::args();
    let args = if os::getenv(~"RUST_BENCH").is_some() {
        ~[~"", ~"4000"]
    } else {
        args
    };

    let path = if vec::len(args) < 3_u { ~"" }
    else { copy args[2] };  // FIXME: bad for perf

    let size = if vec::len(args) < 2_u { 80_u }
    else { uint::from_str(args[1]).get() };

    let (pport, pchan) = pipes::stream();
    let pchan = pipes::SharedChan(pchan);
    for uint::range(0_u, size) |j| {
        let cchan = pchan.clone();
        do task::spawn |move cchan| { cchan.send(chanmb(j, size)) };
    };
    writer(path, pport, size);
}
<|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.

use std::io;

struct DummyWriter;
impl Writer for DummyWriter {
    fn write(&mut self, _: &[u8]) -> io::IoResult<()> { Ok(()) }
}

static ITER: int = 50;
static LIMIT: f64 = 2.0;

fn main() {
    let args = std::os::args();
    let (w, mut out) = if args.len() < 2 {
        println!("Test mode: do not dump the image because it's not utf8, \
                  which interferes with the test runner.");
        (1000, ~DummyWriter as ~Writer)
    } else {
        (from_str(args[1]).unwrap(),
         ~std::io::stdout() as ~Writer)
    };
    let h = w;
    let mut byte_acc = 0u8;
    let mut bit_num = 0;

    writeln!(out, "P4\n{} {}", w, h);

    for y in range(0, h) {
        let y = y as f64;
        for x in range(0, w) {
            let mut z_r = 0f64;
            let mut z_i = 0f64;
            let mut t_r = 0f64;
            let mut t_i = 0f64;
            let c_r = 2.0 * (x as f64) / (w as f64) - 1.5;
            let c_i = 2.0 * (y as f64) / (h as f64) - 1.0;

            for _ in range(0, ITER) {
                if t_r + t_i > LIMIT * LIMIT {
                    break;
                }

                z_i = 2.0 * z_r * z_i + c_i;
                z_r = t_r - t_i + c_r;
                t_r = z_r * z_r;
                t_i = z_i * z_i;
            }

            byte_acc <<= 1;
            if t_r + t_i <= LIMIT * LIMIT {
                byte_acc |= 1;
            }

            bit_num += 1;

            if bit_num == 8 {
                out.write_u8(byte_acc);
                byte_acc = 0;
                bit_num = 0;
            } else if x == w - 1 {
                byte_acc <<= 8 - w % 8;
                out.write_u8(byte_acc);
                byte_acc = 0;
                bit_num = 0;
            }
        }
    }

    out.flush();
}
<commit_msg>auto merge of #13916 : TeXitoi/rust/shootout-mandelbrot-rewrite, r=pcwalton<commit_after>// Copyright 2012-2014 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.

extern crate sync;

use std::io;
use sync::Future;

static ITER: int = 50;
static LIMIT: f64 = 2.0;

fn write_line(init_i: f64, vec_init_r: &[f64], res: &mut Vec<u8>) {
    for chunk_init_r in vec_init_r.chunks(8) {
        let mut cur_byte = 0xff;
        let mut cur_bitmask = 0x80;
        for &init_r in chunk_init_r.iter() {
            let mut cur_r = init_r;
            let mut cur_i = init_i;
            for _ in range(0, ITER) {
                let r = cur_r;
                let i = cur_i;
                cur_r = r * r - i * i + init_r;
                cur_i = 2.0 * r * i + init_i;

                if r * r + i * i > LIMIT * LIMIT {
                    cur_byte &= !cur_bitmask;
                    break;
                }
            }
            cur_bitmask >>= 1;
        }
        res.push(cur_byte);
    }
}

fn mandelbrot<W: io::Writer>(w: uint, mut out: W) -> io::IoResult<()> {
    // Ensure w and h are multiples of 8.
    let w = (w + 7) / 8 * 8;
    let h = w;
    let chunk_size = h / 8;

    let data: Vec<Future<Vec<u8>>> = range(0u, 8).map(|i| Future::spawn(proc () {
        let vec_init_r = Vec::from_fn(w, |x| 2.0 * (x as f64) / (w as f64) - 1.5);
        let mut res: Vec<u8> = Vec::with_capacity((chunk_size * w) / 8);
        for y in range(i * chunk_size, (i + 1) * chunk_size) {
            let init_i = 2.0 * (y as f64) / (h as f64) - 1.0;
            write_line(init_i, vec_init_r.as_slice(), &mut res);
        }
        res
    })).collect();

    try!(writeln!(&mut out as &mut Writer, "P4\n{} {}", w, h));
    for res in data.move_iter() {
        try!(out.write(res.unwrap().as_slice()));
    }
    out.flush()
}

fn main() {
    let args = std::os::args();
    let res = if args.len() < 2 {
        println!("Test mode: do not dump the image because it's not utf8, \
                  which interferes with the test runner.");
        mandelbrot(1000, std::io::util::NullWriter)
    } else {
        mandelbrot(from_str(args[1]).unwrap(), std::io::stdout())
    };
    res.unwrap();
}
<|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.

// xfail-fast
// compile-flags:--test

// NB: These tests kill child processes. Valgrind sees these children as leaking
// memory, which makes for some *confusing* logs. That's why these are here
// instead of in std.

use std::libc;
use std::run;
use std::str;
use std::io;

#[test]
fn test_destroy_once() {
    let mut p = run::Process::new("echo", [], run::ProcessOptions::new());
    p.destroy(); // this shouldn't crash (and nor should the destructor)
}

#[test]
fn test_destroy_twice() {
    let mut p = run::Process::new("echo", [], run::ProcessOptions::new());
    p.destroy(); // this shouldnt crash...
    do io::io_error::cond.trap(|_| {}).inside {
        p.destroy(); // ...and nor should this (and nor should the destructor)
    }
}

fn test_destroy_actually_kills(force: bool) {

    #[cfg(unix,not(target_os="android"))]
    static BLOCK_COMMAND: &'static str = "cat";

    #[cfg(unix,target_os="android")]
    static BLOCK_COMMAND: &'static str = "/system/bin/cat";

    #[cfg(windows)]
    static BLOCK_COMMAND: &'static str = "cmd";

    #[cfg(unix,not(target_os="android"))]
    fn process_exists(pid: libc::pid_t) -> bool {
        let run::ProcessOutput {output, _} = run::process_output("ps", [~"-p", pid.to_str()]);
        str::from_utf8(output).contains(pid.to_str())
    }

    #[cfg(unix,target_os="android")]
    fn process_exists(pid: libc::pid_t) -> bool {
        let run::ProcessOutput {output, _} = run::process_output("/system/bin/ps", [pid.to_str()]);
        str::from_utf8(output).contains(~"root")
    }

    #[cfg(windows)]
    fn process_exists(pid: libc::pid_t) -> bool {
        use std::libc::types::os::arch::extra::DWORD;
        use std::libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};
        use std::libc::consts::os::extra::{FALSE, PROCESS_QUERY_INFORMATION, STILL_ACTIVE };

        unsafe {
            let process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid as DWORD);
            if process.is_null() {
                return false;
            }
            // process will be non-null if the process is alive, or if it died recently
            let mut status = 0;
            GetExitCodeProcess(process, &mut status);
            CloseHandle(process);
            return status == STILL_ACTIVE;
        }
    }

    // this process will stay alive indefinitely trying to read from stdin
    let mut p = run::Process::new(BLOCK_COMMAND, [], run::ProcessOptions::new());

    assert!(process_exists(p.get_id()));

    if force {
        p.force_destroy();
    } else {
        p.destroy();
    }

    assert!(!process_exists(p.get_id()));
}

#[test]
fn test_unforced_destroy_actually_kills() {
    test_destroy_actually_kills(false);
}

#[test]
fn test_forced_destroy_actually_kills() {
    test_destroy_actually_kills(true);
}
<commit_msg>fix #10450<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.

// xfail-fast
// compile-flags:--test

// NB: These tests kill child processes. Valgrind sees these children as leaking
// memory, which makes for some *confusing* logs. That's why these are here
// instead of in std.

use std::libc;
use std::run;
use std::str;
use std::io;

#[test]
fn test_destroy_once() {
    #[cfg(not(target_os="android"))]
    static PROG: &'static str = "echo";
    #[cfg(target_os="android")]
    static PROG: &'static str = "ls"; // android don't have echo binary

    let mut p = run::Process::new(PROG, [], run::ProcessOptions::new());
    p.destroy(); // this shouldn't crash (and nor should the destructor)
}

#[test]
fn test_destroy_twice() {
    #[cfg(not(target_os="android"))]
    static PROG: &'static str = "echo";
    #[cfg(target_os="android")]
    static PROG: &'static str = "ls"; // android don't have echo binary

    let mut p = run::Process::new(PROG, [], run::ProcessOptions::new());
    p.destroy(); // this shouldnt crash...
    do io::io_error::cond.trap(|_| {}).inside {
        p.destroy(); // ...and nor should this (and nor should the destructor)
    }
}

fn test_destroy_actually_kills(force: bool) {

    #[cfg(unix,not(target_os="android"))]
    static BLOCK_COMMAND: &'static str = "cat";

    #[cfg(unix,target_os="android")]
    static BLOCK_COMMAND: &'static str = "/system/bin/cat";

    #[cfg(windows)]
    static BLOCK_COMMAND: &'static str = "cmd";

    #[cfg(unix,not(target_os="android"))]
    fn process_exists(pid: libc::pid_t) -> bool {
        let run::ProcessOutput {output, _} = run::process_output("ps", [~"-p", pid.to_str()]);
        str::from_utf8(output).contains(pid.to_str())
    }

    #[cfg(unix,target_os="android")]
    fn process_exists(pid: libc::pid_t) -> bool {
        let run::ProcessOutput {output, _} = run::process_output("/system/bin/ps", [pid.to_str()]);
        str::from_utf8(output).contains(~"root")
    }

    #[cfg(windows)]
    fn process_exists(pid: libc::pid_t) -> bool {
        use std::libc::types::os::arch::extra::DWORD;
        use std::libc::funcs::extra::kernel32::{CloseHandle, GetExitCodeProcess, OpenProcess};
        use std::libc::consts::os::extra::{FALSE, PROCESS_QUERY_INFORMATION, STILL_ACTIVE };

        unsafe {
            let process = OpenProcess(PROCESS_QUERY_INFORMATION, FALSE, pid as DWORD);
            if process.is_null() {
                return false;
            }
            // process will be non-null if the process is alive, or if it died recently
            let mut status = 0;
            GetExitCodeProcess(process, &mut status);
            CloseHandle(process);
            return status == STILL_ACTIVE;
        }
    }

    // this process will stay alive indefinitely trying to read from stdin
    let mut p = run::Process::new(BLOCK_COMMAND, [], run::ProcessOptions::new());

    assert!(process_exists(p.get_id()));

    if force {
        p.force_destroy();
    } else {
        p.destroy();
    }

    assert!(!process_exists(p.get_id()));
}

#[test]
fn test_unforced_destroy_actually_kills() {
    test_destroy_actually_kills(false);
}

#[test]
fn test_forced_destroy_actually_kills() {
    test_destroy_actually_kills(true);
}
<|endoftext|>


<commit_before>//! FIXME: write short doc here

use ra_db::{FileId, FilePosition};
use ra_syntax::{
    algo::find_node_at_offset,
    ast::{self, AstNode, NameOwner},
    SyntaxNode,
};

use crate::{
    db::{AstDatabase, DefDatabase, HirDatabase},
    ids::{AstItemDef, LocationCtx},
    name::AsName,
    Const, Crate, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock, Module,
    ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef,
};

pub trait FromSource: Sized {
    type Ast;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self>;
}

impl FromSource for Struct {
    type Ast = ast::StructDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Struct { id })
    }
}
impl FromSource for Union {
    type Ast = ast::StructDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Union { id })
    }
}
impl FromSource for Enum {
    type Ast = ast::EnumDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Enum { id })
    }
}
impl FromSource for Trait {
    type Ast = ast::TraitDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Trait { id })
    }
}
impl FromSource for Function {
    type Ast = ast::FnDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Function { id })
    }
}
impl FromSource for Const {
    type Ast = ast::ConstDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Const { id })
    }
}
impl FromSource for Static {
    type Ast = ast::StaticDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Static { id })
    }
}
impl FromSource for TypeAlias {
    type Ast = ast::TypeAliasDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(TypeAlias { id })
    }
}
// FIXME: add impl FromSource for MacroDef

impl FromSource for ImplBlock {
    type Ast = ast::ImplBlock;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let module_src = crate::ModuleSource::from_child_node(
            db,
            src.file_id.original_file(db),
            &src.ast.syntax(),
        );
        let module = Module::from_definition(db, Source { file_id: src.file_id, ast: module_src })?;
        let impls = module.impl_blocks(db);
        impls.into_iter().find(|b| b.source(db) == src)
    }
}

impl FromSource for EnumVariant {
    type Ast = ast::EnumVariant;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let parent_enum = src.ast.parent_enum();
        let src_enum = Source { file_id: src.file_id, ast: parent_enum };
        let variants = Enum::from_source(db, src_enum)?.variants(db);
        variants.into_iter().find(|v| v.source(db) == src)
    }
}

impl FromSource for StructField {
    type Ast = FieldSource;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let variant_def: VariantDef = match src.ast {
            FieldSource::Named(ref field) => {
                let ast = field.syntax().ancestors().find_map(ast::StructDef::cast)?;
                let src = Source { file_id: src.file_id, ast };
                let def = Struct::from_source(db, src)?;
                VariantDef::from(def)
            }
            FieldSource::Pos(ref field) => {
                let ast = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?;
                let src = Source { file_id: src.file_id, ast };
                let def = EnumVariant::from_source(db, src)?;
                VariantDef::from(def)
            }
        };
        variant_def
            .variant_data(db)
            .fields()
            .into_iter()
            .flat_map(|it| it.iter())
            .map(|(id, _)| StructField { parent: variant_def, id })
            .find(|f| f.source(db) == src)
    }
}

// FIXME: simplify it
impl ModuleSource {
    pub fn from_position(
        db: &(impl DefDatabase + AstDatabase),
        position: FilePosition,
    ) -> ModuleSource {
        let parse = db.parse(position.file_id);
        match &find_node_at_offset::<ast::Module>(parse.tree().syntax(), position.offset) {
            Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()),
            _ => {
                let source_file = parse.tree();
                ModuleSource::SourceFile(source_file)
            }
        }
    }

    pub fn from_child_node(
        db: &(impl DefDatabase + AstDatabase),
        file_id: FileId,
        child: &SyntaxNode,
    ) -> ModuleSource {
        if let Some(m) = child.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) {
            ModuleSource::Module(m)
        } else {
            let source_file = db.parse(file_id).tree();
            ModuleSource::SourceFile(source_file)
        }
    }

    pub fn from_file_id(db: &(impl DefDatabase + AstDatabase), file_id: FileId) -> ModuleSource {
        let source_file = db.parse(file_id).tree();
        ModuleSource::SourceFile(source_file)
    }
}

impl Module {
    pub fn from_declaration(db: &impl HirDatabase, src: Source<ast::Module>) -> Option<Self> {
        let src_parent = Source {
            file_id: src.file_id,
            ast: ModuleSource::new(db, Some(src.file_id.original_file(db)), None),
        };
        let parent_module = Module::from_definition(db, src_parent)?;
        let child_name = src.ast.name()?;
        parent_module.child(db, &child_name.as_name())
    }

    pub fn from_definition(
        db: &(impl DefDatabase + AstDatabase),
        src: Source<ModuleSource>,
    ) -> Option<Self> {
        let decl_id = match src.ast {
            ModuleSource::Module(ref module) => {
                let ast_id_map = db.ast_id_map(src.file_id);
                let item_id = ast_id_map.ast_id(module).with_file_id(src.file_id);
                Some(item_id)
            }
            ModuleSource::SourceFile(_) => None,
        };

        db.relevant_crates(src.file_id.original_file(db))
            .iter()
            .map(|&crate_id| Crate { crate_id })
            .find_map(|krate| {
                let def_map = db.crate_def_map(krate);
                let module_id = def_map.find_module_by_source(src.file_id, decl_id)?;
                Some(Module { krate, module_id })
            })
    }
}

fn from_source<N, DEF>(db: &(impl DefDatabase + AstDatabase), src: Source<N>) -> Option<DEF>
where
    N: AstNode,
    DEF: AstItemDef<N>,
{
    let module_src =
        crate::ModuleSource::from_child_node(db, src.file_id.original_file(db), &src.ast.syntax());
    let module = Module::from_definition(db, Source { file_id: src.file_id, ast: module_src })?;
    let ctx = LocationCtx::new(db, module, src.file_id);
    Some(DEF::from_ast(ctx, &src.ast))
}
<commit_msg>restore assert<commit_after>//! FIXME: write short doc here

use ra_db::{FileId, FilePosition};
use ra_syntax::{
    algo::find_node_at_offset,
    ast::{self, AstNode, NameOwner},
    SyntaxNode,
};

use crate::{
    db::{AstDatabase, DefDatabase, HirDatabase},
    ids::{AstItemDef, LocationCtx},
    name::AsName,
    Const, Crate, Enum, EnumVariant, FieldSource, Function, HasSource, ImplBlock, Module,
    ModuleSource, Source, Static, Struct, StructField, Trait, TypeAlias, Union, VariantDef,
};

pub trait FromSource: Sized {
    type Ast;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self>;
}

impl FromSource for Struct {
    type Ast = ast::StructDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Struct { id })
    }
}
impl FromSource for Union {
    type Ast = ast::StructDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Union { id })
    }
}
impl FromSource for Enum {
    type Ast = ast::EnumDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Enum { id })
    }
}
impl FromSource for Trait {
    type Ast = ast::TraitDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Trait { id })
    }
}
impl FromSource for Function {
    type Ast = ast::FnDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Function { id })
    }
}
impl FromSource for Const {
    type Ast = ast::ConstDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Const { id })
    }
}
impl FromSource for Static {
    type Ast = ast::StaticDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(Static { id })
    }
}
impl FromSource for TypeAlias {
    type Ast = ast::TypeAliasDef;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let id = from_source(db, src)?;
        Some(TypeAlias { id })
    }
}
// FIXME: add impl FromSource for MacroDef

impl FromSource for ImplBlock {
    type Ast = ast::ImplBlock;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let module_src = crate::ModuleSource::from_child_node(
            db,
            src.file_id.original_file(db),
            &src.ast.syntax(),
        );
        let module = Module::from_definition(db, Source { file_id: src.file_id, ast: module_src })?;
        let impls = module.impl_blocks(db);
        impls.into_iter().find(|b| b.source(db) == src)
    }
}

impl FromSource for EnumVariant {
    type Ast = ast::EnumVariant;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let parent_enum = src.ast.parent_enum();
        let src_enum = Source { file_id: src.file_id, ast: parent_enum };
        let variants = Enum::from_source(db, src_enum)?.variants(db);
        variants.into_iter().find(|v| v.source(db) == src)
    }
}

impl FromSource for StructField {
    type Ast = FieldSource;
    fn from_source(db: &(impl DefDatabase + AstDatabase), src: Source<Self::Ast>) -> Option<Self> {
        let variant_def: VariantDef = match src.ast {
            FieldSource::Named(ref field) => {
                let ast = field.syntax().ancestors().find_map(ast::StructDef::cast)?;
                let src = Source { file_id: src.file_id, ast };
                let def = Struct::from_source(db, src)?;
                VariantDef::from(def)
            }
            FieldSource::Pos(ref field) => {
                let ast = field.syntax().ancestors().find_map(ast::EnumVariant::cast)?;
                let src = Source { file_id: src.file_id, ast };
                let def = EnumVariant::from_source(db, src)?;
                VariantDef::from(def)
            }
        };
        variant_def
            .variant_data(db)
            .fields()
            .into_iter()
            .flat_map(|it| it.iter())
            .map(|(id, _)| StructField { parent: variant_def, id })
            .find(|f| f.source(db) == src)
    }
}

// FIXME: simplify it
impl ModuleSource {
    pub fn from_position(
        db: &(impl DefDatabase + AstDatabase),
        position: FilePosition,
    ) -> ModuleSource {
        let parse = db.parse(position.file_id);
        match &find_node_at_offset::<ast::Module>(parse.tree().syntax(), position.offset) {
            Some(m) if !m.has_semi() => ModuleSource::Module(m.clone()),
            _ => {
                let source_file = parse.tree();
                ModuleSource::SourceFile(source_file)
            }
        }
    }

    pub fn from_child_node(
        db: &(impl DefDatabase + AstDatabase),
        file_id: FileId,
        child: &SyntaxNode,
    ) -> ModuleSource {
        if let Some(m) = child.ancestors().filter_map(ast::Module::cast).find(|it| !it.has_semi()) {
            ModuleSource::Module(m)
        } else {
            let source_file = db.parse(file_id).tree();
            ModuleSource::SourceFile(source_file)
        }
    }

    pub fn from_file_id(db: &(impl DefDatabase + AstDatabase), file_id: FileId) -> ModuleSource {
        let source_file = db.parse(file_id).tree();
        ModuleSource::SourceFile(source_file)
    }
}

impl Module {
    pub fn from_declaration(db: &impl HirDatabase, src: Source<ast::Module>) -> Option<Self> {
        let src_parent = Source {
            file_id: src.file_id,
            ast: ModuleSource::new(db, Some(src.file_id.original_file(db)), None),
        };
        let parent_module = Module::from_definition(db, src_parent)?;
        let child_name = src.ast.name()?;
        parent_module.child(db, &child_name.as_name())
    }

    pub fn from_definition(
        db: &(impl DefDatabase + AstDatabase),
        src: Source<ModuleSource>,
    ) -> Option<Self> {
        let decl_id = match src.ast {
            ModuleSource::Module(ref module) => {
                assert!(!module.has_semi());
                let ast_id_map = db.ast_id_map(src.file_id);
                let item_id = ast_id_map.ast_id(module).with_file_id(src.file_id);
                Some(item_id)
            }
            ModuleSource::SourceFile(_) => None,
        };

        db.relevant_crates(src.file_id.original_file(db))
            .iter()
            .map(|&crate_id| Crate { crate_id })
            .find_map(|krate| {
                let def_map = db.crate_def_map(krate);
                let module_id = def_map.find_module_by_source(src.file_id, decl_id)?;
                Some(Module { krate, module_id })
            })
    }
}

fn from_source<N, DEF>(db: &(impl DefDatabase + AstDatabase), src: Source<N>) -> Option<DEF>
where
    N: AstNode,
    DEF: AstItemDef<N>,
{
    let module_src =
        crate::ModuleSource::from_child_node(db, src.file_id.original_file(db), &src.ast.syntax());
    let module = Module::from_definition(db, Source { file_id: src.file_id, ast: module_src })?;
    let ctx = LocationCtx::new(db, module, src.file_id);
    Some(DEF::from_ast(ctx, &src.ast))
}
<|endoftext|>


<commit_before>use crate::io;
use crate::io::{IoSlice, IoSliceMut};
use crate::sys::hermit::abi;

pub struct Stdin;
pub struct Stdout;
pub struct Stderr;

impl Stdin {
    pub fn new() -> io::Result<Stdin> {
        Ok(Stdin)
    }
}

impl io::Read for Stdin {
    fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
        self.read_vectored(&mut [IoSliceMut::new(data)])
    }

    fn read_vectored(&self, _data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        //ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) })
        //    .read(data)
        Ok(0)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        true
    }
}

impl Stdout {
    pub fn new() -> io::Result<Stdout> {
        Ok(Stdout)
    }
}

impl io::Write for Stdout {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        let len;

        unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }

        if len < 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Stdout is not able to print"))
        } else {
            Ok(len as usize)
        }
    }

    fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
        let len;

        unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }

        if len < 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Stdout is not able to print"))
        } else {
            Ok(len as usize)
        }
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        true
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl Stderr {
    pub fn new() -> io::Result<Stderr> {
        Ok(Stderr)
    }
}

impl io::Write for Stderr {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        let len;

        unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }

        if len < 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print"))
        } else {
            Ok(len as usize)
        }
    }

    fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
        let len;

        unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }

        if len < 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print"))
        } else {
            Ok(len as usize)
        }
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        true
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

pub const STDIN_BUF_SIZE: usize = 0;

pub fn is_ebadf(_err: &io::Error) -> bool {
    true
}

pub fn panic_output() -> Option<impl io::Write> {
    Stderr::new().ok()
}
<commit_msg>Fixed missing `mut`<commit_after>use crate::io;
use crate::io::{IoSlice, IoSliceMut};
use crate::sys::hermit::abi;

pub struct Stdin;
pub struct Stdout;
pub struct Stderr;

impl Stdin {
    pub fn new() -> io::Result<Stdin> {
        Ok(Stdin)
    }
}

impl io::Read for Stdin {
    fn read(&mut self, data: &mut [u8]) -> io::Result<usize> {
        self.read_vectored(&mut [IoSliceMut::new(data)])
    }

    fn read_vectored(&mut self, _data: &mut [IoSliceMut<'_>]) -> io::Result<usize> {
        //ManuallyDrop::new(unsafe { WasiFd::from_raw(libc::STDIN_FILENO as u32) })
        //    .read(data)
        Ok(0)
    }

    #[inline]
    fn is_read_vectored(&self) -> bool {
        true
    }
}

impl Stdout {
    pub fn new() -> io::Result<Stdout> {
        Ok(Stdout)
    }
}

impl io::Write for Stdout {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        let len;

        unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }

        if len < 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Stdout is not able to print"))
        } else {
            Ok(len as usize)
        }
    }

    fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
        let len;

        unsafe { len = abi::write(1, data.as_ptr() as *const u8, data.len()) }

        if len < 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Stdout is not able to print"))
        } else {
            Ok(len as usize)
        }
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        true
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

impl Stderr {
    pub fn new() -> io::Result<Stderr> {
        Ok(Stderr)
    }
}

impl io::Write for Stderr {
    fn write(&mut self, data: &[u8]) -> io::Result<usize> {
        let len;

        unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }

        if len < 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print"))
        } else {
            Ok(len as usize)
        }
    }

    fn write_vectored(&mut self, data: &[IoSlice<'_>]) -> io::Result<usize> {
        let len;

        unsafe { len = abi::write(2, data.as_ptr() as *const u8, data.len()) }

        if len < 0 {
            Err(io::Error::new(io::ErrorKind::Other, "Stderr is not able to print"))
        } else {
            Ok(len as usize)
        }
    }

    #[inline]
    fn is_write_vectored(&self) -> bool {
        true
    }

    fn flush(&mut self) -> io::Result<()> {
        Ok(())
    }
}

pub const STDIN_BUF_SIZE: usize = 0;

pub fn is_ebadf(_err: &io::Error) -> bool {
    true
}

pub fn panic_output() -> Option<impl io::Write> {
    Stderr::new().ok()
}
<|endoftext|>


<commit_before>#![feature(test)]
extern crate test;
extern crate tera;
#[macro_use]
extern crate serde_derive;

use tera::{Tera, Template, Context, escape_html};

static VARIABLE_ONLY: &'static str = "{{product.name}}";

static SIMPLE_TEMPLATE: &'static str = "

    <title>{{ product.name }}</title>

{{ product.name }} - {{ product.manufacturer | upper }}

{{ product.summary }}

£{{ product.price * 1.20 }} (VAT inc.)

Look at reviews from your friends {{ username }}

    <button>Buy!</button>

";

static PARENT_TEMPLATE: &'static str = "

    <title>{% block title %}Hello{% endblock title%}</title>

    {% block body %}{% endblock body %}

";

static MACRO_TEMPLATE: &'static str = "
{% macro render_product(product) %}

{{ product.name }} - {{ product.manufacturer | upper }}

{{ product.summary }}

£{{ product.price * 1.20 }} (VAT inc.)

    <button>Buy!</button>
{% endmacro render_product %}
";

static CHILD_TEMPLATE: &'static str = r#"{% extends "parent.html" %}
{% block title %}{{ super() }} - {{ username | lower }}{% endblock title %}

{% block body %}body{% endblock body %}
"#;

static CHILD_TEMPLATE_WITH_MACRO: &'static str = r#"{% extends "parent.html" %}
{% import "macros.html" as macros %}

{% block title %}{{ super() }} - {{ username | lower }}{% endblock title %}

{% block body %}
{{ macros::render_product(product=product) }}
{% endblock body %}
"#;

static USE_MACRO_TEMPLATE: &'static str = r#"
{% import "macros.html" as macros %}
{{ macros::render_product(product=product) }}
"#;

#[derive(Debug, Serialize)]
struct Product {
    name: String,
    manufacturer: String,
    price: i32,
    summary: String
}
impl Product {
    pub fn new() -> Product {
        Product {
            name: "Moto G".to_owned(),
            manufacturer: "Motorala".to_owned(),
            summary: "A phone".to_owned(),
            price: 100
        }
    }
}

#[bench]
fn bench_parsing_basic_template(b: &mut test::Bencher) {
    b.iter(|| Template::new("bench", None, SIMPLE_TEMPLATE));
}

#[bench]
fn bench_parsing_with_inheritance_and_macros(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    b.iter(|| tera.add_raw_templates(vec![
        ("parent.html", PARENT_TEMPLATE),
        ("child.html", CHILD_TEMPLATE),
        ("macros.html", MACRO_TEMPLATE),
    ]));
}

#[bench]
fn bench_rendering_only_variable(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_template("test.html", VARIABLE_ONLY).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("test.html", &context));
}

#[bench]
fn bench_rendering_basic_template(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_template("bench.html", SIMPLE_TEMPLATE).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("bench.html", &context));
}

#[bench]
fn bench_rendering_only_parent(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("parent.html", PARENT_TEMPLATE),
    ]).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("parent.html", &context));
}

#[bench]
fn bench_rendering_only_macro_call(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("hey.html", USE_MACRO_TEMPLATE),
    ]).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("hey.html", &context));
}

#[bench]
fn bench_rendering_only_inheritance(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("parent.html", PARENT_TEMPLATE),
        ("child.html", CHILD_TEMPLATE),
    ]).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("child.html", &context));
}

#[bench]
fn bench_rendering_inheritance_and_macros(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("parent.html", PARENT_TEMPLATE),
        ("child.html", CHILD_TEMPLATE_WITH_MACRO),
        ("macros.html", MACRO_TEMPLATE),
    ]).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("child.html", &context));
}

#[bench]
fn bench_build_inheritance_chains(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("parent.html", PARENT_TEMPLATE),
        ("child.html", CHILD_TEMPLATE_WITH_MACRO),
        ("macros.html", MACRO_TEMPLATE),
    ]).unwrap();
    b.iter(|| tera.build_inheritance_chains());
}

#[bench]
fn bench_escape_html(b: &mut test::Bencher) {
    b.iter(|| escape_html(r#"Hello word "#));
}
<commit_msg>Add bench for huge loop<commit_after>#![feature(test)]
extern crate test;
extern crate tera;
#[macro_use]
extern crate serde_derive;

use tera::{Tera, Template, Context, escape_html};

static VARIABLE_ONLY: &'static str = "{{product.name}}";

static SIMPLE_TEMPLATE: &'static str = "

    <title>{{ product.name }}</title>

{{ product.name }} - {{ product.manufacturer | upper }}

{{ product.summary }}

£{{ product.price * 1.20 }} (VAT inc.)

Look at reviews from your friends {{ username }}

    <button>Buy!</button>

";

static PARENT_TEMPLATE: &'static str = "

    <title>{% block title %}Hello{% endblock title%}</title>

    {% block body %}{% endblock body %}

";

static MACRO_TEMPLATE: &'static str = "
{% macro render_product(product) %}

{{ product.name }} - {{ product.manufacturer | upper }}

{{ product.summary }}

£{{ product.price * 1.20 }} (VAT inc.)

    <button>Buy!</button>
{% endmacro render_product %}
";

static CHILD_TEMPLATE: &'static str = r#"{% extends "parent.html" %}
{% block title %}{{ super() }} - {{ username | lower }}{% endblock title %}

{% block body %}body{% endblock body %}
"#;

static CHILD_TEMPLATE_WITH_MACRO: &'static str = r#"{% extends "parent.html" %}
{% import "macros.html" as macros %}

{% block title %}{{ super() }} - {{ username | lower }}{% endblock title %}

{% block body %}
{{ macros::render_product(product=product) }}
{% endblock body %}
"#;

static USE_MACRO_TEMPLATE: &'static str = r#"
{% import "macros.html" as macros %}
{{ macros::render_product(product=product) }}
"#;

#[derive(Debug, Serialize)]
struct Product {
    name: String,
    manufacturer: String,
    price: i32,
    summary: String
}
impl Product {
    pub fn new() -> Product {
        Product {
            name: "Moto G".to_owned(),
            manufacturer: "Motorala".to_owned(),
            summary: "A phone".to_owned(),
            price: 100
        }
    }
}

#[bench]
fn bench_parsing_basic_template(b: &mut test::Bencher) {
    b.iter(|| Template::new("bench", None, SIMPLE_TEMPLATE));
}

#[bench]
fn bench_parsing_with_inheritance_and_macros(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    b.iter(|| tera.add_raw_templates(vec![
        ("parent.html", PARENT_TEMPLATE),
        ("child.html", CHILD_TEMPLATE),
        ("macros.html", MACRO_TEMPLATE),
    ]));
}

#[bench]
fn bench_rendering_only_variable(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_template("test.html", VARIABLE_ONLY).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("test.html", &context));
}

#[bench]
fn bench_rendering_basic_template(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_template("bench.html", SIMPLE_TEMPLATE).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("bench.html", &context));
}

#[bench]
fn bench_rendering_only_parent(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("parent.html", PARENT_TEMPLATE),
    ]).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("parent.html", &context));
}

#[bench]
fn bench_rendering_only_macro_call(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("hey.html", USE_MACRO_TEMPLATE),
    ]).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("hey.html", &context));
}

#[bench]
fn bench_rendering_only_inheritance(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("parent.html", PARENT_TEMPLATE),
        ("child.html", CHILD_TEMPLATE),
    ]).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("child.html", &context));
}

#[bench]
fn bench_rendering_inheritance_and_macros(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("parent.html", PARENT_TEMPLATE),
        ("child.html", CHILD_TEMPLATE_WITH_MACRO),
        ("macros.html", MACRO_TEMPLATE),
    ]).unwrap();
    let mut context = Context::new();
    context.add("product", &Product::new());
    context.add("username", &"bob");

    b.iter(|| tera.render("child.html", &context));
}

#[bench]
fn bench_build_inheritance_chains(b: &mut test::Bencher) {
    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("parent.html", PARENT_TEMPLATE),
        ("child.html", CHILD_TEMPLATE_WITH_MACRO),
        ("macros.html", MACRO_TEMPLATE),
    ]).unwrap();
    b.iter(|| tera.build_inheritance_chains());
}

#[bench]
fn bench_escape_html(b: &mut test::Bencher) {
    b.iter(|| escape_html(r#"Hello word "#));
}

#[bench]
fn bench_huge_loop(b: &mut test::Bencher) {
    #[derive(Serialize)]
    struct DataWrapper {
        v: String,
    }

    #[derive(Serialize)]
    struct RowWrapper {
        real: Vec<DataWrapper>,
        dummy: Vec<DataWrapper>,
    }
    let real: Vec<DataWrapper> = (1..1000)
        .into_iter()
        .map(|i| DataWrapper { v: format!("n={}", i) })
        .collect();
    let dummy: Vec<DataWrapper> = (1..1000)
        .into_iter()
        .map(|i| DataWrapper { v: format!("n={}", i) })
        .collect();
    let rows = RowWrapper { real, dummy };

    let mut tera = Tera::default();
    tera.add_raw_templates(vec![
        ("huge.html", "{% for v in rows %}{{v}}{% endfor %}"),
    ]).unwrap();
    let mut context = Context::new();
    context.add("rows", &rows);

    b.iter(|| tera.render("huge.html", &context));
}
<|endoftext|>


<commit_before>use command_prelude::*;

use cargo::ops::{self, OwnersOptions};

pub fn cli() -> App {
    subcommand("owner")
        .about("Manage the owners of a crate on the registry")
        .arg(Arg::with_name("crate"))
        .arg(multi_opt("add", "LOGIN", "Name of a user or team to add as an owner").short("a"))
        .arg(
            multi_opt(
                "remove",
                "LOGIN",
                "Name of a user or team to remove as an owner",
            ).short("r"),
        )
        .arg(opt("list", "List owners of a crate").short("l"))
        .arg(opt("index", "Registry index to modify owners for").value_name("INDEX"))
        .arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
        .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
        .after_help(
            "\
    This command will modify the owners for a package
    on the specified registry(or
    default).Note that owners of a package can upload new versions, yank old
    versions.Explicitly named owners can also modify the set of owners, so take
    caution!

        See http://doc.crates.io/crates-io.html#cargo-owner for detailed documentation
        and troubleshooting.",
        )
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
    let registry = args.registry(config)?;
    let opts = OwnersOptions {
        krate: args.value_of("crate").map(|s| s.to_string()),
        token: args.value_of("token").map(|s| s.to_string()),
        index: args.value_of("index").map(|s| s.to_string()),
        to_add: args.values_of("add")
            .map(|xs| xs.map(|s| s.to_string()).collect()),
        to_remove: args.values_of("remove")
            .map(|xs| xs.map(|s| s.to_string()).collect()),
        list: args.is_present("list"),
        registry,
    };
    ops::modify_owners(config, &opts)?;
    Ok(())
}
<commit_msg>Auto merge of #5773 - Metaswitch:cargo-owner-help, r=dwijnand<commit_after>use command_prelude::*;

use cargo::ops::{self, OwnersOptions};

pub fn cli() -> App {
    subcommand("owner")
        .about("Manage the owners of a crate on the registry")
        .arg(Arg::with_name("crate"))
        .arg(multi_opt("add", "LOGIN", "Name of a user or team to add as an owner").short("a"))
        .arg(
            multi_opt(
                "remove",
                "LOGIN",
                "Name of a user or team to remove as an owner",
            ).short("r"),
        )
        .arg(opt("list", "List owners of a crate").short("l"))
        .arg(opt("index", "Registry index to modify owners for").value_name("INDEX"))
        .arg(opt("token", "API token to use when authenticating").value_name("TOKEN"))
        .arg(opt("registry", "Registry to use").value_name("REGISTRY"))
        .after_help("\
This command will modify the owners for a crate on the specified registry (or
default). Owners of a crate can upload new versions and yank old versions.
Explicitly named owners can also modify the set of owners, so take care!

    See https://doc.rust-lang.org/cargo/reference/publishing.html#cargo-owner
    for detailed documentation and troubleshooting.",
        )
}

pub fn exec(config: &mut Config, args: &ArgMatches) -> CliResult {
    let registry = args.registry(config)?;
    let opts = OwnersOptions {
        krate: args.value_of("crate").map(|s| s.to_string()),
        token: args.value_of("token").map(|s| s.to_string()),
        index: args.value_of("index").map(|s| s.to_string()),
        to_add: args.values_of("add")
            .map(|xs| xs.map(|s| s.to_string()).collect()),
        to_remove: args.values_of("remove")
            .map(|xs| xs.map(|s| s.to_string()).collect()),
        list: args.is_present("list"),
        registry,
    };
    ops::modify_owners(config, &opts)?;
    Ok(())
}
<|endoftext|>


<commit_before>//! Plugin which transforms `dc::File` to point at local clones of GitHub
//! repositories.

use docker_compose::v2 as dc;
use std::marker::PhantomData;

use ext::service::ServiceExt;
use plugins;
use plugins::{Operation, PluginNew, PluginTransform};
use project::Project;
use util::{ConductorPathExt, Error};

/// Transforms `dc::File` to point at local clones of GitHub
/// repositories.
#[derive(Debug)]
#[allow(missing_copy_implementations)]
pub struct Plugin {
    /// Placeholder field for future hidden fields, to keep this from being
    /// directly constructable.
    _placeholder: PhantomData<()>,
}

impl plugins::Plugin for Plugin {
    fn name(&self) -> &'static str {
        Self::plugin_name()
    }
}

impl PluginNew for Plugin {
    fn plugin_name() -> &'static str {
        "repos"
    }

    fn new(_project: &Project) -> Result<Self, Error> {
        Ok(Plugin { _placeholder: PhantomData })
    }
}

impl PluginTransform for Plugin {
    fn transform(&self,
                 op: Operation,
                 ctx: &plugins::Context,
                 file: &mut dc::File)
                 -> Result<(), Error> {
        // Give up immediately if we're not doing this for local output.
        if op != Operation::Output {
            return Ok(());
        }

        // Update each service to point to our locally cloned repos.
        let project = ctx.project;
        for service in &mut file.services.values_mut() {

            // Handle the main repo associated with this service.
            if let Some(git_url) = try!(service.git_url()).cloned() {
                if let Some(repo) = project.repos().find_by_git_url(&git_url) {
                    if repo.is_cloned(project) {
                        // Build an absolute path to our repo's clone directory.
                        let path = try!(repo.path(project).to_absolute());

                        // Mount the local build directory inside the
                        // container.
                        let srcdir = try!(service.source_mount_dir());
                        let mount = dc::VolumeMount::host(&path, &srcdir);
                        service.volumes.push(dc::value(mount));

                        // Update the `build` field if present.
                        if let Some(ref mut build) = service.build {
                            build.context = dc::value(dc::Context::Dir(path));
                        }
                    }
                }
            }

            // Look for library repos as well.
            for (label, mount_as) in &service.labels {
                let prefix = "io.fdy.conductor.lib.";
                if label.starts_with(prefix) {
                    let key = &label[prefix.len()..];
                    let repo = try!(project.repos()
                        .find_by_lib_key(key)
                        .ok_or_else(|| {
                            err!("no library <{}> defined in `config/libraries.yml`",
                                 key)
                        }));

                    let path = try!(repo.path(project).to_absolute());
                    let mount = dc::VolumeMount::host(&path, mount_as);
                    service.volumes.push(dc::value(mount));
                }
            }
        }

        Ok(())
    }
}
<commit_msg>Document the `repos` plugin a bit better<commit_after>//! Plugin which transforms `dc::File` to point at local clones of GitHub
//! repositories.

use docker_compose::v2 as dc;
use std::marker::PhantomData;

use ext::service::ServiceExt;
use plugins;
use plugins::{Operation, PluginNew, PluginTransform};
use project::Project;
use util::{ConductorPathExt, Error};

/// Transforms `dc::File` to point at local clones of GitHub repositories.
///
/// Note that this is only part of our repository support—this plugin
/// doesn't load repositories or check them out.  (That's the job of our
/// top-level `repos` module.)  Rather, this plugin uses information that
/// we already know about repositories in order to transform a `dc::File`
/// for local development purposes.
#[derive(Debug)]
#[allow(missing_copy_implementations)]
pub struct Plugin {
    /// Placeholder field for future hidden fields, to keep this from being
    /// directly constructable.
    _placeholder: PhantomData<()>,
}

impl plugins::Plugin for Plugin {
    fn name(&self) -> &'static str {
        Self::plugin_name()
    }
}

impl PluginNew for Plugin {
    fn plugin_name() -> &'static str {
        "repos"
    }

    fn new(_project: &Project) -> Result<Self, Error> {
        Ok(Plugin { _placeholder: PhantomData })
    }
}

impl PluginTransform for Plugin {
    fn transform(&self,
                 op: Operation,
                 ctx: &plugins::Context,
                 file: &mut dc::File)
                 -> Result<(), Error> {
        // Give up immediately if we're not doing this for local output.
        if op != Operation::Output {
            return Ok(());
        }

        // Update each service to point to our locally cloned repos.
        let project = ctx.project;
        for service in &mut file.services.values_mut() {

            // Handle the main repo associated with this service.
            if let Some(git_url) = try!(service.git_url()).cloned() {
                if let Some(repo) = project.repos().find_by_git_url(&git_url) {
                    if repo.is_cloned(project) {
                        // Build an absolute path to our repo's clone directory.
                        let path = try!(repo.path(project).to_absolute());

                        // Mount the local build directory inside the
                        // container.
                        let srcdir = try!(service.source_mount_dir());
                        let mount = dc::VolumeMount::host(&path, &srcdir);
                        service.volumes.push(dc::value(mount));

                        // Update the `build` field if present.
                        if let Some(ref mut build) = service.build {
                            build.context = dc::value(dc::Context::Dir(path));
                        }
                    }
                }
            }

            // Look for library repos as well.
            for (label, mount_as) in &service.labels {
                let prefix = "io.fdy.conductor.lib.";
                if label.starts_with(prefix) {
                    let key = &label[prefix.len()..];
                    let repo = try!(project.repos()
                        .find_by_lib_key(key)
                        .ok_or_else(|| {
                            err!("no library <{}> defined in `config/libraries.yml`",
                                 key)
                        }));

                    let path = try!(repo.path(project).to_absolute());
                    let mount = dc::VolumeMount::host(&path, mount_as);
                    service.volumes.push(dc::value(mount));
                }
            }
        }

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