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

use collections::hashmap::HashMap;
use font::SpecifiedFontStyle;
use gfx_font::FontHandleMethods;
use platform::font::FontHandle;
use platform::font_context::FontContextHandle;
use platform::font_list::FontListHandle;
use style::computed_values::{font_weight, font_style};

use servo_util::time::{ProfilerChan, profile};
use servo_util::time;

pub type FontFamilyMap = HashMap<~str, FontFamily>;

trait FontListHandleMethods {
    fn get_available_families(&self, fctx: &FontContextHandle) -> FontFamilyMap;
    fn load_variations_for_family(&self, family: &mut FontFamily);
    fn get_last_resort_font_families() -> ~[~str];
}

/// The platform-independent font list abstraction.
pub struct FontList {
    family_map: FontFamilyMap,
    handle: FontListHandle,
    prof_chan: ProfilerChan,
}

impl FontList {
    pub fn new(fctx: &FontContextHandle,
           prof_chan: ProfilerChan)
           -> FontList {
        let handle = FontListHandle::new(fctx);
        let mut list = FontList {
            handle: handle,
            family_map: HashMap::new(),
            prof_chan: prof_chan.clone(),
        };
        list.refresh(fctx);
        list
    }

    fn refresh(&mut self, _: &FontContextHandle) {
        // TODO(Issue #186): don't refresh unless something actually
        // changed.  Does OSX have a notification for this event?
        //
        // Should font families with entries be invalidated/refreshed too?
        profile(time::GfxRegenAvailableFontsCategory, self.prof_chan.clone(), || {
            self.family_map = self.handle.get_available_families();
        });
    }

    pub fn find_font_in_family<'a>(&'a mut self,
                                   family_name: &~str,
                                   style: &SpecifiedFontStyle) -> Option<&'a FontEntry> {
        // TODO(Issue #188): look up localized font family names if canonical name not found
        // look up canonical name
        if self.family_map.contains_key(family_name) {
            //FIXME call twice!(ksh8281)
            debug!("FontList: Found font family with name={:s}", family_name.to_str());
            let s: &'a mut FontFamily = self.family_map.get_mut(family_name);
            // TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'.
            // if such family exists, try to match style to a font
            let result = s.find_font_for_style(&mut self.handle, style);
            if result.is_some() {
                return result;
            }

            None
        } else {
            debug!("FontList: Couldn't find font family with name={:s}", family_name.to_str());
            None
        }
    }

    pub fn get_last_resort_font_families() -> ~[~str] {
        let last_resort = FontListHandle::get_last_resort_font_families();
        last_resort
    }
}

// Holds a specific font family, and the various
pub struct FontFamily {
    pub family_name: ~str,
    pub entries: ~[FontEntry],
}

impl FontFamily {
    pub fn new(family_name: &str) -> FontFamily {
        FontFamily {
            family_name: family_name.to_str(),
            entries: ~[],
        }
    }

    fn load_family_variations(&mut self, list: &FontListHandle) {
        if self.entries.len() > 0 {
            return
        }
        list.load_variations_for_family(self);
        assert!(self.entries.len() > 0)
    }

    pub fn find_font_for_style<'a>(&'a mut self, list: &FontListHandle, style: &SpecifiedFontStyle)
                               -> Option<&'a FontEntry> {
        self.load_family_variations(list);

        // TODO(Issue #189): optimize lookup for
        // regular/bold/italic/bolditalic with fixed offsets and a
        // static decision table for fallback between these values.

        // TODO(Issue #190): if not in the fast path above, do
        // expensive matching of weights, etc.
        for entry in self.entries.iter() {
            if (style.weight.is_bold() == entry.is_bold()) &&
               ((style.style == font_style::italic) == entry.is_italic()) {

                return Some(entry);
            }
        }

        None
    }
}

/// This struct summarizes an available font's features. In the future, this will include fiddly
/// settings such as special font table handling.
///
/// In the common case, each FontFamily will have a singleton FontEntry, or it will have the
/// standard four faces: Normal, Bold, Italic, BoldItalic.
pub struct FontEntry {
    pub face_name: ~str,
    weight: font_weight::T,
    italic: bool,
    pub handle: FontHandle,
    // TODO: array of OpenType features, etc.
}

impl FontEntry {
    pub fn new(handle: FontHandle) -> FontEntry {
        FontEntry {
            face_name: handle.face_name(),
            weight: handle.boldness(),
            italic: handle.is_italic(),
            handle: handle
        }
    }

    pub fn is_bold(&self) -> bool {
        self.weight.is_bold()
    }

    pub fn is_italic(&self) -> bool {
        self.italic
    }
}

<commit_msg>~[] to Vec in gfx/font_list.rs<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

use collections::hashmap::HashMap;
use font::SpecifiedFontStyle;
use gfx_font::FontHandleMethods;
use platform::font::FontHandle;
use platform::font_context::FontContextHandle;
use platform::font_list::FontListHandle;
use style::computed_values::{font_weight, font_style};

use servo_util::time::{ProfilerChan, profile};
use servo_util::time;

pub type FontFamilyMap = HashMap<~str, FontFamily>;

trait FontListHandleMethods {
    fn get_available_families(&self, fctx: &FontContextHandle) -> FontFamilyMap;
    fn load_variations_for_family(&self, family: &mut FontFamily);
    fn get_last_resort_font_families() -> ~[~str];
}

/// The platform-independent font list abstraction.
pub struct FontList {
    family_map: FontFamilyMap,
    handle: FontListHandle,
    prof_chan: ProfilerChan,
}

impl FontList {
    pub fn new(fctx: &FontContextHandle,
           prof_chan: ProfilerChan)
           -> FontList {
        let handle = FontListHandle::new(fctx);
        let mut list = FontList {
            handle: handle,
            family_map: HashMap::new(),
            prof_chan: prof_chan.clone(),
        };
        list.refresh(fctx);
        list
    }

    fn refresh(&mut self, _: &FontContextHandle) {
        // TODO(Issue #186): don't refresh unless something actually
        // changed.  Does OSX have a notification for this event?
        //
        // Should font families with entries be invalidated/refreshed too?
        profile(time::GfxRegenAvailableFontsCategory, self.prof_chan.clone(), || {
            self.family_map = self.handle.get_available_families();
        });
    }

    pub fn find_font_in_family<'a>(&'a mut self,
                                   family_name: &~str,
                                   style: &SpecifiedFontStyle) -> Option<&'a FontEntry> {
        // TODO(Issue #188): look up localized font family names if canonical name not found
        // look up canonical name
        if self.family_map.contains_key(family_name) {
            //FIXME call twice!(ksh8281)
            debug!("FontList: Found font family with name={:s}", family_name.to_str());
            let s: &'a mut FontFamily = self.family_map.get_mut(family_name);
            // TODO(Issue #192: handle generic font families, like 'serif' and 'sans-serif'.
            // if such family exists, try to match style to a font
            let result = s.find_font_for_style(&mut self.handle, style);
            if result.is_some() {
                return result;
            }

            None
        } else {
            debug!("FontList: Couldn't find font family with name={:s}", family_name.to_str());
            None
        }
    }

    pub fn get_last_resort_font_families() -> ~[~str] {
        let last_resort = FontListHandle::get_last_resort_font_families();
        last_resort
    }
}

// Holds a specific font family, and the various
pub struct FontFamily {
    pub family_name: ~str,
    pub entries: Vec<FontEntry>,
}

impl FontFamily {
    pub fn new(family_name: &str) -> FontFamily {
        FontFamily {
            family_name: family_name.to_str(),
            entries: Vec::new(),
        }
    }

    fn load_family_variations(&mut self, list: &FontListHandle) {
        if self.entries.len() > 0 {
            return
        }
        list.load_variations_for_family(self);
        assert!(self.entries.len() > 0)
    }

    pub fn find_font_for_style<'a>(&'a mut self, list: &FontListHandle, style: &SpecifiedFontStyle)
                               -> Option<&'a FontEntry> {
        self.load_family_variations(list);

        // TODO(Issue #189): optimize lookup for
        // regular/bold/italic/bolditalic with fixed offsets and a
        // static decision table for fallback between these values.

        // TODO(Issue #190): if not in the fast path above, do
        // expensive matching of weights, etc.
        for entry in self.entries.iter() {
            if (style.weight.is_bold() == entry.is_bold()) &&
               ((style.style == font_style::italic) == entry.is_italic()) {

                return Some(entry);
            }
        }

        None
    }
}

/// This struct summarizes an available font's features. In the future, this will include fiddly
/// settings such as special font table handling.
///
/// In the common case, each FontFamily will have a singleton FontEntry, or it will have the
/// standard four faces: Normal, Bold, Italic, BoldItalic.
pub struct FontEntry {
    pub face_name: ~str,
    weight: font_weight::T,
    italic: bool,
    pub handle: FontHandle,
    // TODO: array of OpenType features, etc.
}

impl FontEntry {
    pub fn new(handle: FontHandle) -> FontEntry {
        FontEntry {
            face_name: handle.face_name(),
            weight: handle.boldness(),
            italic: handle.is_italic(),
            handle: handle
        }
    }

    pub fn is_bold(&self) -> bool {
        self.weight.is_bold()
    }

    pub fn is_italic(&self) -> bool {
        self.italic
    }
}

<|endoftext|>


<commit_before>//! See [`patch_json_for_outdated_configs`]
use serde_json::{json, Value};

/// This function patches the json config to the new expected keys.
/// That is we try to load old known config keys here and convert them to the new ones.
/// See https://github.com/rust-lang/rust-analyzer/pull/12010
pub(super) fn patch_json_for_outdated_configs(json: &mut Value) {
    let copy = json.clone();

    macro_rules! patch {
        ($(
            $($src:ident).+ -> $($dst:ident).+ ;
        )+) => { $(
            if let Some(it) = copy.pointer(concat!($("/", stringify!($src)),+)).cloned() {
                let mut last = it;
                for segment in [$(stringify!($dst)),+].into_iter().rev() {
                    last = Value::Object(serde_json::Map::from_iter(std::iter::once((segment.to_string(), last))));
                }

                merge(json, last);
            }
        )+ };
    }

    patch! {
        assist.allowMergingIntoGlobImports -> imports.merge.glob;
        assist.exprFillDefault -> assist.expressionFillDefault;
        assist.importEnforceGranularity -> imports.granularity.enforce;
        assist.importGranularity -> imports.granularity.group;
        assist.importMergeBehavior -> imports.granularity.group;
        assist.importMergeBehaviour -> imports.granularity.group;
        assist.importGroup -> imports.group.enable;
        assist.importPrefix -> imports.prefix;
        cache.warmup -> primeCaches.enable;
        cargo.loadOutDirsFromCheck -> cargo.buildScripts.enable;
        cargo.runBuildScripts -> cargo.runBuildScripts.overrideCommand;
        cargo.runBuildScriptsCommand -> cargo.runBuildScripts.overrideCommand;
        cargo.useRustcWrapperForBuildScripts -> cargo.runBuildScripts.useRustcWrapper;
        completion.snippets -> completion.snippets.custom;
        diagnostics.enableExperimental -> diagnostics.experimental.enable;
        experimental.procAttrMacros -> procMacro.attributes.enable;
        highlighting.strings -> semanticHighlighting.strings.enable;
        highlightRelated.breakPoints -> semanticHighlighting.breakPoints.enable;
        highlightRelated.exitPoints -> semanticHighlighting.exitPoints.enable;
        highlightRelated.yieldPoints -> semanticHighlighting.yieldPoints.enable;
        highlightRelated.references -> semanticHighlighting.references.enable;
        hover.documentation -> hover.documentation.enable;
        hover.linksInHover -> hover.links.enable;
        hoverActions.linksInHover -> hover.links.enable;
        hoverActions.debug -> hoverActions.debug.enable;
        hoverActions.enable -> hoverActions.enable.enable;
        hoverActions.gotoTypeDef -> hoverActions.gotoTypeDef.enable;
        hoverActions.implementations -> hoverActions.implementations.enable;
        hoverActions.references -> hoverActions.references.enable;
        hoverActions.run -> hoverActions.run.enable;
        inlayHints.chainingHints -> inlayHints.chainingHints.enable;
        inlayHints.closureReturnTypeHints -> inlayHints.closureReturnTypeHints.enable;
        inlayHints.hideNamedConstructorHints -> inlayHints.typeHints.hideNamedConstructorHints;
        inlayHints.parameterHints -> inlayHints.parameterHints.enable;
        inlayHints.reborrowHints -> inlayHints.reborrowHints.enable;
        inlayHints.typeHints -> inlayHints.typeHints.enable;
        lruCapacity -> lru.capacity;
        runnables.cargoExtraArgs -> runnables.extraArgs ;
        runnables.overrideCargo -> runnables.command ;
        rustcSource -> rustc.source;
        rustfmt.enableRangeFormatting -> rustfmt.rangeFormatting.enable;
    }

    // callInfo_full -> signatureInfo_detail, signatureInfo_documentation_enable
    if let Some(Value::Bool(b)) = copy.pointer("/callInfo/full") {
        let sig_info = match b {
            true => json!({ "signatureInfo": {
                "documentation": {"enable": true}},
                "detail": "full"
            }),
            false => json!({ "signatureInfo": {
                "documentation": {"enable": false}},
                "detail": "parameters"
            }),
        };
        merge(json, sig_info);
    }

    // cargo_allFeatures, cargo_features -> cargo_features
    if let Some(Value::Bool(true)) = copy.pointer("/cargo/allFeatures") {
        merge(json, json!({ "cargo": { "features": "all" } }));
    }

    // checkOnSave_allFeatures, checkOnSave_features -> checkOnSave_features
    if let Some(Value::Bool(true)) = copy.pointer("/checkOnSave/allFeatures") {
        merge(json, json!({ "checkOnSave": { "features": "all" } }));
    }

    // completion_addCallArgumentSnippets completion_addCallParenthesis -> completion_callable_snippets
    let res = match (
        copy.pointer("/completion/addCallArgumentSnippets"),
        copy.pointer("/completion/addCallParenthesis"),
    ) {
        (Some(Value::Bool(true)), Some(Value::Bool(true))) => json!("fill_arguments"),
        (Some(Value::Bool(true)), _) => json!("add_parentheses"),
        (_, _) => json!(null),
    };
    merge(json, json!({ "completion": { "callable": {"snippets": res }} }));
}

fn merge(dst: &mut Value, src: Value) {
    match (dst, src) {
        (Value::Object(dst), Value::Object(src)) => {
            for (k, v) in src {
                merge(dst.entry(k).or_insert(v.clone()), v)
            }
        }
        (dst, src) => *dst = src,
    }
}
<commit_msg>Auto merge of #12209 - Veykril:config-fix, r=Veykril<commit_after>//! See [`patch_json_for_outdated_configs`]
use serde_json::{json, Value};

/// This function patches the json config to the new expected keys.
/// That is we try to load old known config keys here and convert them to the new ones.
/// See https://github.com/rust-lang/rust-analyzer/pull/12010
pub(super) fn patch_json_for_outdated_configs(json: &mut Value) {
    let copy = json.clone();

    macro_rules! patch {
        ($(
            $($src:ident).+ -> $($dst:ident).+ ;
        )+) => { $(
            match copy.pointer(concat!($("/", stringify!($src)),+)).cloned() {
                Some(Value::Object(_)) | None => (),
                Some(it) => {
                    let mut last = it;
                    for segment in [$(stringify!($dst)),+].into_iter().rev() {
                        last = Value::Object(serde_json::Map::from_iter(std::iter::once((segment.to_string(), last))));
                    }

                    merge(json, last);
                },
            }
        )+ };
    }

    patch! {
        assist.allowMergingIntoGlobImports -> imports.merge.glob;
        assist.exprFillDefault -> assist.expressionFillDefault;
        assist.importEnforceGranularity -> imports.granularity.enforce;
        assist.importGranularity -> imports.granularity.group;
        assist.importMergeBehavior -> imports.granularity.group;
        assist.importMergeBehaviour -> imports.granularity.group;
        assist.importGroup -> imports.group.enable;
        assist.importPrefix -> imports.prefix;
        cache.warmup -> primeCaches.enable;
        cargo.loadOutDirsFromCheck -> cargo.buildScripts.enable;
        cargo.runBuildScripts -> cargo.runBuildScripts.overrideCommand;
        cargo.runBuildScriptsCommand -> cargo.runBuildScripts.overrideCommand;
        cargo.useRustcWrapperForBuildScripts -> cargo.runBuildScripts.useRustcWrapper;
        diagnostics.enableExperimental -> diagnostics.experimental.enable;
        experimental.procAttrMacros -> procMacro.attributes.enable;
        highlighting.strings -> semanticHighlighting.strings.enable;
        highlightRelated.breakPoints -> semanticHighlighting.breakPoints.enable;
        highlightRelated.exitPoints -> semanticHighlighting.exitPoints.enable;
        highlightRelated.yieldPoints -> semanticHighlighting.yieldPoints.enable;
        highlightRelated.references -> semanticHighlighting.references.enable;
        hover.documentation -> hover.documentation.enable;
        hover.linksInHover -> hover.links.enable;
        hoverActions.linksInHover -> hover.links.enable;
        hoverActions.debug -> hoverActions.debug.enable;
        hoverActions.enable -> hoverActions.enable.enable;
        hoverActions.gotoTypeDef -> hoverActions.gotoTypeDef.enable;
        hoverActions.implementations -> hoverActions.implementations.enable;
        hoverActions.references -> hoverActions.references.enable;
        hoverActions.run -> hoverActions.run.enable;
        inlayHints.chainingHints -> inlayHints.chainingHints.enable;
        inlayHints.closureReturnTypeHints -> inlayHints.closureReturnTypeHints.enable;
        inlayHints.hideNamedConstructorHints -> inlayHints.typeHints.hideNamedConstructorHints;
        inlayHints.parameterHints -> inlayHints.parameterHints.enable;
        inlayHints.reborrowHints -> inlayHints.reborrowHints.enable;
        inlayHints.typeHints -> inlayHints.typeHints.enable;
        lruCapacity -> lru.capacity;
        runnables.cargoExtraArgs -> runnables.extraArgs ;
        runnables.overrideCargo -> runnables.command ;
        rustcSource -> rustc.source;
        rustfmt.enableRangeFormatting -> rustfmt.rangeFormatting.enable;
    }

    // completion.snippets -> completion.snippets.custom;
    if let Some(Value::Object(obj)) = copy.pointer("/completion/snippets").cloned() {
        if obj.len() != 1 || obj.get("custom").is_none() {
            merge(
                json,
                json! {{
                    "completion": {
                        "snippets": {
                            "custom": obj
                        },
                    },
                }},
            );
        }
    }

    // callInfo_full -> signatureInfo_detail, signatureInfo_documentation_enable
    if let Some(Value::Bool(b)) = copy.pointer("/callInfo/full") {
        let sig_info = match b {
            true => json!({ "signatureInfo": {
                "documentation": {"enable": true}},
                "detail": "full"
            }),
            false => json!({ "signatureInfo": {
                "documentation": {"enable": false}},
                "detail": "parameters"
            }),
        };
        merge(json, sig_info);
    }

    // cargo_allFeatures, cargo_features -> cargo_features
    if let Some(Value::Bool(true)) = copy.pointer("/cargo/allFeatures") {
        merge(json, json!({ "cargo": { "features": "all" } }));
    }

    // checkOnSave_allFeatures, checkOnSave_features -> checkOnSave_features
    if let Some(Value::Bool(true)) = copy.pointer("/checkOnSave/allFeatures") {
        merge(json, json!({ "checkOnSave": { "features": "all" } }));
    }

    // completion_addCallArgumentSnippets completion_addCallParenthesis -> completion_callable_snippets
    let res = match (
        copy.pointer("/completion/addCallArgumentSnippets"),
        copy.pointer("/completion/addCallParenthesis"),
    ) {
        (Some(Value::Bool(true)), Some(Value::Bool(true))) => json!("fill_arguments"),
        (Some(Value::Bool(true)), _) => json!("add_parentheses"),
        (_, _) => json!(null),
    };
    merge(json, json!({ "completion": { "callable": {"snippets": res }} }));
}

fn merge(dst: &mut Value, src: Value) {
    match (dst, src) {
        (Value::Object(dst), Value::Object(src)) => {
            for (k, v) in src {
                merge(dst.entry(k).or_insert(v.clone()), v)
            }
        }
        (dst, src) => *dst = src,
    }
}
<|endoftext|>


<commit_before>use clap::{App, Arg};

fn main() {
    // Subcommands function exactly like sub-Apps, because that's exactly what they are. Each
    // instance of a Subcommand can have its own version, author(s), Args, and even its own
    // subcommands.
    //
    // # Help and Version
    // Just like Apps, each subcommand will get its own "help" and "version" flags automatically
    // generated. Also, like Apps, you can override "-V" or "-h" safely and still get "--help" and
    // "--version" auto generated.
    //
    // NOTE: If you specify a subcommand for your App, clap will also autogenerate a "help"
    // subcommand along with "-h" and "--help" (applies to sub-subcommands as well).
    //
    // Just like arg() and args(), subcommands can be specified one at a time via subcommand() or
    // multiple ones at once with a Vec<Subcommand> provided to subcommands().
    let matches = App::new("MyApp")
        // Normal App and Arg configuration goes here...
        // In the following example assume we wanted an application which
        // supported an "add" subcommand, this "add" subcommand also took
        // one positional argument of a file to add:
        .subcommand(
            App::new("add") // The name we call argument with
                .about("Adds files to myapp") // The message displayed in "myapp -h"
                // or "myapp help"
                .license("MIT OR Apache-2.0")
                .version("0.1") // Subcommands can have independent version
                .author("Kevin K.") // And authors
                .arg(
                    Arg::new("input") // And their own arguments
                        .about("the file to add")
                        .index(1)
                        .required(true),
                ),
        )
        .get_matches();

    // You can check if a subcommand was used like normal
    if matches.is_present("add") {
        println!("'myapp add' was run.");
    }

    // You can get the independent subcommand matches (which function exactly like App matches)
    if let Some(ref matches) = matches.subcommand_matches("add") {
        // Safe to use unwrap() because of the required() option
        println!("Adding file: {}", matches.value_of("input").unwrap());
    }

    // You can also match on a subcommand's name
    match matches.subcommand_name() {
        Some("add") => println!("'myapp add' was used"),
        None => println!("No subcommand was used"),
        _ => println!("Some other subcommand was used"),
    }

    // Continued program logic goes here...
}
<commit_msg>Update examples/08_subcommands.rs<commit_after>use clap::{App, Arg};

fn main() {
    // Subcommands function exactly like sub-Apps, because that's exactly what they are. Each
    // instance of a Subcommand can have its own version, author(s), Args, and even its own
    // subcommands.
    //
    // # Help and Version
    // Just like Apps, each subcommand will get its own "help" and "version" flags automatically
    // generated. Also, like Apps, you can override "-V" or "-h" safely and still get "--help" and
    // "--version" auto generated.
    //
    // NOTE: If you specify a subcommand for your App, clap will also autogenerate a "help"
    // subcommand along with "-h" and "--help" (applies to sub-subcommands as well).
    //
    // Just like arg() and args(), subcommands can be specified one at a time via subcommand() or
    // multiple ones at once with a Vec<App> provided to subcommands().
    let matches = App::new("MyApp")
        // Normal App and Arg configuration goes here...
        // In the following example assume we wanted an application which
        // supported an "add" subcommand, this "add" subcommand also took
        // one positional argument of a file to add:
        .subcommand(
            App::new("add") // The name we call argument with
                .about("Adds files to myapp") // The message displayed in "myapp -h"
                // or "myapp help"
                .license("MIT OR Apache-2.0")
                .version("0.1") // Subcommands can have independent version
                .author("Kevin K.") // And authors
                .arg(
                    Arg::new("input") // And their own arguments
                        .about("the file to add")
                        .index(1)
                        .required(true),
                ),
        )
        .get_matches();

    // You can check if a subcommand was used like normal
    if matches.is_present("add") {
        println!("'myapp add' was run.");
    }

    // You can get the independent subcommand matches (which function exactly like App matches)
    if let Some(ref matches) = matches.subcommand_matches("add") {
        // Safe to use unwrap() because of the required() option
        println!("Adding file: {}", matches.value_of("input").unwrap());
    }

    // You can also match on a subcommand's name
    match matches.subcommand_name() {
        Some("add") => println!("'myapp add' was used"),
        None => println!("No subcommand was used"),
        _ => println!("Some other subcommand was used"),
    }

    // Continued program logic goes here...
}
<|endoftext|>


<commit_before>// http://rosettacode.org/wiki/Define_a_primitive_data_type
// Implements a custom type named CustomInt.
// This type only implements a subset of all traits within std::ops.

mod custom_int {
    use std::ops;

    #[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone)]
    pub struct CustomInt {
        value: u8,
    }

    // constructor function
    pub fn custom_int(v: u8) -> CustomInt {
        let rval = CustomInt { value: v };
        rval.in_bounds();
        rval
    }

    // custom trait to specify bounds
    trait Bounded {
        fn in_bounds(&self);
    }

    impl Bounded for CustomInt {
        fn in_bounds(&self) {
            if self.value < 1 || self.value > 10 {
                panic(self.value);
            }
            #[cold]
            #[inline(never)]
            fn panic(v: u8) -> ! {
                panic!("CustomInt is out of bounds! {} was value", v);
            }
        }
    }

    impl ops::Add for CustomInt {
        type Output = CustomInt;
        fn add(self, rhs: CustomInt) -> CustomInt {
            let rval = CustomInt { value: (self.value + rhs.value) };
            rval.in_bounds();
            rval
        }
    }

    impl ops::Sub for CustomInt {
        type Output = CustomInt;
        fn sub(self, rhs: CustomInt) -> CustomInt {
            let rval = CustomInt { value: (self.value - rhs.value) };
            rval.in_bounds();
            rval
        }
    }

    impl ops::Mul for CustomInt {
        type Output = CustomInt;
        fn mul(self, rhs: CustomInt) -> CustomInt {
            let rval = CustomInt { value: (self.value * rhs.value) };
            rval.in_bounds();
            rval
        }
    }

    impl ops::Div for CustomInt {
        type Output = CustomInt;
        fn div(self, rhs: CustomInt) -> CustomInt {
            let rval = CustomInt { value: (self.value / rhs.value) };
            rval.in_bounds();
            rval
        }
    }

    impl ops::BitAnd for CustomInt {
        type Output = CustomInt;
        fn bitand(self, rhs: CustomInt) -> CustomInt {
            let rval = CustomInt { value: (self.value & rhs.value) };
            rval.in_bounds();
            rval
        }
    }

    impl ops::BitOr for CustomInt {
        type Output = CustomInt;
        fn bitor(self, rhs: CustomInt) -> CustomInt {
            let rval = CustomInt { value: (self.value | rhs.value) };
            rval.in_bounds();
            rval
        }
    }

    impl ops::BitXor for CustomInt {
        type Output = CustomInt;
        fn bitxor(self, rhs: CustomInt) -> CustomInt {
            let rval = CustomInt { value: (self.value ^ rhs.value) };
            rval.in_bounds();
            rval
        }
    }
}

fn main() {
    use custom_int::*;
    let cint_2 = custom_int(2);
    let cint_3 = custom_int(3);
    let cint_4 = custom_int(4);
    cint_2 + cint_4; // CustomInt { value: 6 }
    cint_4 - cint_2; // CustomInt { value: 2 }
    cint_4 * cint_2; // CustomInt { value: 8 }
    cint_4 / cint_2; // CustomInt { value: 2 }
    cint_3 & cint_2; // CustomInt { value: 2 }
    cint_3 | cint_2; // CustomInt { value: 3 }
    cint_3 ^ cint_2; // CustomInt { value: 1 }
}

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

    #[test]
    fn add_test() {
        let cint_2 = custom_int(2);
        let cint_4 = custom_int(4);
        assert_eq!(custom_int(6), cint_2 + cint_4);
    }

    #[test]
    fn sub_test() {
        let cint_2 = custom_int(2);
        let cint_4 = custom_int(4);
        assert_eq!(custom_int(2), cint_4 - cint_2);
    }

    #[test]
    fn mul_test() {
        let cint_2 = custom_int(2);
        let cint_4 = custom_int(4);
        assert_eq!(custom_int(8), cint_4 * cint_2);
    }

    #[test]
    fn div_test() {
        let cint_2 = custom_int(2);
        let cint_4 = custom_int(4);
        assert_eq!(custom_int(2), cint_4 / cint_2);
    }

    #[test]
    fn and_test() {
        let cint_2 = custom_int(2);
        let cint_3 = custom_int(3);
        assert_eq!(custom_int(2), cint_3 & cint_2);
    }

    #[test]
    fn or_test() {
        let cint_2 = custom_int(2);
        let cint_3 = custom_int(3);
        assert_eq!(custom_int(3), cint_3 | cint_2);
    }

    #[test]
    fn xor_test() {
        let cint_2 = custom_int(2);
        let cint_3 = custom_int(3);
        assert_eq!(custom_int(1), cint_3 ^ cint_2);
    }
}
<commit_msg>add new changes<commit_after>// http://rosettacode.org/wiki/Define_a_primitive_data_type
// Implements a custom type named CustomInt.
// This type only implements a subset of all traits within std::ops.
use std::ops;

#[derive(Eq, PartialEq, Ord, PartialOrd, Debug, Copy, Clone)]
struct CustomInt {
    value: u8,
}

// constructor function
impl CustomInt {
    fn custom_int(v: u8) -> CustomInt {
        let rval = CustomInt { value: v };
        rval.in_bounds();
        rval
    }
}
// custom trait to specify bounds
trait Bounded {
    fn in_bounds(&self);
}

impl Bounded for CustomInt {
    fn in_bounds(&self) {
        if self.value < 1 || self.value > 10 {
            panic(self.value);
        }
        #[cold]
        #[inline(never)]
        fn panic(v: u8) -> ! {
            panic!("CustomInt is out of bounds! {} was value", v);
        }
    }
}

impl ops::Add for CustomInt {
    type Output = CustomInt;
    fn add(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value + rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Sub for CustomInt {
    type Output = CustomInt;
    fn sub(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value - rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Mul for CustomInt {
    type Output = CustomInt;
    fn mul(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value * rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::Div for CustomInt {
    type Output = CustomInt;
    fn div(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value / rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitAnd for CustomInt {
    type Output = CustomInt;
    fn bitand(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value & rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitOr for CustomInt {
    type Output = CustomInt;
    fn bitor(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value | rhs.value) };
        rval.in_bounds();
        rval
    }
}

impl ops::BitXor for CustomInt {
    type Output = CustomInt;
    fn bitxor(self, rhs: CustomInt) -> CustomInt {
        let rval = CustomInt { value: (self.value ^ rhs.value) };
        rval.in_bounds();
        rval
    }
}

fn main() {
    let cint_2: CustomInt = CustomInt::custom_int(2);
    let cint_3: CustomInt = CustomInt::custom_int(3);
    let cint_4: CustomInt = CustomInt::custom_int(4);
    cint_2 + cint_4; // CustomInt { value: 6 }
    cint_4 - cint_2; // CustomInt { value: 2 }
    cint_4 * cint_2; // CustomInt { value: 8 }
    cint_4 / cint_2; // CustomInt { value: 2 }
    cint_3 & cint_2; // CustomInt { value: 2 }
    cint_3 | cint_2; // CustomInt { value: 3 }
    cint_3 ^ cint_2; // CustomInt { value: 1 }
}

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

    #[test]
    fn add_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2);
        let cint_4: CustomInt = CustomInt::custom_int(4);
        assert_eq!(CustomInt::custom_int(6), cint_2 + cint_4);
    }

    #[test]
    fn sub_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2);
        let cint_4: CustomInt = CustomInt::custom_int(4);
        assert_eq!(CustomInt::custom_int(2), cint_4 - cint_2);
    }

    #[test]
    fn mul_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2);
        let cint_4: CustomInt = CustomInt::custom_int(4);
        assert_eq!(CustomInt::custom_int(8), cint_4 * cint_2);
    }

    #[test]
    fn div_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2);
        let cint_4: CustomInt = CustomInt::custom_int(4);
        assert_eq!(CustomInt::custom_int(2), cint_4 / cint_2);
    }

    #[test]
    fn and_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2);
        let cint_3: CustomInt = CustomInt::custom_int(3);
        assert_eq!(CustomInt::custom_int(2), cint_3 & cint_2);
    }

    #[test]
    fn or_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2);
        let cint_3: CustomInt = CustomInt::custom_int(3);
        assert_eq!(CustomInt::custom_int(3), cint_3 | cint_2);
    }

    #[test]
    fn xor_test() {
        let cint_2: CustomInt = CustomInt::custom_int(2);
        let cint_3: CustomInt = CustomInt::custom_int(3);
        assert_eq!(CustomInt::custom_int(1), cint_3 ^ cint_2);
    }

    #[test]
    #[should_panic(expected = "CustomInt is out of bounds! 11 was value")]
    fn above_out_of_bounds_test() {
        let cint_10: CustomInt = CustomInt::custom_int(10);
        let cint_1: CustomInt = CustomInt::custom_int(1);
        cint_10 + cint_1; // should panic here
    }

    #[test]
    #[should_panic(expected = "CustomInt is out of bounds! 0 was value")]
    fn below_out_of_bounds_test() {
        let cint_1: CustomInt = CustomInt::custom_int(10);
        cint_1 - cint_1; // should panic here
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016 Masaki Hara
//
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php

extern crate crypt_impl;

use std::io::{self, Write};
use crypt_impl::md5::MD5Writer;

fn main() {
    let stdin = io::stdin();
    let mut stdin = stdin.lock();
    let mut md5w = MD5Writer::new();
    match io::copy(&mut stdin, &mut md5w) {
        Ok(_) => {
            let sum = md5w.sum();
            for b in sum.iter() {
                print!("{:02x}", b);
            }
            println!("");
        }
        Err(e) => {
            writeln!(&mut io::stderr(), "Error: {}", e).unwrap();
        }
    }
}
<commit_msg>Small modification in md5sum.<commit_after>// Copyright (c) 2016 Masaki Hara
//
// This software is released under the MIT License.
// http://opensource.org/licenses/mit-license.php

extern crate crypt_impl;

use std::io::{self, Write};
use crypt_impl::md5::MD5Writer;

fn main() {
    let stdin = io::stdin();
    let mut stdin = stdin.lock();
    let mut writer = MD5Writer::new();
    match io::copy(&mut stdin, &mut writer) {
        Ok(_) => {
            let sum = writer.sum();
            for b in sum.iter() {
                print!("{:02x}", b);
            }
            println!("");
        }
        Err(e) => {
            writeln!(&mut io::stderr(), "Error: {}", e).unwrap();
        }
    }
}
<|endoftext|>


<commit_before>//! Tests for the registry

use std::collections::BTreeMap;
use super::*;
use rustc_serialize::{Decodable, Decoder};
use rustc_serialize::json;
use rustc_serialize::json::{Json, ToJson};

#[derive(Debug, Clone, Eq, PartialEq)]
struct Point {
    x: i32,
    y: i32
}

impl ToJson for Point {
    fn to_json(&self) -> Json {
        let mut map = BTreeMap::new();
        map.insert("x".to_string(), Json::I64(self.x as i64));
        map.insert("y".to_string(), Json::I64(self.y as i64));
        Json::Object(map)
    }
}

const i32_SIZE: usize = 32usize / 8usize;

impl Decodable for Point {
    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
        let mut x = 0;
        let mut y = 0;

        x = try!(d.read_struct_field("x", 1, |d| d.read_i32()));
        y = try!(d.read_struct_field("y", 1, |d| d.read_i32()));

        Ok(Point { x: x, y: y })
    }
}

#[test]
fn registry_tests() {
    let num = 1i32;
    let double = -392f64;
    let string = "Hello world".to_string();
    let numbers = vec![1, 2, 3, 4, 5];
    let point = Point { x: -11, y: 12 };

    set(String::from("test_num"), num);
    set(String::from("test_double"), double);
    set(String::from("test_string"), string.clone());
    set(String::from("test_numbers"), numbers.clone());
    set(String::from("test_point"), point.clone());

    assert!(contains_key(&String::from("test_num")));
    assert!(contains_key(&String::from("test_double")));
    assert!(contains_key(&String::from("test_string")));
    assert!(contains_key(&String::from("test_numbers")));
    assert!(contains_key(&String::from("test_point")));

    assert_eq!(get::<_, i32>(&String::from("test_num")).unwrap(), num);
    assert_eq!(get::<_, f64>(&String::from("test_double")).unwrap(), double);
    assert_eq!(get::<_, String>(&String::from("test_string")).unwrap(), string);
    assert_eq!(get::<_, Vec<i32>>(&String::from("test_numbers")).unwrap(),
               numbers);
    assert_eq!(get::<_, Point>(&String::from("test_point")).unwrap(), point);

}
<commit_msg>Fix tests and add 5-threads-reading test<commit_after>//! Tests for the registry

use std::collections::BTreeMap;
use std::sync::mpsc;
use std::thread;

use super::*;

use rustc_serialize::{Decodable, Decoder};
use rustc_serialize::json;
use rustc_serialize::json::{Json, ToJson};

#[derive(Debug, Clone, Eq, PartialEq)]
struct Point {
    x: i32,
    y: i32
}

impl ToJson for Point {
    fn to_json(&self) -> Json {
        let mut map = BTreeMap::new();
        map.insert("x".to_string(), Json::I64(self.x as i64));
        map.insert("y".to_string(), Json::I64(self.y as i64));
        Json::Object(map)
    }
}

impl Decodable for Point {
    fn decode<D: Decoder>(d: &mut D) -> Result<Self, D::Error> {
        let mut x = 0;
        let mut y = 0;

        x = try!(d.read_struct_field("x", 1, |d| d.read_i32()));
        y = try!(d.read_struct_field("y", 1, |d| d.read_i32()));

        Ok(Point { x: x, y: y })
    }
}

#[test]
fn registry_tests() {
    let num = 1i32;
    let double = -392f64;
    let string = "Hello world".to_string();
    let numbers = vec![1, 2, 3, 4, 5];
    let point = Point { x: -11, y: 12 };

    set(String::from("test_num"), num);
    set(String::from("test_double"), double);
    set(String::from("test_string"), string.clone());
    set(String::from("test_numbers"), numbers.clone());
    set(String::from("test_point"), point.clone());

    assert!(contains_key(&String::from("test_num")));
    assert!(contains_key(&String::from("test_double")));
    assert!(contains_key(&String::from("test_string")));
    assert!(contains_key(&String::from("test_numbers")));
    assert!(contains_key(&String::from("test_point")));

    assert_eq!(get::<_, i32>(&String::from("test_num")).unwrap().1, num);
    assert_eq!(get::<_, f64>(&String::from("test_double")).unwrap().1, double);
    assert_eq!(get::<_, String>(&String::from("test_string")).unwrap().1, string);
    assert_eq!(get::<_, Vec<i32>>(&String::from("test_numbers")).unwrap().1,
               numbers);
    assert_eq!(get::<_, Point>(&String::from("test_point")).unwrap().1, point);

    let (tx, rx) = mpsc::channel();

    let tx1 = tx.clone();
    thread::spawn(move || {
        read_thread(String::from("test_num"), num, tx1);
    });
    let tx2 = tx.clone();
    thread::spawn(move || {
        read_thread(String::from("test_double"), double, tx2);
    });
    let tx3 = tx.clone();
    thread::spawn(move || {
        read_thread(String::from("test_string"), string, tx3);
    });
    let tx4 = tx.clone();
    thread::spawn(move || {
        read_thread(String::from("test_numbers"), numbers, tx4);
    });
    let tx5 = tx.clone();
    thread::spawn(move || {
        read_thread(String::from("test_point"), point, tx5);
    });

    let mut result = true;

    for i in 0..5 {
        result = result && rx.recv().unwrap();
    }
    assert!(result);
}

fn read_thread<T>(name: String, in_val: T, sender: mpsc::Sender<bool>)
where T: ::std::fmt::Debug + Decodable + PartialEq {
    for _ in 1 .. 100 {
        if let Ok(acc_val) = get::<_, T>(&name) {
            let (acc, val) = acc_val;
            assert_eq!(acc, RegistryAccess::Public);
            assert_eq!(val, in_val);
        }
        else {
            sender.send(false).unwrap();
        }
    }
    sender.send(true).unwrap();
}
<|endoftext|>


<commit_before>use std::collections::HashSet;
use std::io::Cursor;
use std::ops::Deref;
use std::rc::Rc;

use digest::digest_reader;
use serde_json;
use sha2::Sha256;
use url::Url;
use url_serde;

use resman::{AudioBuffer, ResMan};
use super::routegraph::RouteGraph;
use super::adjlist::AdjList;

#[derive(Debug)]
pub enum Error {
    /// No effect matches the metadata requested.
    NoMatchingEffect(EffectId),
}

/// Alias for a `Result` with our error type.
pub type ResultE<T> = Result<T, Error>;

/// Serializable info needed to look up an effect.
#[derive(Clone, Debug)]
#[derive(Serialize, Deserialize)]
pub struct EffectId {
    /// Canonical name of the effect
    name: String,
    /// Hash of the effect's definition file, or None if the effect is primitive
    sha256: Option<[u8; 32]>,
    // TODO: consider a smallset.
    // TODO: use #[serde(with = "url_serde")]
    /// List of URLs where the Effect can be obtained
    urls: HashSet<url_serde::Serde<Url>>,
}

/// All information that will be loaded from disk/network to describe how to
/// synthesize the Effect.
#[derive(Debug)]
#[derive(Serialize, Deserialize)]
pub struct EffectDesc {
    meta: EffectMeta,
    adjlist: AdjList,
}

/// Validated version of `EffectDesc`. Guaranteed to be synthesizable.
#[derive(Debug)]
pub struct Effect {
    id: EffectId,
    meta: EffectMeta,
    // TODO: Effects are immutable, so we can make this an AdjList and store
    // the connectivity information separately.
    // option, because effect MAY be primitive.
    data: EffectData,
}

#[derive(Clone, Debug)]
#[derive(Serialize, Deserialize)]
pub struct EffectMeta {
    /// Canonical name of the effect
    name: String,
    /// List of URLs where the Effect can be obtained
    urls: HashSet<url_serde::Serde<Url>>,
    inputs: Vec<EffectInput>,
    outputs: Vec<EffectOutput>,
}

#[derive(Clone, Debug)]
#[derive(Serialize, Deserialize)]
pub struct EffectIO {
    name: String,
    channel: u8,
}
pub type EffectInput = EffectIO;
pub type EffectOutput = EffectIO;

/// Implementation details of an Effect.
/// Either its route graph, a primitive effect, etc.
#[derive(Debug)]
pub enum EffectData {
    RouteGraph(RouteGraph),
    Primitive(PrimitiveEffect),
    Buffer(AudioBuffer),
}

/// Effects that cannot be decomposed; they have no implementation details and
/// must be implemented directly by the renderer.
#[derive(Debug, Copy, Clone)]
pub enum PrimitiveEffect {
    /// Primitive Delay effect
    Delay,
    /// Primitive Constant effect.
    /// Also serves as a unit step;
    /// Returns the float value for t >= 0, else 0.
    F32Constant,
    /// Primitive effect to multiply TWO input streams sample-wise.
    Multiply,
    /// Primitive effect to calculate A/B.
    /// Note: because not all floating point numbers have inverses,
    /// A * (1/B) != A/B. Hence, we need division (not inversion) for proper
    /// precision.
    Divide,
    /// Primitive effect to calculate A%B (true modulo; not remainder.
    /// Result, y,  is always positive: y is bounded by [0, B).
    Modulo,
    /// Primitive effect to return the sample-wise minimum of two input streams.
    /// Max(A, B) can be implemented as -Min(-A, -B).
    /// The choice to define Min instead of Max was mostly arbitrary,
    /// and chosen because Min is more common in linear programming to avoid dealing
    /// with Inf.
    Minimum,
}

impl Effect {
    pub fn are_slots_connected(&self, from_slot: u32, to_slot: u32) -> bool {
        match self.data {
            EffectData::RouteGraph(ref g) => g.are_slots_connected(from_slot, to_slot),
            // For primitive effects, we assume ALL slots are connected.
            _ => true,
        }
    }
    pub fn id(&self) -> &EffectId {
        &self.id
    }
    pub fn meta(&self) -> &EffectMeta {
        &self.meta
    }
    /// Given the effect's information, and an interface by which to load
    /// resources, return an actual Effect.
    pub fn from_id(id: EffectId, resman: &ResMan) -> ResultE<Rc<Self>> {
        // For primitive effects, don't attempt to locate their descriptions (they don't exist)
        let prim_effect = id.get_primitive_url().and_then(|url| match url.path() {
            "/F32Constant" => Some(PrimitiveEffect::F32Constant),
            "/Delay"       => Some(PrimitiveEffect::Delay),
            "/Multiply"    => Some(PrimitiveEffect::Multiply),
            "/Divide"      => Some(PrimitiveEffect::Divide),
            "/Modulo"      => Some(PrimitiveEffect::Modulo),
            "/Minimum"     => Some(PrimitiveEffect::Minimum),
            _ => {
                warn!("Unrecognized primitive effect: {} (full url: {})", url.path(), url);
                None
            }
        });
        if let Some(prim_effect) = prim_effect {
            if id.sha256 == None {
                let me = Self {
                    meta: EffectMeta {
                        name: id.name.clone(),
                        urls: id.urls.clone(),
                        // Primitive effects have undocumented I/O;
                        inputs: Default::default(),
                        outputs: Default::default(),
                    },
                    // sha256 was already verified; no need to update it
                    id: id,
                    data: EffectData::Primitive(prim_effect),
                };
                return Ok(Rc::new(me));
            } else {
                warn!("Attempted to load a primitive Effect, but cannot because of mismatched sha256");
            }
        }

        // Locate descriptions for non-primitive effects
        for (path, reader) in resman.find_effect(&id) {
            // Try to deserialize to an effect description
            let desc: Result<EffectDesc, serde_json::Error> = serde_json::from_reader(reader);
            match desc {
                Ok(desc) => {
                    if desc.id().name() == id.name() {
                        // TODO: since we've matched the effect, we only need to recalculate
                        // the id if the original search had missing hashes.
                        let id = desc.id();
                        match RouteGraph::from_adjlist(desc.adjlist, resman) {
                            Ok(graph) => {
                                let me = Self {
                                    id,
                                    meta: desc.meta,
                                    data: EffectData::RouteGraph(graph),
                                };
                                // TODO: implement some form of caching
                                return Ok(Rc::new(me));
                            },
                            Err(error) => warn!("RouteGraph::from_adjlist failed: {:?}", error)
                        }
                    } else {
                        trace!("[{:?}] Effect names differ: wanted {:?} got {:?}", path, id.name(), desc.id().name());
                    }
                },
                Err(error) => {
                    // Try parsing the file as an audio stream.
                    if let Ok(buffer) = AudioBuffer::from_path(path.clone()) {
                        let me = Self {
                            meta: EffectMeta {
                                name: id.name.clone(),
                                urls: id.urls.clone(),
                                // TODO: should be able to extract the number of outputs from the
                                // audio buffer
                                inputs: Default::default(),
                                outputs: Default::default(),
                            },
                            // TODO: refactor to avoid this clone.
                            // TODO: sha256 may need to be updated.
                            id: id.clone(),
                            data: EffectData::Buffer(buffer),
                        };
                        // TODO: implement some form of caching
                        return Ok(Rc::new(me));
                    } else {
                        warn!("[{:?}] Unable to deserialize EffectDesc: {:?}", path, error)
                    }
                }
            }
        }
        // No matching effects
        Err(Error::NoMatchingEffect(id))
    }
    pub fn data(&self) -> &EffectData {
        &self.data
    }
}

impl EffectId {
    pub fn new<U>(name: String, sha256: Option<[u8; 32]>, urls: U) -> Self
        where U: IntoIterator<Item=Url>
    {
        Self {
            name,
            sha256,
            urls: urls.into_iter().map(url_serde::Serde).collect(),
        }
    }
    pub fn name(&self) -> &str {
        &self.name
    }
    pub fn sha256(&self) -> &Option<[u8; 32]> {
        &self.sha256
    }
    /// Returns true if the effect cannot be decomposed.
    /// This is determined by the effect providing a SINGLE url, with the primitive:// Schema
    pub fn is_primitive(&self) -> bool {
        self.urls.len() == 1 && self.urls.iter().all(|url| {
            url.scheme() == "primitive"
        })
    }
    pub fn get_primitive_url(&self) -> Option<&Url> {
        if self.is_primitive() {
            self.urls.iter().next().map(|url| url.deref())
        } else {
            None
        }
    }
}

impl EffectDesc {
    pub fn new(meta: EffectMeta, adjlist: AdjList) -> Self {
        Self{ meta, adjlist }
    }
    pub fn meta(&self) -> &EffectMeta {
        &self.meta
    }
    pub fn id(&self) -> EffectId {
        // TODO: calculate sha using a smaller buffer
        let as_vec = serde_json::to_vec(self).unwrap();
        let result = digest_reader::<Sha256>(&mut Cursor::new(as_vec)).unwrap();
        let mut hash: [u8; 32] = Default::default();
        hash.copy_from_slice(result.as_slice());
        EffectId {
            name: self.meta.name.clone(),
            sha256: Some(hash),
            urls: self.meta.urls.clone(),
        }
    }
}

impl EffectMeta {
    pub fn new<U>(name: String, urls: U, inputs: Vec<EffectInput>, outputs: Vec<EffectOutput>) -> Self
        where U: IntoIterator<Item=Url>
    {
        Self {
            name,
            urls: urls.into_iter().map(url_serde::Serde).collect(),
            inputs,
            outputs,
        }
    }
    pub fn name(&self) -> &str {
        self.name.as_str()
    }
    pub fn inputs(&self) -> &Vec<EffectInput> {
        &self.inputs
    }
    pub fn outputs(&self) -> &Vec<EffectOutput> {
        &self.outputs
    }
    pub fn inputs_by_name<'a>(&'a self, name: &'a str) -> impl Iterator<Item=&EffectInput> + 'a {
        self.inputs.iter().filter(move |item| item.name() == name)
    }
    pub fn outputs_by_name<'a>(&'a self, name: &'a str) -> impl Iterator<Item=&EffectOutput> + 'a {
        self.outputs.iter().filter(move |item| item.name() == name)
    }
}

impl EffectIO {
    pub fn new(name: String, channel: u8) -> Self {
        Self{ name, channel }
    }
    pub fn name(&self) -> &str {
        &self.name
    }
    pub fn channel(&self) -> u8 {
        self.channel
    }
    pub fn is_source(&self) -> bool {
        self.name == "source"
    }
    pub fn is_result(&self) -> bool {
        self.name == "result"
    }
}

impl PartialEq for EffectMeta {
    // Equality implemented in a way where we can easily check things like
    //   "Is this the same primitive Delay effect this renderer knows how to implement?"
    fn eq(&self, other: &EffectMeta) -> bool {
        self.name == other.name &&
            self.urls == other.urls
    }
}
impl Eq for EffectMeta {}

impl PartialEq for Effect {
    fn eq(&self, other: &Effect) -> bool {
        self.meta == other.meta
    }
}
impl Eq for Effect {}

<commit_msg>Expose adjlist field of EffectDesc<commit_after>use std::collections::HashSet;
use std::io::Cursor;
use std::ops::Deref;
use std::rc::Rc;

use digest::digest_reader;
use serde_json;
use sha2::Sha256;
use url::Url;
use url_serde;

use resman::{AudioBuffer, ResMan};
use super::routegraph::RouteGraph;
use super::adjlist::AdjList;

#[derive(Debug)]
pub enum Error {
    /// No effect matches the metadata requested.
    NoMatchingEffect(EffectId),
}

/// Alias for a `Result` with our error type.
pub type ResultE<T> = Result<T, Error>;

/// Serializable info needed to look up an effect.
#[derive(Clone, Debug)]
#[derive(Serialize, Deserialize)]
pub struct EffectId {
    /// Canonical name of the effect
    name: String,
    /// Hash of the effect's definition file, or None if the effect is primitive
    sha256: Option<[u8; 32]>,
    // TODO: consider a smallset.
    // TODO: use #[serde(with = "url_serde")]
    /// List of URLs where the Effect can be obtained
    urls: HashSet<url_serde::Serde<Url>>,
}

/// All information that will be loaded from disk/network to describe how to
/// synthesize the Effect.
#[derive(Debug)]
#[derive(Serialize, Deserialize)]
pub struct EffectDesc {
    meta: EffectMeta,
    adjlist: AdjList,
}

/// Validated version of `EffectDesc`. Guaranteed to be synthesizable.
#[derive(Debug)]
pub struct Effect {
    id: EffectId,
    meta: EffectMeta,
    // TODO: Effects are immutable, so we can make this an AdjList and store
    // the connectivity information separately.
    // option, because effect MAY be primitive.
    data: EffectData,
}

#[derive(Clone, Debug)]
#[derive(Serialize, Deserialize)]
pub struct EffectMeta {
    /// Canonical name of the effect
    name: String,
    /// List of URLs where the Effect can be obtained
    urls: HashSet<url_serde::Serde<Url>>,
    inputs: Vec<EffectInput>,
    outputs: Vec<EffectOutput>,
}

#[derive(Clone, Debug)]
#[derive(Serialize, Deserialize)]
pub struct EffectIO {
    name: String,
    channel: u8,
}
pub type EffectInput = EffectIO;
pub type EffectOutput = EffectIO;

/// Implementation details of an Effect.
/// Either its route graph, a primitive effect, etc.
#[derive(Debug)]
pub enum EffectData {
    RouteGraph(RouteGraph),
    Primitive(PrimitiveEffect),
    Buffer(AudioBuffer),
}

/// Effects that cannot be decomposed; they have no implementation details and
/// must be implemented directly by the renderer.
#[derive(Debug, Copy, Clone)]
pub enum PrimitiveEffect {
    /// Primitive Delay effect
    Delay,
    /// Primitive Constant effect.
    /// Also serves as a unit step;
    /// Returns the float value for t >= 0, else 0.
    F32Constant,
    /// Primitive effect to multiply TWO input streams sample-wise.
    Multiply,
    /// Primitive effect to calculate A/B.
    /// Note: because not all floating point numbers have inverses,
    /// A * (1/B) != A/B. Hence, we need division (not inversion) for proper
    /// precision.
    Divide,
    /// Primitive effect to calculate A%B (true modulo; not remainder.
    /// Result, y,  is always positive: y is bounded by [0, B).
    Modulo,
    /// Primitive effect to return the sample-wise minimum of two input streams.
    /// Max(A, B) can be implemented as -Min(-A, -B).
    /// The choice to define Min instead of Max was mostly arbitrary,
    /// and chosen because Min is more common in linear programming to avoid dealing
    /// with Inf.
    Minimum,
}

impl Effect {
    pub fn are_slots_connected(&self, from_slot: u32, to_slot: u32) -> bool {
        match self.data {
            EffectData::RouteGraph(ref g) => g.are_slots_connected(from_slot, to_slot),
            // For primitive effects, we assume ALL slots are connected.
            _ => true,
        }
    }
    pub fn id(&self) -> &EffectId {
        &self.id
    }
    pub fn meta(&self) -> &EffectMeta {
        &self.meta
    }
    /// Given the effect's information, and an interface by which to load
    /// resources, return an actual Effect.
    pub fn from_id(id: EffectId, resman: &ResMan) -> ResultE<Rc<Self>> {
        // For primitive effects, don't attempt to locate their descriptions (they don't exist)
        let prim_effect = id.get_primitive_url().and_then(|url| match url.path() {
            "/F32Constant" => Some(PrimitiveEffect::F32Constant),
            "/Delay"       => Some(PrimitiveEffect::Delay),
            "/Multiply"    => Some(PrimitiveEffect::Multiply),
            "/Divide"      => Some(PrimitiveEffect::Divide),
            "/Modulo"      => Some(PrimitiveEffect::Modulo),
            "/Minimum"     => Some(PrimitiveEffect::Minimum),
            _ => {
                warn!("Unrecognized primitive effect: {} (full url: {})", url.path(), url);
                None
            }
        });
        if let Some(prim_effect) = prim_effect {
            if id.sha256 == None {
                let me = Self {
                    meta: EffectMeta {
                        name: id.name.clone(),
                        urls: id.urls.clone(),
                        // Primitive effects have undocumented I/O;
                        inputs: Default::default(),
                        outputs: Default::default(),
                    },
                    // sha256 was already verified; no need to update it
                    id: id,
                    data: EffectData::Primitive(prim_effect),
                };
                return Ok(Rc::new(me));
            } else {
                warn!("Attempted to load a primitive Effect, but cannot because of mismatched sha256");
            }
        }

        // Locate descriptions for non-primitive effects
        for (path, reader) in resman.find_effect(&id) {
            // Try to deserialize to an effect description
            let desc: Result<EffectDesc, serde_json::Error> = serde_json::from_reader(reader);
            match desc {
                Ok(desc) => {
                    if desc.id().name() == id.name() {
                        // TODO: since we've matched the effect, we only need to recalculate
                        // the id if the original search had missing hashes.
                        let id = desc.id();
                        match RouteGraph::from_adjlist(desc.adjlist, resman) {
                            Ok(graph) => {
                                let me = Self {
                                    id,
                                    meta: desc.meta,
                                    data: EffectData::RouteGraph(graph),
                                };
                                // TODO: implement some form of caching
                                return Ok(Rc::new(me));
                            },
                            Err(error) => warn!("RouteGraph::from_adjlist failed: {:?}", error)
                        }
                    } else {
                        trace!("[{:?}] Effect names differ: wanted {:?} got {:?}", path, id.name(), desc.id().name());
                    }
                },
                Err(error) => {
                    // Try parsing the file as an audio stream.
                    if let Ok(buffer) = AudioBuffer::from_path(path.clone()) {
                        let me = Self {
                            meta: EffectMeta {
                                name: id.name.clone(),
                                urls: id.urls.clone(),
                                // TODO: should be able to extract the number of outputs from the
                                // audio buffer
                                inputs: Default::default(),
                                outputs: Default::default(),
                            },
                            // TODO: refactor to avoid this clone.
                            // TODO: sha256 may need to be updated.
                            id: id.clone(),
                            data: EffectData::Buffer(buffer),
                        };
                        // TODO: implement some form of caching
                        return Ok(Rc::new(me));
                    } else {
                        warn!("[{:?}] Unable to deserialize EffectDesc: {:?}", path, error)
                    }
                }
            }
        }
        // No matching effects
        Err(Error::NoMatchingEffect(id))
    }
    pub fn data(&self) -> &EffectData {
        &self.data
    }
}

impl EffectId {
    pub fn new<U>(name: String, sha256: Option<[u8; 32]>, urls: U) -> Self
        where U: IntoIterator<Item=Url>
    {
        Self {
            name,
            sha256,
            urls: urls.into_iter().map(url_serde::Serde).collect(),
        }
    }
    pub fn name(&self) -> &str {
        &self.name
    }
    pub fn sha256(&self) -> &Option<[u8; 32]> {
        &self.sha256
    }
    /// Returns true if the effect cannot be decomposed.
    /// This is determined by the effect providing a SINGLE url, with the primitive:// Schema
    pub fn is_primitive(&self) -> bool {
        self.urls.len() == 1 && self.urls.iter().all(|url| {
            url.scheme() == "primitive"
        })
    }
    pub fn get_primitive_url(&self) -> Option<&Url> {
        if self.is_primitive() {
            self.urls.iter().next().map(|url| url.deref())
        } else {
            None
        }
    }
}

impl EffectDesc {
    pub fn new(meta: EffectMeta, adjlist: AdjList) -> Self {
        Self{ meta, adjlist }
    }
    pub fn meta(&self) -> &EffectMeta {
        &self.meta
    }
    pub fn id(&self) -> EffectId {
        // TODO: calculate sha using a smaller buffer
        let as_vec = serde_json::to_vec(self).unwrap();
        let result = digest_reader::<Sha256>(&mut Cursor::new(as_vec)).unwrap();
        let mut hash: [u8; 32] = Default::default();
        hash.copy_from_slice(result.as_slice());
        EffectId {
            name: self.meta.name.clone(),
            sha256: Some(hash),
            urls: self.meta.urls.clone(),
        }
    }
    pub fn adjlist(&self) -> &AdjList {
        &self.adjlist
    }
}

impl EffectMeta {
    pub fn new<U>(name: String, urls: U, inputs: Vec<EffectInput>, outputs: Vec<EffectOutput>) -> Self
        where U: IntoIterator<Item=Url>
    {
        Self {
            name,
            urls: urls.into_iter().map(url_serde::Serde).collect(),
            inputs,
            outputs,
        }
    }
    pub fn name(&self) -> &str {
        self.name.as_str()
    }
    pub fn inputs(&self) -> &Vec<EffectInput> {
        &self.inputs
    }
    pub fn outputs(&self) -> &Vec<EffectOutput> {
        &self.outputs
    }
    pub fn inputs_by_name<'a>(&'a self, name: &'a str) -> impl Iterator<Item=&EffectInput> + 'a {
        self.inputs.iter().filter(move |item| item.name() == name)
    }
    pub fn outputs_by_name<'a>(&'a self, name: &'a str) -> impl Iterator<Item=&EffectOutput> + 'a {
        self.outputs.iter().filter(move |item| item.name() == name)
    }
}

impl EffectIO {
    pub fn new(name: String, channel: u8) -> Self {
        Self{ name, channel }
    }
    pub fn name(&self) -> &str {
        &self.name
    }
    pub fn channel(&self) -> u8 {
        self.channel
    }
    pub fn is_source(&self) -> bool {
        self.name == "source"
    }
    pub fn is_result(&self) -> bool {
        self.name == "result"
    }
}

impl PartialEq for EffectMeta {
    // Equality implemented in a way where we can easily check things like
    //   "Is this the same primitive Delay effect this renderer knows how to implement?"
    fn eq(&self, other: &EffectMeta) -> bool {
        self.name == other.name &&
            self.urls == other.urls
    }
}
impl Eq for EffectMeta {}

impl PartialEq for Effect {
    fn eq(&self, other: &Effect) -> bool {
        self.meta == other.meta
    }
}
impl Eq for Effect {}

<|endoftext|>


<commit_before>use std::libc::{
    c_char,
    c_double,
    c_int,
    c_uint,
    c_ulong,
    c_void,
    dev_t,
    gid_t,
    mode_t,
    off_t,
    pid_t,
    size_t,
    stat,
    time_t,
    uid_t,
};
use fuse::*;
use statvfs::Struct_statvfs;

mod fuse;
mod statvfs;

/// Information to be returned from open
#[deriving(Zero)]
pub struct OpenReply {
    direct_io:bool,
    keep_cache:bool,
    fh: u64
}

pub struct AttrReply {
    attr: stat,
    attr_timeout: c_double
}

pub struct EntryReply {
    ino: fuse_ino_t,
    generation: c_ulong,
    attr: stat,
    attr_timeout: c_double,
    entry_timeout: c_double
}

pub enum AttrToSet {
    Mode(mode_t),
    Uid(uid_t),
    Gid(gid_t),
    Size(size_t),
    Atime(time_t),
    Mtime(time_t),

    // TODO: confirm assumption about what these mean
    Atime_now,
    Mtime_now,
}

pub enum ReadReply {
    // TODO: support iov and fuse_bufvec type replies for more efficient (?)
    // types of implementation
    DataBuffer(~[u8])
}

type ErrnoResult<T> = Result<T, c_int>;

/** Struct full of optional functions to implement fuse operations
 *
 * This really should be a trait.  But we can't know at run time which default
 * methods of a trait were overridden, which means we don't know which entries
 * in the Struct_fuse_lowlevel_ops to null out.  FUSE has default behavior for
 * some ops that can't just be invoked from a callback--the only way to get it
 * is to pass NULL for the callback pointers.  So here it is--a struct full of
 * optional closures instead. Argh.
 */
#[deriving(Zero)]
pub struct FuseLowLevelOps {
    init: Option<~fn()>,
    destroy: Option<~fn()>,
    lookup: Option<~fn(parent: fuse::fuse_ino_t, name: &str)
                       -> ErrnoResult<fuse::Struct_fuse_entry_param>>,
    forget: Option<~fn(ino:fuse::fuse_ino_t, nlookup:c_ulong)>,
    getattr: Option<~fn(ino: fuse::fuse_ino_t, flags: c_int)
                        -> ErrnoResult<AttrReply>>,
    setattr: Option<~fn(ino: fuse_ino_t, attrs_to_set:&[AttrToSet],
                        fh:Option<u64>) -> ErrnoResult<AttrReply>>,
    readlink:Option<~fn(fuse_ino_t) -> ErrnoResult<~str>>,
    mknod: Option<~fn(parent: fuse_ino_t, name: &str, mode: mode_t,
                      rdev: dev_t) -> ErrnoResult<EntryReply>>,
    mkdir: Option<~fn(parent: fuse_ino_t, name: &str, mode: mode_t)
        -> ErrnoResult<EntryReply>>,
    // TODO: Using the unit type with result seems kind of goofy, but
    // is done for consistency with the others.  Is this right?
    unlink: Option<~fn(parent: fuse_ino_t, name: &str)
        -> ErrnoResult<()>>,
    rmdir: Option<~fn(parent: fuse_ino_t, name: &str)
        -> ErrnoResult<()>>,
    symlink: Option<~fn(link:&str, parent: fuse_ino_t, name: &str)
        -> ErrnoResult<EntryReply>>,
    rename: Option<~fn(parent: fuse_ino_t, name: &str,
                       newparent: fuse_ino_t, newname: &str)
        -> ErrnoResult<()>>,
    link: Option<~fn(ino: fuse_ino_t, newparent: fuse_ino_t, newname: &str)
        -> ErrnoResult<EntryReply>>,
    open: Option<~fn(ino: fuse_ino_t, flags: c_int)
        -> ErrnoResult<OpenReply>>,
    read: Option<~fn(ino: fuse::fuse_ino_t, size: size_t, off: off_t, fh: u64)
                     -> ErrnoResult<ReadReply>>,
    // TODO: is writepage a bool, or an actual number that needs to be
    // preserved?
    write: Option<~fn(ino: fuse_ino_t, buf:&[u8], off: off_t, fh: u64,
                      writepage: bool) -> ErrnoResult<size_t>>,
    flush: Option<~fn(ino: fuse_ino_t, lock_owner: u64, fh: u64)
        -> ErrnoResult<()>>,
    release: Option<~fn(ino: fuse_ino_t, flags: c_int, fh: u64)
        -> ErrnoResult<()>>,
    fsync: Option<~fn(ino: fuse_ino_t, datasync: bool, fh: u64)
        -> ErrnoResult<()>>,
    opendir: Option<~fn(ino: fuse_ino_t) -> ErrnoResult<OpenReply>>,
    // TODO: Using a ReadReply would require the impl to do unsafe operations
    // to use fuse_add_direntry.  So even the thin interface needs something
    // else here.
    readdir: Option<~fn(ino: fuse_ino_t, size: size_t, off: off_t, fh: u64)
        -> ErrnoResult<ReadReply>>,
    releasedir: Option<~fn(ino: fuse_ino_t, fh: u64) -> ErrnoResult<()>>,
    fsyncdir: Option<~fn(ino: fuse_ino_t, datasync: bool, fh: u64)
        -> ErrnoResult<()>>,
    statfs: Option<~fn(ino: fuse_ino_t) -> ErrnoResult<Struct_statvfs>>,
    setxattr: Option<~fn(ino: fuse_ino_t, name: &str, value: &[u8], flags: int)
        -> ErrnoResult<()>>,
    // TODO: examine this--ReadReply may not be appropraite here
    getxattr: Option<~fn(ino: fuse_ino_t, name: &str, size: size_t)
        -> ErrnoResult<ReadReply>>,
    // Called on getxattr with size of zero (meaning a query of total size)
    getxattr_size: Option<~fn(ino: fuse_ino_t, name: &str)
        -> ErrnoResult<size_t>>,
    // TODO: examine this--ReadReply may not be appropraite here
    listxattr: Option<~fn(ino: fuse_ino_t, name: &str, size: size_t)
        -> ErrnoResult<ReadReply>>,
    // Called on listxattr with size of zero (meaning a query of total size)
    listxattr_size: Option<~fn(ino: fuse_ino_t, name: &str)
        -> ErrnoResult<size_t>>,
    removexattr: Option<~fn(ino: fuse_ino_t, name: &str) -> ErrnoResult<()>>,
    access: Option<~fn(ino: fuse_ino_t, mask: c_int) -> ErrnoResult<()>>,
    create: Option<~fn(ino: fuse_ino_t, parent: fuse_ino_t, name: &str,
                       mode: mode_t, flags: c_int) -> ErrnoResult<OpenReply>>,

    // TODO: The following, which didn't even exist in earlier versions of FUSE,
    // can be considered nice-to-have (to an even greater extent than the whole
    // project can at this point):
    //
    // getlk
    // setlk
    // bmap
    // ioctl
    // poll
    // write_buf
    // retrieve_reply
    // forget_multi
    // flock
    // fallocate
}
<commit_msg>FuseLowLevelOps is a trait<commit_after>use std::libc::{
    c_char,
    c_double,
    c_int,
    c_uint,
    c_ulong,
    c_void,
    dev_t,
    gid_t,
    mode_t,
    off_t,
    pid_t,
    size_t,
    stat,
    time_t,
    uid_t,
};
use fuse::*;
use statvfs::Struct_statvfs;

mod fuse;
mod statvfs;

/// Information to be returned from open
#[deriving(Zero)]
pub struct OpenReply {
    direct_io:bool,
    keep_cache:bool,
    fh: u64
}

pub struct AttrReply {
    attr: stat,
    attr_timeout: c_double
}

pub struct EntryReply {
    ino: fuse_ino_t,
    generation: c_ulong,
    attr: stat,
    attr_timeout: c_double,
    entry_timeout: c_double
}

pub enum AttrToSet {
    Mode(mode_t),
    Uid(uid_t),
    Gid(gid_t),
    Size(size_t),
    Atime(time_t),
    Mtime(time_t),

    // TODO: confirm assumption about what these mean
    Atime_now,
    Mtime_now,
}

pub enum ReadReply {
    // TODO: support iov and fuse_bufvec type replies for more efficient (?)
    // types of implementation
    DataBuffer(~[u8])
}

type ErrnoResult<T> = Result<T, c_int>;

/**
 * Trait for "thin" interface to low-level FUSE ops.

 * It would be best if a user of this could just implement the methods as
 * desired, and leave the rest as defaults, and have this interface take care of
 * the rest.  Unfortunately that's not quite possible.  FUSE has default
 * behavior for some ops that can't just be invoked from a callback--the only
 * way to get it is to pass NULL for the callback pointers into the
 * fuse_lowlevel_ops structure.  But we can't know at run time which default
 * methods of a trait were overridden, which means we don't know which entries
 * in the Struct_fuse_lowlevel_ops to null out.

 * Instead, we've got a corresponding "is_implemented" method for each one.
 * Define it to return true for each real method you implement.  _BLEAH!  YUCK!
 * UGH!_ If you return true from an "is_implemented" method, but don't implement
 * the corresponding real method, it's not a compile error--you just fail at
 * run-time!  But it's the best we can do without some sort of reflection API
 * that rust doesn't have, or a way to call the FUSE default behavior from a
 * callback, which FUSE does not have.

 */
pub trait FuseLowLevelOps {
    fn init() { fail!() }
    fn init_is_implemented() -> bool { false }
    fn destroy() { fail!() }
    fn destroy_is_implemented() -> bool { false }
    fn lookup(parent: fuse_ino_t, name: &str) -> ErrnoResult<Struct_fuse_entry_param> { fail!() }
    fn lookup_is_implemented() -> bool { false }
    fn forget(ino:fuse_ino_t, nlookup:c_ulong) { fail!() }
    fn forget_is_implemented() -> bool { false }
    fn getattr(ino: fuse_ino_t, flags: c_int) -> ErrnoResult<AttrReply> { fail!() }
    fn getattr_is_implemented() -> bool { false }
    fn setattr(ino: fuse_ino_t, attrs_to_set:&[AttrToSet], fh:Option<u64>) -> ErrnoResult<AttrReply> { fail!() }
    fn setattr_is_implemented() -> bool { false }
    fn readlink(ino: fuse_ino_t) -> ErrnoResult<~str> { fail!() }
    fn readlink_is_implemented() -> bool { false }
    fn mknod(parent: fuse_ino_t, name: &str, mode: mode_t, rdev: dev_t) -> ErrnoResult<EntryReply> { fail!() }
    fn mknod_is_implemented() -> bool { false }
    fn mkdir(parent: fuse_ino_t, name: &str, mode: mode_t) -> ErrnoResult<EntryReply> { fail!() }
    fn mkdir_is_implemented() -> bool { false }
    // TODO: Using the unit type with result seems kind of goofy, but;
    // is done for consistency with the others.  Is this right?;
    fn unlink(parent: fuse_ino_t, name: &str) -> ErrnoResult<()> { fail!() }
    fn unlink_is_implemented() -> bool { false }
    fn rmdir(parent: fuse_ino_t, name: &str) -> ErrnoResult<()> { fail!() }
    fn rmdir_is_implemented() -> bool { false }
    fn symlink(link:&str, parent: fuse_ino_t, name: &str) -> ErrnoResult<EntryReply> { fail!() }
    fn symlink_is_implemented() -> bool { false }
    fn rename(parent: fuse_ino_t, name: &str, newparent: fuse_ino_t, newname: &str) -> ErrnoResult<()> { fail!() }
    fn rename_is_implemented() -> bool { false }
    fn link(ino: fuse_ino_t, newparent: fuse_ino_t, newname: &str) -> ErrnoResult<EntryReply> { fail!() }
    fn link_is_implemented() -> bool { false }
    fn open(ino: fuse_ino_t, flags: c_int) -> ErrnoResult<OpenReply> { fail!() }
    fn open_is_implemented() -> bool { false }
    fn read(ino: fuse_ino_t, size: size_t, off: off_t, fh: u64) -> ErrnoResult<ReadReply> { fail!() }
    fn read_is_implemented() -> bool { false }
    // TODO: is writepage a bool, or an actual number that needs to be;
    // preserved?;
    fn write(ino: fuse_ino_t, buf:&[u8], off: off_t, fh: u64, writepage: bool) -> ErrnoResult<size_t> { fail!() }
    fn write_is_implemented() -> bool { false }
    fn flush(ino: fuse_ino_t, lock_owner: u64, fh: u64) -> ErrnoResult<()> { fail!() }
    fn flush_is_implemented() -> bool { false }
    fn release(ino: fuse_ino_t, flags: c_int, fh: u64) -> ErrnoResult<()> { fail!() }
    fn release_is_implemented() -> bool { false }
    fn fsync(ino: fuse_ino_t, datasync: bool, fh: u64) -> ErrnoResult<()> { fail!() }
    fn fsync_is_implemented() -> bool { false }
    fn opendir(ino: fuse_ino_t) -> ErrnoResult<OpenReply> { fail!() }
    fn opendir_is_implemented() -> bool { false }
    // TODO: Using a ReadReply would require the impl to do unsafe operations;
    // to use fuse_add_direntry.  So even the thin interface needs something;
    // else here.;
    fn readdir(ino: fuse_ino_t, size: size_t, off: off_t, fh: u64) -> ErrnoResult<ReadReply> { fail!() }
    fn readdir_is_implemented() -> bool { false }
    fn releasedir(ino: fuse_ino_t, fh: u64) -> ErrnoResult<()> { fail!() }
    fn releasedir_is_implemented() -> bool { false }
    fn fsyncdir(ino: fuse_ino_t, datasync: bool, fh: u64) -> ErrnoResult<()> { fail!() }
    fn fsyncdir_is_implemented() -> bool { false }
    fn statfs(ino: fuse_ino_t) -> ErrnoResult<Struct_statvfs> { fail!() }
    fn statfs_is_implemented() -> bool { false }
    fn setxattr(ino: fuse_ino_t, name: &str, value: &[u8], flags: int) -> ErrnoResult<()> { fail!() }
    fn setxattr_is_implemented() -> bool { false }
    // TODO: examine this--ReadReply may not be appropraite here;
    fn getxattr(ino: fuse_ino_t, name: &str, size: size_t) -> ErrnoResult<ReadReply> { fail!() }
    fn getxattr_is_implemented() -> bool { false }
    // Called on getxattr with size of zero (meaning a query of total size);
    fn getxattr_size(ino: fuse_ino_t, name: &str) -> ErrnoResult<size_t> { fail!() }
    fn getxattr_size_is_implemented() -> bool { false }
    // TODO: examine this--ReadReply may not be appropraite here;
    fn listxattr(ino: fuse_ino_t, name: &str, size: size_t) -> ErrnoResult<ReadReply> { fail!() }
    fn listxattr_is_implemented() -> bool { false }
    // Called on listxattr with size of zero (meaning a query of total size);
    fn listxattr_size(ino: fuse_ino_t, name: &str) -> ErrnoResult<size_t> { fail!() }
    fn listxattr_size_is_implemented() -> bool { false }
    fn removexattr(ino: fuse_ino_t, name: &str) -> ErrnoResult<()> { fail!() }
    fn removexattr_is_implemented() -> bool { false }
    fn access(ino: fuse_ino_t, mask: c_int) -> ErrnoResult<()> { fail!() }
    fn access_is_implemented() -> bool { false }
    fn create(ino: fuse_ino_t, parent: fuse_ino_t, name: &str, mode: mode_t, flags: c_int) -> ErrnoResult<OpenReply> { fail!() }
    fn create_is_implemented() -> bool { false }

    // TODO: The following, which didn't even exist in earlier versions of FUSE,
    // can be considered nice-to-have (to an even greater extent than the whole
    // project can at this point):
    //
    // getlk
    // setlk
    // bmap
    // ioctl
    // poll
    // write_buf
    // retrieve_reply
    // forget_multi
    // flock
    // fallocate
}
<|endoftext|>


<commit_before>struct Token<'a> {
    value: &'a str,
}

impl <'a> Token<'a> {
    fn is_valid(&self) -> bool {
        !self.value.is_empty() && (self.is_operand() || self.is_operator())
    }

    fn is_operand(&self) -> bool {
        self.value.chars().all(|c| c.is_numeric() || c == '-')
    }

    fn is_operator(&self) -> bool {
        self.value == "plus"
            || self.value == "minus"
            || self.value == "multiplied"
            || self.value == "divided"
    }
}

pub fn answer(c: &str) -> Option<i32> {
    let mut t = tokens(c);
    let mut result: i32 = 0;
    let mut opr = "plus";

    if t.len() <= 1 {
        None
    } else {
        while t.len() > 1 {
            result = evaluate(result, opr, operand(&t.remove(0)));
            opr = operator(&t.remove(0));
        }
        result = evaluate(result, opr, operand(&t.remove(0)));
        Some(result)
    }
}

fn evaluate(r: i32, operator: &str, operand: i32) -> i32 {
    match operator {
        "plus" => r + operand,
        "minus" => r - operand,
        "multiplied" => r * operand,
        "divided" => r / operand,
        _ => r,
    }
}

fn operand(t: &Token) -> i32 {
    t.value.parse().unwrap()
}

fn operator<'a>(t: &Token<'a>) -> &'a str {
    t.value
}

fn tokens<'a>(command: &'a str) -> Vec<Token<'a>> {
    command
        .split(|c: char| c.is_whitespace() || c == '?')
        .map(|w| Token {
            value: w,
        })
        .filter(|t| t.is_valid())
        .collect()
}
<commit_msg>wordy: rewrite example to deal with errors<commit_after>#[derive(PartialEq)]
enum Token<'a> {
    Number(i32),
    NonNumber(&'a str),
}

fn apply_op<'a, 'b>(num1: i32, words: &'a [Token<'b>]) -> Option<(i32, &'a [Token<'b>])> {
    let number_pos = words.iter().position(|w| match w {
        Token::Number(_) => true,
        Token::NonNumber(_) => false,
    })?;
    let (op_and_num, remainder) = words.split_at(number_pos + 1);
    let (op, num2) = op_and_num.split_at(number_pos);
    let num2 = match num2 {
        [Token::Number(i)] => i,
        _ => unreachable!("We split at a Number above, so num2 is surely a single-element slice w/ a number"),
    };
    match op {
        [Token::NonNumber("plus")] => Some(num1 + num2),
        [Token::NonNumber("minus")] => Some(num1 - num2),
        [Token::NonNumber("multiplied"), Token::NonNumber("by")] => Some(num1 * num2),
        [Token::NonNumber("divided"), Token::NonNumber("by")] => Some(num1 / num2),
        _ => None,
    }.map(|n| (n, remainder))
}

pub fn answer(c: &str) -> Option<i32> {
    let words = c.trim_end_matches('?').split_whitespace().map(|word| {
        if let Ok(i) = word.parse::<i32>() {
            Token::Number(i)
        } else {
            Token::NonNumber(word)
        }
    }).collect::<Vec<_>>();
    if words.len() < 3 {
        return None;
    }
    let mut result: i32 = match words[0..3] {
        [
            Token::NonNumber("What"),
            Token::NonNumber("is"),
            Token::Number(i),
        ] => i,
        _ => return None,
    };
    let mut words = words.split_at(3).1;
    while !words.is_empty() {
        let tmp = apply_op(result, words)?;
        result = tmp.0;
        words = tmp.1;
    }
    Some(result)
}
<|endoftext|>


<commit_before>use super::*;
use redox::*;

impl Editor {
    /// Redraw the window
    pub fn redraw(&mut self) {
        // TODO: Only draw when relevant for the window
        let x = self.x();
        let y = self.y();
        // Redraw window
        self.window.set(Color::BLACK);

        self.window.rect(8 * (x - self.scroll_y) as isize,
                         16 * (y - self.scroll_x) as isize,
                         8,
                         16,
                         Color::WHITE);

        let mut string = false;

        for (y, row) in self.text.iter().enumerate() {
            for (x, &c) in row.iter().enumerate() {
                let color = match c {
                    '\'' | '"' => {
                        string = !string;
                        (226, 225, 167) //(167, 222, 156)
                    },
                    _ if string => (226, 225, 167), //(167, 222, 156)
                    '!' | '@' | '#' | '$' | '%' | '^' | '&' | '|' | '*' | '+' | '-' | '/' | ':' | '=' | '<' | '>' => (198, 83, 83), //(228, 190, 175), //(194, 106, 71),
                    '.' | ',' => (241, 213, 226),
                    '(' | ')' | '[' | ']' | '{' | '}' => (164, 212, 125), //(195, 139, 75),
                    '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => (209, 209, 177),
                    _ => (255, 255, 255),
                };

                if self.x() == x && self.y() == y {
                    self.window.char(8 * (x - self.scroll_y) as isize,
                                     16 * (y - self.scroll_x) as isize,
                                     c,
                                     Color::rgb(color.0 / 3, color.1 / 3, color.2 / 3));
                } else {
                    self.window.char(8 * (x - self.scroll_y) as isize,
                                     16 * (y - self.scroll_x) as isize,
                                     c,
                                     Color::rgb(color.0, color.1, color.2));
                }
            }
        }
        let h = self.window.height();
        let w = self.window.width();
        self.window.rect(0, h as isize - 18, w, 18, Color::rgba(74, 74, 74, 255));

        for (n, c) in (if self.status_bar.mode.len() > w / (8 * 4) {
            self.status_bar.mode.chars().take(w / (8 * 4) - 5).chain(vec!['.', '.', '.']).collect::<Vec<_>>()
        } else {
            self.status_bar.mode.chars().collect()
        }).into_iter().enumerate() {

            self.window.char(n as isize * 8, h as isize - 16 - 1, if c == '\t' { ' ' } else { c }, Color::RED);
        }

        self.window.sync();
    }
}

/// The statubar (showing various info about the current state of the editor)
pub struct StatusBar {
    /// The current mode
    pub mode: String,
    /// The cureent char
    pub file: String,
    /// The current command
    pub cmd: String,
    /// A message (such as an error or other info to the user)
    pub msg: String,
}

impl StatusBar {
    /// Create new status bar
    pub fn new() -> Self {
        StatusBar {
            mode: "Normal".to_string(),
            file: String::new(),
            cmd: String::new(),
            msg: String::new(),
        }
    }
}
<commit_msg>Change statusbar color<commit_after>use super::*;
use redox::*;

impl Editor {
    /// Redraw the window
    pub fn redraw(&mut self) {
        // TODO: Only draw when relevant for the window
        let x = self.x();
        let y = self.y();
        // Redraw window
        self.window.set(Color::BLACK);

        self.window.rect(8 * (x - self.scroll_y) as isize,
                         16 * (y - self.scroll_x) as isize,
                         8,
                         16,
                         Color::WHITE);

        let mut string = false;

        for (y, row) in self.text.iter().enumerate() {
            for (x, &c) in row.iter().enumerate() {
                // TODO: Move outta here
                let color = match c {
                    '\'' | '"' => {
                        string = !string;
                        (226, 225, 167) //(167, 222, 156)
                    },
                    _ if string => (226, 225, 167), //(167, 222, 156)
                    '!' | '@' | '#' | '$' | '%' | '^' | '&' | '|' | '*' | '+' | '-' | '/' | ':' | '=' | '<' | '>' => (198, 83, 83), //(228, 190, 175), //(194, 106, 71),
                    '.' | ',' => (241, 213, 226),
                    '(' | ')' | '[' | ']' | '{' | '}' => (164, 212, 125), //(195, 139, 75),
                    '0' | '1' | '2' | '3' | '4' | '5' | '6' | '7' | '8' | '9' => (209, 209, 177),
                    _ => (255, 255, 255),
                };

                if self.x() == x && self.y() == y {
                    self.window.char(8 * (x - self.scroll_y) as isize,
                                     16 * (y - self.scroll_x) as isize,
                                     c,
                                     Color::rgb(color.0 / 3, color.1 / 3, color.2 / 3));
                } else {
                    self.window.char(8 * (x - self.scroll_y) as isize,
                                     16 * (y - self.scroll_x) as isize,
                                     c,
                                     Color::rgb(color.0, color.1, color.2));
                }
            }
        }
        let h = self.window.height();
        let w = self.window.width();
        self.window.rect(0, h as isize - 18, w, 18, Color::rgba(74, 74, 74, 255));

        for (n, c) in (if self.status_bar.mode.len() > w / (8 * 4) {
            self.status_bar.mode.chars().take(w / (8 * 4) - 5).chain(vec!['.', '.', '.']).collect::<Vec<_>>()
        } else {
            self.status_bar.mode.chars().collect()
        }).into_iter().enumerate() {

            self.window.char(n as isize * 8, h as isize - 16 - 1, if c == '\t' { ' ' } else { c }, Color::WHITE);
        }

        self.window.sync();
    }
}

/// The statubar (showing various info about the current state of the editor)
pub struct StatusBar {
    /// The current mode
    pub mode: String,
    /// The cureent char
    pub file: String,
    /// The current command
    pub cmd: String,
    /// A message (such as an error or other info to the user)
    pub msg: String,
}

impl StatusBar {
    /// Create new status bar
    pub fn new() -> Self {
        StatusBar {
            mode: "Normal".to_string(),
            file: String::new(),
            cmd: String::new(),
            msg: String::new(),
        }
    }
}
<|endoftext|>