<commit_before>
extern crate cheddar;
extern crate regex;
extern crate imageflow_helpers;
use imageflow_helpers::identifier_styles::*;

use regex::{Regex, Captures};
use std::io::Write;
use std::path;
use cheddar::*;

//We've reimplemented I/O for cheddar so we can post-process

pub fn write<F, P: AsRef<path::Path>>(cheddar: &Cheddar, file: P, filter:F) -> Result<(), Vec<Error>>where
    F:  FnOnce(String) -> String  {
    let file = file.as_ref();

    if let Some(dir) = file.parent() {
        if let Err(error) = std::fs::create_dir_all(dir) {
            panic!("could not create directories in '{}': {}", dir.display(), error);
        }
    }

    let file_name = file.file_stem().map_or("default".into(), |os| os.to_string_lossy());
    let header = cheddar.compile(&file_name)?;
    let filtered_header = filter(header);

    let bytes_buf = filtered_header.into_bytes();
    if let Err(error) = std::fs::File::create(&file).and_then(|mut f| f.write_all(&bytes_buf)) {
        panic!("could not write to '{}': {}", file.display(), error);
    } else {
        Ok(())
    }
}

pub fn run_build<F, P: AsRef<path::Path>>(cheddar: &Cheddar,  file: P, filter: F) where
F:  FnOnce(String) -> String {
    if let Err(errors) = write(cheddar, file, filter) {
        for error in &errors {
            cheddar.print_error(error);
        }

        panic!("errors compiling header file");
    }
}

static OPAQUE_STRUCTS: &'static str = r#"
struct Context;
struct JsonResponse;
struct Job;
struct JobIo;
        "#;

static DEFINE_INTS: &'static str = r#"
typedef signed byte int8_t;
typedef signed long int64_t;
typedef signed int int32_t;
typedef unsigned byte uint8_t;
        "#;

//not used
//static TYPEDEF_VOID_STRUCTS: &'static str = r#"
//typedef void* Context;
//typedef void* JobIo;
//typedef void* Job;
//typedef void* JsonResponse;
//        "#;

fn rename_word_excluding_enum_members(input: String, old_name: &str, new_name_before_casing: &str, change_case: Style) -> String{
    let find_str = r"\b".to_owned() + old_name + r"\b(\s*)(.)";
    let new_name = style_id(new_name_before_casing, change_case);
    let s = Regex::new(&find_str).unwrap().replace_all(&input, |caps: &Captures| {
        if &caps[2] == "="  {
            caps[0].to_owned() //This is an enum member, skip
        }else{
            format!("{}{}{}", new_name, &caps[1], &caps[2])
        }
    });
    s.into_owned()
}

fn rename_enum_snake_case_and_prefix_members(input: String, old_name: &str, new_name: String, change_case: Style, member_prefix: &str, member_casing: Style) -> String {

    let new_name = style_id(&new_name, change_case);

    let new_ref = &new_name;

    let rename_term = format!("\\b{}\\b", old_name);
    let s = input;
    let s = Regex::new(&rename_term).unwrap().replace_all(&s, |_: &Captures| new_ref.to_owned() );

    let find_def_str = r"\btypedef\s+enum\s+".to_owned() + &new_name + r"\s+(\{[^\}]+\})";

    let moz_cheddar_prefix = format!("{}_", old_name);

    let s = Regex::new(&find_def_str).unwrap().replace(&s, |outer_caps: &Captures| {

        let re_member = Regex::new(r"\b([A-Za-z0-9_]+)\s+=").unwrap();

        let contents = re_member.replace_all(&outer_caps[1], | caps: &Captures| {
            let without_moz_cheddar_prefix = caps[1].replace(&moz_cheddar_prefix,"");
            let snake_id = style_id(&without_moz_cheddar_prefix, Style::Snake);
            let full_snake_id = if member_prefix == "" {
                snake_id
            }else {
               format!("{}_{}", style_id(member_prefix, Style::Snake), snake_id)
            };
            format!("{} =", style_id(&full_snake_id, member_casing))
        });
        format!("typedef enum {} {}", new_ref, contents)
    });
    s.into()
}

#[derive(Copy,Clone,PartialEq,Debug)]
enum StructModification{
    //Replace with void
    Erase,
    //You can specify no prefix..
    Prefix {
        prefix: &'static str,
        style: Style
    }
}

fn filter_structs(s: String, names: &[&str], how: StructModification) -> String{
    let mut temp = s;
    temp = match  how{
        StructModification::Erase => {
            for n in names {
                temp = rename_word_excluding_enum_members(temp, n, "void", Style::Snake);
            }
            temp
        }
        StructModification::Prefix{ prefix, style} => {
            for n in names {
                let new_name = format!("struct {}{}", prefix, n);
                temp = rename_word_excluding_enum_members(temp, n, &new_name, style);
            }
            temp
        }
    };

    //De-duplicate and lowercase struct
    temp = Regex::new(r"(?i)\bstruct\b(\s+struct)*").unwrap().replace_all(&temp, "struct").into();
    //Drop our opaque structs decl.
    temp = Regex::new(r"\bstruct void;").unwrap().replace_all(&temp, "").into();
    temp
}

#[derive(Copy,Clone,PartialEq,Debug)]
struct EnumModification{
    name_prefix: &'static str,
    member_prefix: &'static str,
    name_style: Style,
    member_style: Style
}

fn filter_enums<'a,'b>(s: String,  names: &'a[&'a str],  how: EnumModification) -> String{
    let mut temp =s;
    for n in names{
        let new_name = format!("{}{}", how.name_prefix, n);
        let member_prefix = if how.member_prefix == ""{
            "".to_owned()
        }else{
            new_name.to_owned()
        };
        temp = rename_enum_snake_case_and_prefix_members(temp, n, new_name, how.name_style, &member_prefix, how.member_style);
    }
    temp
}

static ENUM_NAMES: [&'static str; 4] = ["IoMode", "Direction", "Lifetime", "CleanupWith"];
static STRUCT_NAMES: [&'static str; 4] = ["Job", "JobIo", "Context", "JsonResponse"];

#[derive(Copy,Clone,PartialEq,Debug)]
enum Target{
    Raw,
    PInvoke,
    Default,
    Lua,
    PrefixAll{ prefix: &'static str, struct_name: Style, enum_name: Style, enum_member: Style},
    Other{structs: StructModification, enums: EnumModification}
}

fn strip_preprocessor_directives(contents: &str) -> String{
    //Strip the extern C stuff
    let temp = Regex::new(r"(?im)^\s*\#\s*ifdef\s+__cplusplus[^\#]+\#\s*endif").unwrap().replace_all(&contents, "");
    //Strip all ifndef/ifdef statements
    //let temp2 = Regex::new(r"(?im)^\s*\#\s*(ifdef|ifndef|endif).*").unwrap().replace_all(&temp, "");
    //Strip ALL # preprocessor directives
    let temp2 = Regex::new(r"(?im)^\s*\#\s*.*").unwrap().replace_all(&temp, "").into();

    temp2
}

fn build(file: String, target: Target){

    let insert = match target{
        Target::PInvoke => DEFINE_INTS,
        _ => OPAQUE_STRUCTS
    };

    if target == Target::Raw {
        run_build(cheddar::Cheddar::new().expect("could not read manifest")
                      .insert_code(insert), file, |s| s);
    }else {
        let should_strip_preprocessor_directives = target == Target::Lua;
        let target = match target {
            Target::PrefixAll { prefix, struct_name, enum_name, enum_member } => Target::Other {
                structs: StructModification::Prefix { prefix: prefix, style: struct_name },
                enums: EnumModification {
                    name_prefix: prefix, name_style: enum_name,
                    member_prefix: prefix, member_style: enum_member
                }
            },
            Target::Default | Target::Lua => Target::Other {
                structs: StructModification::Prefix { prefix: "Imageflow", style: Style::Snake },
                enums: EnumModification {
                    name_prefix: "Imageflow", name_style: Style::Snake,
                    member_prefix: "Imageflow", member_style: Style::Snake
                }
            },
            Target::PInvoke => Target::Other {
                structs: StructModification::Erase,
                enums: EnumModification {
                    name_prefix: "", name_style: Style::PascalCase,
                    member_prefix: "", member_style: Style::PascalCase
                }
            },
            t => t
        };
        if let Target::Other { structs, enums } = target {
            run_build(cheddar::Cheddar::new().expect("could not read manifest")
                          .insert_code(insert), file, |s: String| -> String {
                let temp = filter_enums(filter_structs(s, &STRUCT_NAMES, structs), &ENUM_NAMES, enums);
                if should_strip_preprocessor_directives{
                    strip_preprocessor_directives(&temp)
                }else {
                    temp
                }
            });
        } else {
            panic!("");
        }
    }
}

fn main() {
    //let base = "imageflow_"; //for debugging more easily
    let base = "../bindings/headers/imageflow_";

    build(format!("{}default.h",base), Target::Default);

    build(format!("{}lua.h",base), Target::Lua);
    build(format!("{}raw.h",base), Target::Raw);
    build(format!("{}pinvoke.h",base), Target::PInvoke);

    build(format!("{}SCREAMING_SNAKE.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::ScreamingSnake,
        enum_name: Style::ScreamingSnake,
        enum_member: Style::ScreamingSnake,
    });
    build(format!("{}SCREAMING_ENUMS.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::Snake,
        enum_name: Style::ScreamingSnake,
        enum_member: Style::ScreamingSnake,
    });
    build(format!("{}PascalCase.h",base), Target::PrefixAll{
        prefix: "",
        struct_name: Style::PascalCase,
        enum_name: Style::PascalCase,
        enum_member: Style::PascalCase,
    });
    build(format!("{}PrefixedPascalCase.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::PascalCase,
        enum_name: Style::PascalCase,
        enum_member: Style::PascalCase,
    });
    build(format!("{}Prefixed_Pascal_Snake.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::PascalSnake,
        enum_name: Style::PascalSnake,
        enum_member: Style::PascalSnake,
    });

    build(format!("{}prefixed_Camel_Snake.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::CamelSnake,
        enum_name: Style::CamelSnake,
        enum_member: Style::CamelSnake,
    });
    build(format!("{}prefixedCamelCase.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::CamelCase,
        enum_name: Style::CamelCase,
        enum_member: Style::CamelCase,
    });

}
<commit_msg>Add generation of headers/imaeflow_short.h<commit_after>
extern crate cheddar;
extern crate regex;
extern crate imageflow_helpers;
use imageflow_helpers::identifier_styles::*;

use regex::{Regex, Captures};
use std::io::Write;
use std::path;
use cheddar::*;

//We've reimplemented I/O for cheddar so we can post-process

pub fn write<F, P: AsRef<path::Path>>(cheddar: &Cheddar, file: P, filter:F) -> Result<(), Vec<Error>>where
    F:  FnOnce(String) -> String  {
    let file = file.as_ref();

    if let Some(dir) = file.parent() {
        if let Err(error) = std::fs::create_dir_all(dir) {
            panic!("could not create directories in '{}': {}", dir.display(), error);
        }
    }

    let file_name = file.file_stem().map_or("default".into(), |os| os.to_string_lossy());
    let header = cheddar.compile(&file_name)?;
    let filtered_header = filter(header);

    let bytes_buf = filtered_header.into_bytes();
    if let Err(error) = std::fs::File::create(&file).and_then(|mut f| f.write_all(&bytes_buf)) {
        panic!("could not write to '{}': {}", file.display(), error);
    } else {
        Ok(())
    }
}

pub fn run_build<F, P: AsRef<path::Path>>(cheddar: &Cheddar,  file: P, filter: F) where
F:  FnOnce(String) -> String {
    if let Err(errors) = write(cheddar, file, filter) {
        for error in &errors {
            cheddar.print_error(error);
        }

        panic!("errors compiling header file");
    }
}

static OPAQUE_STRUCTS: &'static str = r#"
struct Context;
struct JsonResponse;
struct Job;
struct JobIo;
        "#;

static DEFINE_INTS: &'static str = r#"
typedef signed byte int8_t;
typedef signed long int64_t;
typedef signed int int32_t;
typedef unsigned byte uint8_t;
        "#;

//not used
//static TYPEDEF_VOID_STRUCTS: &'static str = r#"
//typedef void* Context;
//typedef void* JobIo;
//typedef void* Job;
//typedef void* JsonResponse;
//        "#;

fn rename_word_excluding_enum_members(input: String, old_name: &str, new_name_before_casing: &str, change_case: Style) -> String{
    let find_str = r"\b".to_owned() + old_name + r"\b(\s*)(.)";
    let new_name = style_id(new_name_before_casing, change_case);
    let s = Regex::new(&find_str).unwrap().replace_all(&input, |caps: &Captures| {
        if &caps[2] == "="  {
            caps[0].to_owned() //This is an enum member, skip
        }else{
            format!("{}{}{}", new_name, &caps[1], &caps[2])
        }
    });
    s.into_owned()
}

fn rename_enum_snake_case_and_prefix_members(input: String, old_name: &str, new_name: String, change_case: Style, member_prefix: &str, member_casing: Style) -> String {

    let new_name = style_id(&new_name, change_case);

    let new_ref = &new_name;

    let rename_term = format!("\\b{}\\b", old_name);
    let s = input;
    let s = Regex::new(&rename_term).unwrap().replace_all(&s, |_: &Captures| new_ref.to_owned() );

    let find_def_str = r"\btypedef\s+enum\s+".to_owned() + &new_name + r"\s+(\{[^\}]+\})";

    let moz_cheddar_prefix = format!("{}_", old_name);

    let s = Regex::new(&find_def_str).unwrap().replace(&s, |outer_caps: &Captures| {

        let re_member = Regex::new(r"\b([A-Za-z0-9_]+)\s+=").unwrap();

        let contents = re_member.replace_all(&outer_caps[1], | caps: &Captures| {
            let without_moz_cheddar_prefix = caps[1].replace(&moz_cheddar_prefix,"");
            let snake_id = style_id(&without_moz_cheddar_prefix, Style::Snake);
            let full_snake_id = if member_prefix == "" {
                snake_id
            }else {
               format!("{}_{}", style_id(member_prefix, Style::Snake), snake_id)
            };
            format!("{} =", style_id(&full_snake_id, member_casing))
        });
        format!("typedef enum {} {}", new_ref, contents)
    });
    s.into()
}

#[derive(Copy,Clone,PartialEq,Debug)]
enum StructModification{
    //Replace with void
    Erase,
    //You can specify no prefix..
    Prefix {
        prefix: &'static str,
        style: Style
    }
}

fn filter_structs(s: String, names: &[&str], how: StructModification) -> String{
    let mut temp = s;
    temp = match  how{
        StructModification::Erase => {
            for n in names {
                temp = rename_word_excluding_enum_members(temp, n, "void", Style::Snake);
            }
            temp
        }
        StructModification::Prefix{ prefix, style} => {
            for n in names {
                let new_name = format!("struct {}{}", prefix, n);
                temp = rename_word_excluding_enum_members(temp, n, &new_name, style);
            }
            temp
        }
    };

    //De-duplicate and lowercase struct
    temp = Regex::new(r"(?i)\bstruct\b(\s+struct)*").unwrap().replace_all(&temp, "struct").into();
    //Drop our opaque structs decl.
    temp = Regex::new(r"\bstruct void;").unwrap().replace_all(&temp, "").into();
    temp
}

#[derive(Copy,Clone,PartialEq,Debug)]
struct EnumModification{
    name_prefix: &'static str,
    member_prefix: &'static str,
    name_style: Style,
    member_style: Style
}

fn filter_enums<'a,'b>(s: String,  names: &'a[&'a str],  how: EnumModification) -> String{
    let mut temp =s;
    for n in names{
        let new_name = format!("{}{}", how.name_prefix, n);
        let member_prefix = if how.member_prefix == ""{
            "".to_owned()
        }else{
            new_name.to_owned()
        };
        temp = rename_enum_snake_case_and_prefix_members(temp, n, new_name, how.name_style, &member_prefix, how.member_style);
    }
    temp
}

static ENUM_NAMES: [&'static str; 4] = ["IoMode", "Direction", "Lifetime", "CleanupWith"];
static STRUCT_NAMES: [&'static str; 4] = ["Job", "JobIo", "Context", "JsonResponse"];

#[derive(Copy,Clone,PartialEq,Debug)]
enum Target{
    Raw,
    PInvoke,
    Default,
    Lua,
    SignaturesOnly,
    PrefixAll{ prefix: &'static str, struct_name: Style, enum_name: Style, enum_member: Style},
    Other{structs: StructModification, enums: EnumModification}
}

fn strip_preprocessor_directives(contents: &str) -> String{
    //Strip the extern C stuff
    let temp = Regex::new(r"(?im)^\s*\#\s*ifdef\s+__cplusplus[^\#]+\#\s*endif").unwrap().replace_all(&contents, "");
    //Strip all ifndef/ifdef statements
    //let temp2 = Regex::new(r"(?im)^\s*\#\s*(ifdef|ifndef|endif).*").unwrap().replace_all(&temp, "");
    //Strip ALL # preprocessor directives
    let temp2 = Regex::new(r"(?im)^\s*\#\s*.*").unwrap().replace_all(&temp, "").into();

    temp2
}

fn strip_comments(contents: &str) -> String{
    let temp = Regex::new(r"//[^\n\r]*").unwrap().replace_all(&contents, "");
    let temp2 = Regex::new(r"[\n\r\s\t]+\n").unwrap().replace_all(&temp, "\n\n").into();
    temp2
}
fn build(file: String, target: Target){

    let insert = match target{
        Target::PInvoke => DEFINE_INTS,
        _ => OPAQUE_STRUCTS
    };

    if target == Target::Raw {
        run_build(cheddar::Cheddar::new().expect("could not read manifest")
                      .insert_code(insert), file, |s| s);
    }else {
        let should_strip_preprocessor_directives = target == Target::Lua || target == Target::SignaturesOnly;
        let should_strip_comments = target == Target::SignaturesOnly;
        let target = match target {
            Target::PrefixAll { prefix, struct_name, enum_name, enum_member } => Target::Other {
                structs: StructModification::Prefix { prefix: prefix, style: struct_name },
                enums: EnumModification {
                    name_prefix: prefix, name_style: enum_name,
                    member_prefix: prefix, member_style: enum_member
                }
            },
            Target::Default | Target::Lua => Target::Other {
                structs: StructModification::Prefix { prefix: "Imageflow", style: Style::Snake },
                enums: EnumModification {
                    name_prefix: "Imageflow", name_style: Style::Snake,
                    member_prefix: "Imageflow", member_style: Style::Snake
                }
            },
            Target::PInvoke => Target::Other {
                structs: StructModification::Erase,
                enums: EnumModification {
                    name_prefix: "", name_style: Style::PascalCase,
                    member_prefix: "", member_style: Style::PascalCase
                }
            },
             Target::SignaturesOnly => Target::Other {
                structs: StructModification::Erase,
                enums: EnumModification {
                    name_prefix: "Imageflow", name_style: Style::Snake,
                    member_prefix: "Imageflow", member_style: Style::Snake
                }
            },
            t => t
        };
        if let Target::Other { structs, enums } = target {
            run_build(cheddar::Cheddar::new().expect("could not read manifest")
                          .insert_code(insert), file, |s: String| -> String {
                let temp = filter_enums(filter_structs(s, &STRUCT_NAMES, structs), &ENUM_NAMES, enums);
                let temp = if should_strip_preprocessor_directives{
                    strip_preprocessor_directives(&temp)
                }else {
                    temp
                };
                if should_strip_comments{
                    strip_comments(&temp)
                } else{
                    temp
                }
            });
        } else {
            panic!("");
        }
    }
}

fn main() {
    //let base = "imageflow_"; //for debugging more easily
    let base = "../bindings/headers/imageflow_";

    build(format!("{}default.h",base), Target::Default);

    build(format!("{}lua.h",base), Target::Lua);
    build(format!("{}raw.h",base), Target::Raw);

    build(format!("{}short.h",base), Target::SignaturesOnly);
    build(format!("{}pinvoke.h",base), Target::PInvoke);

    build(format!("{}SCREAMING_SNAKE.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::ScreamingSnake,
        enum_name: Style::ScreamingSnake,
        enum_member: Style::ScreamingSnake,
    });
    build(format!("{}SCREAMING_ENUMS.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::Snake,
        enum_name: Style::ScreamingSnake,
        enum_member: Style::ScreamingSnake,
    });
    build(format!("{}PascalCase.h",base), Target::PrefixAll{
        prefix: "",
        struct_name: Style::PascalCase,
        enum_name: Style::PascalCase,
        enum_member: Style::PascalCase,
    });
    build(format!("{}PrefixedPascalCase.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::PascalCase,
        enum_name: Style::PascalCase,
        enum_member: Style::PascalCase,
    });
    build(format!("{}Prefixed_Pascal_Snake.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::PascalSnake,
        enum_name: Style::PascalSnake,
        enum_member: Style::PascalSnake,
    });

    build(format!("{}prefixed_Camel_Snake.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::CamelSnake,
        enum_name: Style::CamelSnake,
        enum_member: Style::CamelSnake,
    });
    build(format!("{}prefixedCamelCase.h",base), Target::PrefixAll{
        prefix: "Imageflow",
        struct_name: Style::CamelCase,
        enum_name: Style::CamelCase,
        enum_member: Style::CamelCase,
    });

}
<|endoftext|>


<commit_before>use libc::c_int;
use std::ops::Deref;
use tensorflow_sys as tf;

use crate::{AnyTensor, DataType, Result, Shape, Tensor, TensorInner, TensorType};

/// A read-only tensor.
///
/// This ReadonlyTensor is a wrapper around a `Tensor` that is read-only.
/// Some operations that mutate the underlying Tensor are not supported.
#[derive(Debug, Clone, Eq)]
pub struct ReadonlyTensor<T: TensorType> {
    pub(super) inner: T::InnerType,
    pub(super) dims: Vec<u64>,
}

impl<T: TensorType> AnyTensor for ReadonlyTensor<T> {
    fn inner(&self) -> Result<*mut tf::TF_Tensor> {
        self.inner.as_mut_ptr(&self.dims)
    }

    fn data_type(&self) -> DataType {
        T::data_type()
    }
}

impl<T: TensorType> Deref for ReadonlyTensor<T> {
    type Target = [T];

    #[inline]
    fn deref(&self) -> &[T] {
        self.inner.deref()
    }
}

impl<T: TensorType + PartialEq> PartialEq for ReadonlyTensor<T> {
    fn eq(&self, other: &Self) -> bool {
        self.dims == other.dims && self.deref() == other.deref()
    }
}

impl<T: TensorType + PartialEq> PartialEq<Tensor<T>> for ReadonlyTensor<T> {
    fn eq(&self, other: &Tensor<T>) -> bool {
        self.dims == other.dims && self.deref() == other.deref()
    }
}

impl<T: TensorType> ReadonlyTensor<T> {
    /// Get one single value from the Tensor.
    ///
    /// ```
    /// # use tensorflow::Tensor;
    /// # use tensorflow::eager::ReadonlyTensor;
    /// let mut a = Tensor::<i32>::new(&[2, 3, 5]);
    ///
    /// a[1*15 + 1*5 + 1] = 5;
    /// let a = a.freeze();
    /// assert_eq!(a.get(&[1, 1, 1]), 5);
    /// ```
    pub fn get(&self, indices: &[u64]) -> T {
        let index = self.get_index(indices);
        self[index].clone()
    }

    /// Get the array index from rows / columns indices.
    ///
    /// ```
    /// # use tensorflow::Tensor;
    /// # use tensorflow::eager::ReadonlyTensor;
    /// let a = Tensor::<f32>::new(&[3, 3, 3]).freeze();
    ///
    /// assert_eq!(a.get_index(&[2, 2, 2]), 26);
    /// assert_eq!(a.get_index(&[1, 2, 2]), 17);
    /// assert_eq!(a.get_index(&[1, 2, 0]), 15);
    /// assert_eq!(a.get_index(&[1, 0, 1]), 10);
    /// ```
    pub fn get_index(&self, indices: &[u64]) -> usize {
        assert!(self.dims.len() == indices.len());
        let mut index = 0;
        let mut d = 1;
        for i in (0..indices.len()).rev() {
            assert!(self.dims[i] > indices[i]);
            index += indices[i] * d;
            d *= self.dims[i];
        }
        index as usize
    }

    /// Returns the tensor's dimensions.
    pub fn dims(&self) -> &[u64] {
        &self.dims
    }

    /// Returns the tensor's dimensions as a Shape.
    pub fn shape(&self) -> Shape {
        Shape(Some(self.dims.iter().map(|d| Some(*d as i64)).collect()))
    }

    // Wraps a TF_Tensor. Returns None if types don't match.
    pub(super) unsafe fn from_tf_tensor(tensor: *mut tf::TF_Tensor) -> Option<Self> {
        let mut dims = Vec::with_capacity(tf::TF_NumDims(tensor) as usize);
        for i in 0..dims.capacity() {
            dims.push(tf::TF_Dim(tensor, i as c_int) as u64);
        }

        Some(Self {
            inner: T::InnerType::from_tf_tensor(tensor)?,
            dims,
        })
    }

    /// Convert back to a Tensor.
    ///
    /// # Safety
    ///
    /// This is unsafe because modifying the returned Tensor will modify the underlying memory,
    /// which may affect other Tensors that share the same memory.
    ///
    /// ```
    /// # use tensorflow::{Tensor, Result};
    /// # use tensorflow::eager::*;
    /// # fn main() -> Result<()> {
    /// let ctx = Context::new(ContextOptions::new()).unwrap();
    /// let tensor = Tensor::from(0i32).freeze();
    /// let h = tensor.to_handle(&ctx).unwrap();
    ///
    /// let t0 = h.resolve::<i32>().unwrap();
    /// assert_eq!(t0[0], 0i32);
    ///
    /// // Manipulating the Tensor will affect the Tensor that shares underlying buffer.
    /// {
    ///     // Getting multiple times should return the same Tensor.
    ///     let t1 = h.resolve::<i32>().unwrap();
    ///
    ///     // Convert back from a TensorHandle to a Tensor.
    ///     let mut t1 = unsafe { t1.into_tensor() };
    ///     t1[0] = 5;
    /// }
    ///
    /// // Check that t0 shares the same underlying buffer with t1.
    /// // This is why we need to use unsafe.
    /// assert_eq!(t0[0], 5);
    /// # Ok(())
    /// # }
    /// ```
    pub unsafe fn into_tensor(self) -> Tensor<T> {
        Tensor {
            inner: self.inner,
            dims: self.dims,
        }
    }
}
<commit_msg>update doc<commit_after>use libc::c_int;
use std::ops::Deref;
use tensorflow_sys as tf;

use crate::{AnyTensor, DataType, Result, Shape, Tensor, TensorInner, TensorType};

/// A read-only tensor.
///
/// ReadonlyTensor is a [`Tensor`](Tensor) that does not support mutation.
#[derive(Debug, Clone, Eq)]
pub struct ReadonlyTensor<T: TensorType> {
    pub(super) inner: T::InnerType,
    pub(super) dims: Vec<u64>,
}

impl<T: TensorType> AnyTensor for ReadonlyTensor<T> {
    fn inner(&self) -> Result<*mut tf::TF_Tensor> {
        self.inner.as_mut_ptr(&self.dims)
    }

    fn data_type(&self) -> DataType {
        T::data_type()
    }
}

impl<T: TensorType> Deref for ReadonlyTensor<T> {
    type Target = [T];

    #[inline]
    fn deref(&self) -> &[T] {
        self.inner.deref()
    }
}

impl<T: TensorType + PartialEq> PartialEq for ReadonlyTensor<T> {
    fn eq(&self, other: &Self) -> bool {
        self.dims == other.dims && self.deref() == other.deref()
    }
}

impl<T: TensorType + PartialEq> PartialEq<Tensor<T>> for ReadonlyTensor<T> {
    fn eq(&self, other: &Tensor<T>) -> bool {
        self.dims == other.dims && self.deref() == other.deref()
    }
}

impl<T: TensorType> ReadonlyTensor<T> {
    /// Get one single value from the Tensor.
    ///
    /// ```
    /// # use tensorflow::Tensor;
    /// # use tensorflow::eager::ReadonlyTensor;
    /// let mut a = Tensor::<i32>::new(&[2, 3, 5]);
    ///
    /// a[1*15 + 1*5 + 1] = 5;
    /// let a: ReadonlyTensor<_> = a.freeze();
    /// assert_eq!(a.get(&[1, 1, 1]), 5);
    /// ```
    pub fn get(&self, indices: &[u64]) -> T {
        let index = self.get_index(indices);
        self[index].clone()
    }

    /// Get the array index from rows / columns indices.
    ///
    /// ```
    /// # use tensorflow::Tensor;
    /// # use tensorflow::eager::ReadonlyTensor;
    /// let a: ReadonlyTensor<_> = Tensor::<f32>::new(&[3, 3, 3]).freeze();
    ///
    /// assert_eq!(a.get_index(&[2, 2, 2]), 26);
    /// assert_eq!(a.get_index(&[1, 2, 2]), 17);
    /// assert_eq!(a.get_index(&[1, 2, 0]), 15);
    /// assert_eq!(a.get_index(&[1, 0, 1]), 10);
    /// ```
    pub fn get_index(&self, indices: &[u64]) -> usize {
        assert!(self.dims.len() == indices.len());
        let mut index = 0;
        let mut d = 1;
        for i in (0..indices.len()).rev() {
            assert!(self.dims[i] > indices[i]);
            index += indices[i] * d;
            d *= self.dims[i];
        }
        index as usize
    }

    /// Returns the tensor's dimensions.
    pub fn dims(&self) -> &[u64] {
        &self.dims
    }

    /// Returns the tensor's dimensions as a Shape.
    pub fn shape(&self) -> Shape {
        Shape(Some(self.dims.iter().map(|d| Some(*d as i64)).collect()))
    }

    // Wraps a TF_Tensor. Returns None if types don't match.
    pub(super) unsafe fn from_tf_tensor(tensor: *mut tf::TF_Tensor) -> Option<Self> {
        let mut dims = Vec::with_capacity(tf::TF_NumDims(tensor) as usize);
        for i in 0..dims.capacity() {
            dims.push(tf::TF_Dim(tensor, i as c_int) as u64);
        }

        Some(Self {
            inner: T::InnerType::from_tf_tensor(tensor)?,
            dims,
        })
    }

    /// Convert back to a Tensor.
    ///
    /// # Safety
    ///
    /// This is unsafe because modifying the returned Tensor will modify the underlying memory,
    /// which may affect other Tensors that share the same memory.
    ///
    /// ```
    /// # use tensorflow::{Tensor, Result};
    /// # use tensorflow::eager::*;
    /// # fn main() -> Result<()> {
    /// let ctx = Context::new(ContextOptions::new()).unwrap();
    /// let tensor = Tensor::from(0i32).freeze();
    /// let h = tensor.to_handle(&ctx).unwrap();
    ///
    /// let t0 = h.resolve::<i32>().unwrap();
    /// assert_eq!(t0[0], 0i32);
    ///
    /// // Manipulating the Tensor will affect the Tensor that shares underlying buffer.
    /// {
    ///     // Getting multiple times should return the same Tensor.
    ///     let t1 = h.resolve::<i32>().unwrap();
    ///
    ///     // Convert back from a TensorHandle to a Tensor.
    ///     let mut t1 = unsafe { t1.into_tensor() };
    ///     t1[0] = 5;
    /// }
    ///
    /// // Check that t0 shares the same underlying buffer with t1.
    /// // This is why we need to use unsafe.
    /// assert_eq!(t0[0], 5);
    /// # Ok(())
    /// # }
    /// ```
    pub unsafe fn into_tensor(self) -> Tensor<T> {
        Tensor {
            inner: self.inner,
            dims: self.dims,
        }
    }
}
<|endoftext|>


<commit_before>#![feature(proc_macro_hygiene, decl_macro)]

#![macro_use] extern crate rocket;

#[get("/")]
fn index() -> &'static str {
    "Hello, world!"
}

fn main () {
    rocket::ignite().mount("/", routes![index]).launch();
}
<commit_msg>Added working rust rest service<commit_after>#![feature(proc_macro_hygiene, decl_macro)]

extern crate rocket;
extern crate rocket_contrib;
extern crate serde;

#[macro_use]extern crate serde_derive;
#[macro_use]extern crate serde_json;

use rocket::{get, routes};

#[get("/")]
fn index() -> &'static str {
    return("Hello, world!");
}

fn main () {
    rocket::ignite().mount("/", routes![index]).launch();
}
<|endoftext|>


<commit_before>use super::MessageAction;
use super::InjectMode;
use config::action::ExecCondition;

use handlebars::Template;
use handlebars::Handlebars;
use serde::de::{Deserialize, Deserializer, Error, MapVisitor, Visitor};
use std::collections::BTreeMap;
use super::MESSAGE;

impl Deserialize for MessageAction {
    fn deserialize<D>(deserializer: &mut D) -> Result<MessageAction, D::Error>
        where D: Deserializer
    {
        deserializer.visit_struct("MessageAction", &[], MessageActionVisitor)
    }
}

enum Field {
    Uuid,
    Name,
    Message,
    Values,
    When,
    InjectMode,
}

impl Deserialize for Field {
    fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = Field;

            fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
                where E: Error
            {
                match value {
                    "name" => Ok(Field::Name),
                    "uuid" => Ok(Field::Uuid),
                    "values" => Ok(Field::Values),
                    "message" => Ok(Field::Message),
                    "when" => Ok(Field::When),
                    "inject_mode" => Ok(Field::InjectMode),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

struct MessageActionVisitor;

impl MessageActionVisitor {
    fn compile_template<V>(template_string: String, uuid: &str) -> Result<Template, V::Error>
        where V: MapVisitor
    {
        Template::compile(template_string).map_err(|error| {
            Error::syntax(&format!("Invalid handlebars template in 'message' field: \
                                        uuid={}, error={}",
                                       uuid,
                                       error))
        })
    }
}

impl Visitor for MessageActionVisitor {
    type Value = MessageAction;

    fn visit_map<V>(&mut self, mut visitor: V) -> Result<MessageAction, V::Error>
        where V: MapVisitor
    {
        let mut name: Option<String> = None;
        let mut uuid: Option<String> = None;
        let mut message: Option<String> = None;
        let mut values: Option<BTreeMap<String, String>> = None;
        let mut when: ExecCondition = ExecCondition::new();
        let mut inject_mode = Default::default();

        while let Some(field) = try!(visitor.visit_key()) {
            match field {
                Field::Name => name = Some(try!(visitor.visit_value())),
                Field::Uuid => uuid = Some(try!(visitor.visit_value())),
                Field::Message => message = Some(try!(visitor.visit_value())),
                Field::Values => values = Some(try!(visitor.visit_value())),
                Field::When => when = try!(visitor.visit_value()),
                Field::InjectMode => inject_mode = try!(visitor.visit_value()),
            }
        }

        let uuid = match uuid {
            Some(uuid) => uuid,
            None => return visitor.missing_field("uuid"),
        };

        let message = match message {
            Some(message) => try!(MessageActionVisitor::compile_template::<V>(message, &uuid)),
            None => {
                error!("Missing 'message' field: uuid={}", &uuid);
                return visitor.missing_field("message");
            }
        };

        let mut values = match values {
            Some(values) => {
                let mut registry = Handlebars::new();
                for (key, value) in values.into_iter() {
                    let template = try!(MessageActionVisitor::compile_template::<V>(value, &uuid));
                    registry.register_template(&key, template);
                }
                registry
            }
            None => Handlebars::new(),
        };

        try!(visitor.end());

        values.register_template(MESSAGE, message.clone());

        Ok(MessageAction {
            uuid: uuid,
            message: message,
            name: name,
            values: values,
            when: when,
            inject_mode: inject_mode,
        })
    }
}

impl Deserialize for InjectMode {
    fn deserialize<D>(deserializer: &mut D) -> Result<InjectMode, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = InjectMode;

            fn visit_str<E>(&mut self, value: &str) -> Result<InjectMode, E>
                where E: Error
            {
                match value {
                    "log" => Ok(InjectMode::Log),
                    "loopback" => Ok(InjectMode::Loopback),
                    "forward" => Ok(InjectMode::Forward),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

#[cfg(test)]
mod test {
    use config::action::message::{MessageActionBuilder, MessageAction, InjectMode};

    use handlebars::Template;
    use serde_json::from_str;

    fn assert_message_action_eq(expected: &MessageAction, actual: &MessageAction) {
        assert_eq!(expected.uuid(), actual.uuid());
        assert_eq!(expected.name(), actual.name());
        assert_eq!(expected.message(), actual.message());
    }

    #[test]
    fn test_given_message_as_a_json_string_when_it_is_deserialized_then_we_get_the_expected_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "name": "NAME",
          "message": "message",
          "values": {
            "key1": "value1",
            "key2": "value2"
          }
        }
        "#;

        let message = Template::compile("message".to_owned())
                          .expect("Failed to compile a handlebars template");
        let value1 = Template::compile("value1".to_owned())
                         .expect("Failed to compile a handlebars template");
        let value2 = Template::compile("value2".to_owned())
                         .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message)
                                   .name(Some("NAME"))
                                   .pair("key1", value1)
                                   .pair("key2", value2)
                                   .build();
        let result = from_str::<MessageAction>(text);
        let message = result.expect("Failed to deserialize a valid MessageAction object");
        assert_message_action_eq(&expected_message, &message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_only_the_required_fields_are_present_then_we_can_deserialize_the_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "message": "message"
        }
        "#;

        let message = Template::compile("message".to_owned())
                          .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message).build();
        let result = from_str::<MessageAction>(text);
        let message = result.expect("Failed to deserialize a valid MessageAction object");
        assert_message_action_eq(&expected_message, &message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_one_of_the_required_fields_are_not_present_then_we_get_error
        () {
        let text = r#"
        {
        }
        "#;

        let result = from_str::<MessageAction>(text);
        let _ = result.err().expect("Successfully deserialized an invalid MessageAction object");
    }

    #[test]
    fn test_given_inject_modes_when_they_are_deserialized_then_we_get_the_right_result() {
        let text = r#"
        ["forward", "log", "loopback", "log"]
        "#;
        let expected = vec![InjectMode::Forward,
                            InjectMode::Log,
                            InjectMode::Loopback,
                            InjectMode::Log];

        let result = from_str::<Vec<InjectMode>>(text);
        println!("{:?}", &result);
        let array = result.expect("Failed to deserialize a valid array of inject modes");
        assert_eq!(&expected, &array);
    }

    #[test]
    fn test_given_invalid_inject_mode_when_it_is_deserialized_then_we_get_the_right_result() {
        let text = r#"
        ["invalid inject mode", "log"]
        "#;

        let result = from_str::<Vec<InjectMode>>(text);
        println!("{:?}", &result);
        let _ = result.err().expect("Successfully deserialized an invalid inject mode");
    }

    #[test]
    fn test_given_message_when_it_contains_inject_mode_then_it_can_be_deserialized() {
        let text = r#"
        {
          "uuid": "UUID",
          "message": "message",
          "inject_mode": "forward"
        }
        "#;

        let message = Template::compile("message".to_owned())
                          .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message)
                                   .inject_mode(InjectMode::Forward)
                                   .build();
        let result = from_str::<MessageAction>(text);
        let message = result.expect("Failed to deserialize a valid MessageAction object");
        assert_message_action_eq(&expected_message, &message);
    }

    #[test]
    fn test_given_message_is_deserialized_when_it_contains_an_unexpected_field_then_an_error_is_returned() {
        let text = r#"{ "unexpected": "UUID" }"#;
        let result = from_str::<MessageAction>(text);
        let _ = result.err().unwrap();
    }
}
<commit_msg>MessageAction: add a new deserialization unit test<commit_after>use super::MessageAction;
use super::InjectMode;
use config::action::ExecCondition;

use handlebars::Template;
use handlebars::Handlebars;
use serde::de::{Deserialize, Deserializer, Error, MapVisitor, Visitor};
use std::collections::BTreeMap;
use super::MESSAGE;

impl Deserialize for MessageAction {
    fn deserialize<D>(deserializer: &mut D) -> Result<MessageAction, D::Error>
        where D: Deserializer
    {
        deserializer.visit_struct("MessageAction", &[], MessageActionVisitor)
    }
}

enum Field {
    Uuid,
    Name,
    Message,
    Values,
    When,
    InjectMode,
}

impl Deserialize for Field {
    fn deserialize<D>(deserializer: &mut D) -> Result<Field, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = Field;

            fn visit_str<E>(&mut self, value: &str) -> Result<Field, E>
                where E: Error
            {
                match value {
                    "name" => Ok(Field::Name),
                    "uuid" => Ok(Field::Uuid),
                    "values" => Ok(Field::Values),
                    "message" => Ok(Field::Message),
                    "when" => Ok(Field::When),
                    "inject_mode" => Ok(Field::InjectMode),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

struct MessageActionVisitor;

impl MessageActionVisitor {
    fn compile_template<V>(template_string: String, uuid: &str) -> Result<Template, V::Error>
        where V: MapVisitor
    {
        Template::compile(template_string).map_err(|error| {
            Error::syntax(&format!("Invalid handlebars template in 'message' field: \
                                        uuid={}, error={}",
                                       uuid,
                                       error))
        })
    }
}

impl Visitor for MessageActionVisitor {
    type Value = MessageAction;

    fn visit_map<V>(&mut self, mut visitor: V) -> Result<MessageAction, V::Error>
        where V: MapVisitor
    {
        let mut name: Option<String> = None;
        let mut uuid: Option<String> = None;
        let mut message: Option<String> = None;
        let mut values: Option<BTreeMap<String, String>> = None;
        let mut when: ExecCondition = ExecCondition::new();
        let mut inject_mode = Default::default();

        while let Some(field) = try!(visitor.visit_key()) {
            match field {
                Field::Name => name = Some(try!(visitor.visit_value())),
                Field::Uuid => uuid = Some(try!(visitor.visit_value())),
                Field::Message => message = Some(try!(visitor.visit_value())),
                Field::Values => values = Some(try!(visitor.visit_value())),
                Field::When => when = try!(visitor.visit_value()),
                Field::InjectMode => inject_mode = try!(visitor.visit_value()),
            }
        }

        let uuid = match uuid {
            Some(uuid) => uuid,
            None => return visitor.missing_field("uuid"),
        };

        let message = match message {
            Some(message) => try!(MessageActionVisitor::compile_template::<V>(message, &uuid)),
            None => {
                error!("Missing 'message' field: uuid={}", &uuid);
                return visitor.missing_field("message");
            }
        };

        let mut values = match values {
            Some(values) => {
                let mut registry = Handlebars::new();
                for (key, value) in values.into_iter() {
                    let template = try!(MessageActionVisitor::compile_template::<V>(value, &uuid));
                    registry.register_template(&key, template);
                }
                registry
            }
            None => Handlebars::new(),
        };

        try!(visitor.end());

        values.register_template(MESSAGE, message.clone());

        Ok(MessageAction {
            uuid: uuid,
            message: message,
            name: name,
            values: values,
            when: when,
            inject_mode: inject_mode,
        })
    }
}

impl Deserialize for InjectMode {
    fn deserialize<D>(deserializer: &mut D) -> Result<InjectMode, D::Error>
        where D: Deserializer
    {
        struct FieldVisitor;

        impl Visitor for FieldVisitor {
            type Value = InjectMode;

            fn visit_str<E>(&mut self, value: &str) -> Result<InjectMode, E>
                where E: Error
            {
                match value {
                    "log" => Ok(InjectMode::Log),
                    "loopback" => Ok(InjectMode::Loopback),
                    "forward" => Ok(InjectMode::Forward),
                    _ => Err(Error::syntax(&format!("Unexpected field: {}", value))),
                }
            }
        }

        deserializer.visit(FieldVisitor)
    }
}

#[cfg(test)]
mod test {
    use config::action::message::{MessageActionBuilder, MessageAction, InjectMode};

    use handlebars::Template;
    use serde_json::from_str;

    fn assert_message_action_eq(expected: &MessageAction, actual: &MessageAction) {
        assert_eq!(expected.uuid(), actual.uuid());
        assert_eq!(expected.name(), actual.name());
        assert_eq!(expected.message(), actual.message());
    }

    #[test]
    fn test_given_message_as_a_json_string_when_it_is_deserialized_then_we_get_the_expected_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "name": "NAME",
          "message": "message",
          "values": {
            "key1": "value1",
            "key2": "value2"
          }
        }
        "#;

        let message = Template::compile("message".to_owned())
                          .expect("Failed to compile a handlebars template");
        let value1 = Template::compile("value1".to_owned())
                         .expect("Failed to compile a handlebars template");
        let value2 = Template::compile("value2".to_owned())
                         .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message)
                                   .name(Some("NAME"))
                                   .pair("key1", value1)
                                   .pair("key2", value2)
                                   .build();
        let result = from_str::<MessageAction>(text);
        let message = result.expect("Failed to deserialize a valid MessageAction object");
        assert_message_action_eq(&expected_message, &message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_only_the_required_fields_are_present_then_we_can_deserialize_the_message
        () {
        let text = r#"
        {
          "uuid": "UUID",
          "message": "message"
        }
        "#;

        let message = Template::compile("message".to_owned())
                          .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message).build();
        let result = from_str::<MessageAction>(text);
        let message = result.expect("Failed to deserialize a valid MessageAction object");
        assert_message_action_eq(&expected_message, &message);
    }

    #[test]
    fn test_given_message_as_a_json_string_when_one_of_the_required_fields_are_not_present_then_we_get_error
        () {
        let text = r#"
        {
        }
        "#;

        let result = from_str::<MessageAction>(text);
        let _ = result.err().expect("Successfully deserialized an invalid MessageAction object");
    }

    #[test]
    fn test_given_inject_modes_when_they_are_deserialized_then_we_get_the_right_result() {
        let text = r#"
        ["forward", "log", "loopback", "log"]
        "#;
        let expected = vec![InjectMode::Forward,
                            InjectMode::Log,
                            InjectMode::Loopback,
                            InjectMode::Log];

        let result = from_str::<Vec<InjectMode>>(text);
        println!("{:?}", &result);
        let array = result.expect("Failed to deserialize a valid array of inject modes");
        assert_eq!(&expected, &array);
    }

    #[test]
    fn test_given_invalid_inject_mode_when_it_is_deserialized_then_we_get_the_right_result() {
        let text = r#"
        ["invalid inject mode", "log"]
        "#;

        let result = from_str::<Vec<InjectMode>>(text);
        println!("{:?}", &result);
        let _ = result.err().expect("Successfully deserialized an invalid inject mode");
    }

    #[test]
    fn test_given_message_when_it_contains_inject_mode_then_it_can_be_deserialized() {
        let text = r#"
        {
          "uuid": "UUID",
          "message": "message",
          "inject_mode": "forward"
        }
        "#;

        let message = Template::compile("message".to_owned())
                          .expect("Failed to compile a handlebars template");
        let expected_message = MessageActionBuilder::new("UUID", message)
                                   .inject_mode(InjectMode::Forward)
                                   .build();
        let result = from_str::<MessageAction>(text);
        let message = result.expect("Failed to deserialize a valid MessageAction object");
        assert_message_action_eq(&expected_message, &message);
    }

    #[test]
    fn test_given_message_is_deserialized_when_it_contains_an_unexpected_field_then_an_error_is_returned() {
        let text = r#"{ "unexpected": "UUID" }"#;
        let result = from_str::<MessageAction>(text);
        let _ = result.err().unwrap();
    }

    #[test]
    fn test_given_message_with_invalid_message_template_when_it_is_deserialized_then_an_error_is_returned() {
        let text = r#"{ "uuid": "INVALID_MSG", "message": "{invalid}}" }"#;
        let result = from_str::<MessageAction>(text);
        let _ = result.err().unwrap();
    }
}
<|endoftext|>


<commit_before>//! Bindings to kernel/exit.c
//!
//! Currently only provides access to exit() and exit_group()

#![cfg(target_os = "linux")]

extern crate linux_api;

use linux_api::{c_int};

extern {

    ///Exits the current process with the specified error code
    ///
    ///You should use either linux_api::EXIT_SUCCESS or linux_api::EXIT_FAILURE
    pub fn exit(error_code: c_int);

    ///Exits every process in the current process group with the specified error code
    ///
    ///You should use either linux_api::EXIT_SUCCESS or linux_api::EXIT_FAILURE
    pub fn exit_group(error_code: c_int);

}

#[cfg(test)]
mod test {

    use linux_api::{EXIT_SUCCESS, EXIT_FAILURE};

    #[test]
    fn ensure_exit_values_exist() {
        assert_eq!(0, EXIT_SUCCESS);
        assert_eq!(1, EXIT_FAILURE);
    }

}<commit_msg>linux-api-exit: A few minor changes<commit_after>//! Bindings to kernel/exit.c
//!
//! Currently only provides access to exit() and exit_group()

#![cfg(target_os = "linux")]

extern crate linux_api;

use linux_api::{c_int};

extern {

    ///Exits the current process with the specified exit code
    ///
    ///You should use either linux_api::EXIT_SUCCESS or linux_api::EXIT_FAILURE
    pub fn exit(exit_code: c_int);

    //pub fn exit_group(exit_code: c_int); I was advised to remove this since it should never be called in user space, but handled by libc while using exit()

}

///Exits the current process while indicating a successful operation
pub fn exit_as_success() {
    unsafe { exit(linux_api::EXIT_SUCCESS); }
}

///Exits the current process while indicating a failed operation as the cause of exit
pub fn exit_as_failure() {
    unsafe { exit(linux_api::EXIT_FAILURE); }
}

#[cfg(test)]
mod test {

    use linux_api::{EXIT_SUCCESS, EXIT_FAILURE};

    #[test]
    fn ensure_exit_values_exist() {
        assert_eq!(0, EXIT_SUCCESS);
        assert_eq!(1, EXIT_FAILURE);
    }

}<|endoftext|>


<commit_before><commit_msg>identifying and patching panic holes<commit_after><|endoftext|>


<commit_before><commit_msg>Debugging PartialContent status check<commit_after><|endoftext|>


<commit_before><commit_msg>bookmark.rs<commit_after><|endoftext|>


<commit_before><commit_msg>CR2: fix semi-broken YUV->RGB conversion<commit_after><|endoftext|>


<commit_before>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! Code for using the `x86` and `x86_64` segmentation hardware.
//!
//! For more information, refer to the _Intel® 64 and IA-32 Architectures
//! Software Developer’s Manual_, Vol. 3A, section 3.2, "Using Segments".
//! Some of the documentation present in this module was taken from the Intel
//! manual.
use core::{fmt, mem};
use super::PrivilegeLevel;

bitflags! {
    /// A segment selector is a 16-bit identifier for a segment.
    ///
    /// It does not point directly to the segment, but instead points to the
    /// segment descriptor that defines the segment.
    ///
    /// A segment selector contains the following items:
    ///
    /// + *Requested Privilege Level (RPL)*: bits 0 and 1.
    ///    Specifies the privelege level of the selector.
    /// + *Table Indicator*: bit 2. Specifies which descriptor table to use.
    /// + *Index*: bits 3 through 15. Selects one of 8192 descriptors in the
    ///    GDT or LDT. The processor multiplies the index value by 8 (the number
    ///    of bytes in a segment descriptor) and adds the result to the base
    ///    address of the GDT or LDT (from the `%gdtr` or `%ldtr` register,
    ///    respectively).
    pub flags Selector: u16 { const RPL_RING_0 = 0b00
                            , const RPL_RING_1 = 0b01
                            , const RPL_RING_2 = 0b10
                            , const RPL_RING_3 = 0b11

                            , /// Requested Prrivelege Level (RPL)
                              const RPL = RPL_RING_0.bits
                               | RPL_RING_1.bits
                               | RPL_RING_2.bits
                               | RPL_RING_3.bits

                            , /// If the Table Indicator (TI) is 0, use the GDT
                              const TI_GDT = 0 << 3

                            , /// If the TI is 1, use the LDT
                              const TI_LDT = 1 << 3
                            }
}

impl Selector {
    /// Create a new `Selector`
    ///
    /// # Arguments:
    ///   - `index`: the index in the GDT or LDT
    pub const fn new(index: u16) -> Self {
        Selector { bits: index << 3 }
    }

    /// Create a new `Selector` from raw bits
    pub const fn from_raw(bits: u16) -> Self {
        Selector { bits: bits }
    }

    /// Returns the current value of the code segment register.
    pub fn from_cs() -> Self {
        let cs: u16;
        unsafe {
            asm!( "mov $0, cs"
                : "=r"(cs)
                ::: "intel" )
        };
        Selector::from_bits_truncate(cs)
    }

    /// Extracts the index from a segment selector
    #[inline] pub fn index(&self) -> u16 {
        self.bits >> 3
    }

    /// Sets this segment selector to be a GDT segment.
    ///
    /// If the segment is already a GDT segment, this will quietly do nothing.
    #[inline] pub fn set_global(&mut self) -> &mut Self {
        self.remove(TI_LDT);
        self
    }

    /// Sets this segment selector to be an LDT segment.
    ///
    /// If the segment is already an LDT segment, this will quietly do nothing.
    #[inline] pub fn set_local(&mut self) -> &mut Self {
        self.insert(TI_GDT);
        self
    }

    /// Sets the Requested Priveliege Level (RPL)
    ///
    /// The RPL must be in the range between 0 and 3.
    #[inline] pub fn set_rpl(&mut self, rpl: PrivilegeLevel) -> &mut Self {
        self.bits &= rpl as u16;
        self
    }

    /// Checks the segment's privelige.
    #[inline] pub fn get_rpl(&self) -> PrivilegeLevel {
        unsafe { mem::transmute(*self & RPL) }
    }

    /// Load this selector into the stack segment register (`ss`).
    pub unsafe fn load_ss(&self) {
        asm!(  "mov ss, $0"
            :: "r"(*self)
            :  "memory"
            :  "intel");
    }

    /// Load this selector into the data segment register (`ds`).
    pub unsafe fn load_ds(&self) {
        asm!(  "mov ds, $0"
            :: "r"(*self)
            :  "memory"
            :  "intel");
    }

    /// Load this selector into the `es` segment register.
    pub unsafe fn load_es(&self) {
        asm!(  "mov es, $0"
            :: "r"(*self)
            :  "memory"
            :  "intel");
    }

    /// Load this selector into the `fs` segment register.
    pub unsafe fn load_fs(&self) {
        asm!(  "mov fs, $0"
            :: "r"(*self)
            :  "memory"
            :  "intel");
    }

    /// Load this selector into the `gs` segment register.
    pub unsafe fn load_gs(&self) {
        asm!(  "mov gs, $0"
            :: "r"(*self)
            :  "memory"
            :  "intel");
    }

    /// Load this selector into the code segment register.
    ///
    /// N.B. that as we cannot `mov` directly to `cs`, we have to do this
    /// differently. We push the selector and return value onto the stack,
    /// and use `lret` to reload `cs`.
    #[cfg(target_arch = "x86_64")]
    pub unsafe fn load_cs(&self) {
        asm!(  "push $0
                lea rax, [rip + 1]
                push rax
                iret
                1:"
            :: "r"(self.bits as u64)
            :  "{rax}", "memory"
            :  "intel");
    }

}

impl fmt::Display for Selector {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // TODO: this could be much less ugly.
        let ring = if self.contains(RPL_RING_3) { "3" }
                   else if self.contains(RPL_RING_2) { "2" }
                   else if self.contains(RPL_RING_1) { "1" }
                   else if self.contains(RPL_RING_0) { "0" }
                   else { unreachable!() };
        let table = if self.contains(TI_GDT) { "GDT" }
                    else { "LDT" };
        write!(f, "Index {} in {} at Ring {}", self.index(), table, ring)
    }
}

/// A segment descriptor is an entry in an IDT or GDT.
///
/// A segment descriptor is a data structure in a GDT or LDT that provides the
/// processor with the size and location of a segment, as well as access control
/// and status information. Segment descriptors are typically created by
/// compilers, linkers, loaders, or the operating system or executive, but not
/// application programs.
///
#[repr(C, packed)]
pub struct Descriptor { /// The last 8 bits of the base address
                        pub base_high: u8
                      , /// The next 16 bits are bitflags
                        pub flags: Flags
                      , /// The middle 8 bits of the base address
                        pub base_mid: u8
                      , /// The first 16 bits of the base address
                        pub base_low: u16
                      , /// the segment limit
                        pub limit: u16
                      }

impl Descriptor {

    /// Constructs a new null `Descriptor`
    pub const fn null() -> Self {
        Descriptor { base_high: 0
                   , flags: Flags::null()
                   , base_mid: 0
                   , base_low: 0
                   , limit: 0
                   }
    }

    /// Constructs a new `Descriptor` from a `limit` and a `base` address
    pub fn new(base: u32, limit: u32) -> Self {
        let (hi, mid, lo): (u8, u8, u16) = unsafe { mem::transmute(base) };
        let (limit_lo, limit_hi): (u16, u16) = unsafe { mem::transmute(limit) };
        // I hope this is right...
        let flags = (limit_hi & 0b1111) << 8;

        Descriptor { base_high: hi
                   , flags: Flags::from_bits_truncate(flags)
                   , base_mid: mid
                   , base_low: lo
                   , limit: limit_lo
                   }
    }

    /// Extract the limit part from the flags and limit fields.
    #[inline]
    pub fn get_limit(&self) -> u32 {
        // TODO: i hope this is right...
        self.flags.get_limit_part() & self.limit as u32
    }

}

bitflags! {
    pub flags Flags: u16 {
        /// 1 if this is a code or data segment that has been accessed
        const CODE_DATA_ACC = 1 << 0
      , const SEGMENT_TYPE  = 0b0000_0000_0000_1111
      , const DESCR_TYPE    = 1 << 4
      , const DPL           = 0b0000_0000_0110_0000
      , const PRESENT       = 1 << 7
      , const LIMIT         = 0b0000_1111_0000_0000
      , const AVAILABLE     = 1 << 12
      , const LENGTH        = 1 << 13
      , const DEFAULT_SIZE  = 1 << 14
      , const GRANULARITY   = 1 << 15
      , /// If this is a code or data segment and the accessed bit is set,
        /// it has been accessed.
        const ACCESSED      = DESCR_TYPE.bits & CODE_DATA_ACC.bits
    }
}

impl Flags {

    const fn null() -> Self {
        Flags { bits: 0 }
    }

    /// Get the Descriptor Privilege Level (DPL) from the flags
    #[inline] pub fn get_dpl(&self) -> PrivilegeLevel {
        unsafe { mem::transmute((*self & DPL).bits >> 5) }
    }

    /// Returns true if this segment is a system segment.
    ///
    /// Returns false if it is a code or data segment.
    #[inline] pub fn is_system(&self) -> bool {
        !self.contains(DESCR_TYPE)
    }

    /// Returns false if this segment is present
    #[inline] pub fn is_present(&self) -> bool {
        !self.contains(PRESENT)
    }

    /// Returns false if this segment is available to system software
    #[inline] pub fn is_available(&self) -> bool {
        self.contains(AVAILABLE)
    }

    /// Returns true if this is a code or data segment that has been accessed.
    ///
    /// Returns false if it has not been accessed OR if it is a system segment.
    #[inline] pub fn is_accessed(&self) -> bool {
        self.contains(ACCESSED)
    }

    /// Returns the system type indicator, if this is a system segment.
    ///
    /// # Returns
    /// + `Some(SysType)` if this is a system segment
    /// + `None` if this is a code or data segment
    pub fn get_system_type(&self) -> Option<SysType> {
        if self.is_system() {
            Some(unsafe { mem::transmute((*self & SEGMENT_TYPE).bits) })
        } else {
            None
        }
    }

    /// Returns the code type indicator.
    ///
    /// # Returns
    /// + `Some(CodeType)` if this is not a system segment
    /// + `None` if this is a system segment
    pub fn get_code_type(&self) -> Option<CodeFlags> {
        if self.is_system() {
            None
        } else {
            Some(CodeFlags::from_bits_truncate(self.bits))
        }
    }

    /// Returns the data type indicator.
    ///
    /// # Returns
    /// + `Some(DataType)` if this is not a system segment
    /// + `None` if this is a system segment
    pub fn get_data_type(&self) -> Option<DataFlags> {
        if self.is_system() {
            None
        } else {
            Some(DataFlags::from_bits_truncate(self.bits))
        }
    }

    #[inline]
    fn get_limit_part(&self) -> u32 {
        ((*self & LIMIT).bits as u32) << 8
    }

}

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum Type { System(SysType)
              , Code(CodeFlags)
              , Data(DataFlags)
              }

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(u16)]
pub enum SysType { Ldt           = 0b0010
                 , TssAvailable  = 0b1001
                 , TssBusy       = 0b1011
                 , CallGate      = 0b1100
                 , InterruptGate = 0b1110
                 , TrapGate      = 0b1111
                 }

bitflags! {
    pub flags DataFlags: u16 {
        const DATA_ACCESSED = 0b0001
      , const WRITE         = 0b0010
      , const EXPAND_DOWN   = 0b0100
    }
}

impl DataFlags {
    /// Returns true if the data segment is read-only
    #[inline] pub fn is_read_only(&self) -> bool {
        !self.contains(WRITE)
    }

    /// Returns true if the data segment has been accessed
    #[inline] pub fn is_accessed(&self) -> bool {
        self.contains(DATA_ACCESSED)
    }

    /// Returns true if the data segment expands down
    #[inline] pub fn is_expand_down(&self) -> bool {
        self.contains(EXPAND_DOWN)
    }
}

bitflags! {
    pub flags CodeFlags: u16 {
        const CODE_ACCESSED = 0b0001
      , const READ          = 0b0010
      , const EXECUTE       = 0b1000
      , const CONFORMING    = 0b0100
      , const EXEC_ONLY     = EXECUTE.bits & !READ.bits
    }
}

impl CodeFlags {
    /// Returns true if the code segment is execute-only (not readable)
    #[inline] pub fn is_exec_only(&self) -> bool {
        self.contains(EXEC_ONLY)
    }

    /// Returns true if the code segment is readable
    #[inline] pub fn is_readable(&self) -> bool {
        self.contains(READ)
    }

    /// Returns true if the code segment has been accessed.
    #[inline] pub fn is_accessed(&self) -> bool {
        self.contains(CODE_ACCESSED)
    }

    /// Returns true if the code segment is conforming.
    #[inline] pub fn is_conforming(&self) -> bool {
        self.contains(CONFORMING)
    }
}
<commit_msg>[x86_all] fix changed clobber syntax<commit_after>//
//  SOS: the Stupid Operating System
//  by Hawk Weisman (hi@hawkweisman.me)
//
//  Copyright (c) 2015 Hawk Weisman
//  Released under the terms of the MIT license. See `LICENSE` in the root
//  directory of this repository for more information.
//
//! Code for using the `x86` and `x86_64` segmentation hardware.
//!
//! For more information, refer to the _Intel® 64 and IA-32 Architectures
//! Software Developer’s Manual_, Vol. 3A, section 3.2, "Using Segments".
//! Some of the documentation present in this module was taken from the Intel
//! manual.
use core::{fmt, mem};
use super::PrivilegeLevel;

bitflags! {
    /// A segment selector is a 16-bit identifier for a segment.
    ///
    /// It does not point directly to the segment, but instead points to the
    /// segment descriptor that defines the segment.
    ///
    /// A segment selector contains the following items:
    ///
    /// + *Requested Privilege Level (RPL)*: bits 0 and 1.
    ///    Specifies the privelege level of the selector.
    /// + *Table Indicator*: bit 2. Specifies which descriptor table to use.
    /// + *Index*: bits 3 through 15. Selects one of 8192 descriptors in the
    ///    GDT or LDT. The processor multiplies the index value by 8 (the number
    ///    of bytes in a segment descriptor) and adds the result to the base
    ///    address of the GDT or LDT (from the `%gdtr` or `%ldtr` register,
    ///    respectively).
    pub flags Selector: u16 { const RPL_RING_0 = 0b00
                            , const RPL_RING_1 = 0b01
                            , const RPL_RING_2 = 0b10
                            , const RPL_RING_3 = 0b11

                            , /// Requested Prrivelege Level (RPL)
                              const RPL = RPL_RING_0.bits
                               | RPL_RING_1.bits
                               | RPL_RING_2.bits
                               | RPL_RING_3.bits

                            , /// If the Table Indicator (TI) is 0, use the GDT
                              const TI_GDT = 0 << 3

                            , /// If the TI is 1, use the LDT
                              const TI_LDT = 1 << 3
                            }
}

impl Selector {
    /// Create a new `Selector`
    ///
    /// # Arguments:
    ///   - `index`: the index in the GDT or LDT
    pub const fn new(index: u16) -> Self {
        Selector { bits: index << 3 }
    }

    /// Create a new `Selector` from raw bits
    pub const fn from_raw(bits: u16) -> Self {
        Selector { bits: bits }
    }

    /// Returns the current value of the code segment register.
    pub fn from_cs() -> Self {
        let cs: u16;
        unsafe {
            asm!( "mov $0, cs"
                : "=r"(cs)
                ::: "intel" )
        };
        Selector::from_bits_truncate(cs)
    }

    /// Extracts the index from a segment selector
    #[inline] pub fn index(&self) -> u16 {
        self.bits >> 3
    }

    /// Sets this segment selector to be a GDT segment.
    ///
    /// If the segment is already a GDT segment, this will quietly do nothing.
    #[inline] pub fn set_global(&mut self) -> &mut Self {
        self.remove(TI_LDT);
        self
    }

    /// Sets this segment selector to be an LDT segment.
    ///
    /// If the segment is already an LDT segment, this will quietly do nothing.
    #[inline] pub fn set_local(&mut self) -> &mut Self {
        self.insert(TI_GDT);
        self
    }

    /// Sets the Requested Priveliege Level (RPL)
    ///
    /// The RPL must be in the range between 0 and 3.
    #[inline] pub fn set_rpl(&mut self, rpl: PrivilegeLevel) -> &mut Self {
        self.bits &= rpl as u16;
        self
    }

    /// Checks the segment's privelige.
    #[inline] pub fn get_rpl(&self) -> PrivilegeLevel {
        unsafe { mem::transmute(*self & RPL) }
    }

    /// Load this selector into the stack segment register (`ss`).
    pub unsafe fn load_ss(&self) {
        asm!(  "mov ss, $0"
            :: "r"(*self)
            :  "memory"
            :  "intel");
    }

    /// Load this selector into the data segment register (`ds`).
    pub unsafe fn load_ds(&self) {
        asm!(  "mov ds, $0"
            :: "r"(*self)
            :  "memory"
            :  "intel");
    }

    /// Load this selector into the `es` segment register.
    pub unsafe fn load_es(&self) {
        asm!(  "mov es, $0"
            :: "r"(*self)
            :  "memory"
            :  "intel");
    }

    /// Load this selector into the `fs` segment register.
    pub unsafe fn load_fs(&self) {
        asm!(  "mov fs, $0"
            :: "r"(*self)
            :  "memory"
            :  "intel");
    }

    /// Load this selector into the `gs` segment register.
    pub unsafe fn load_gs(&self) {
        asm!(  "mov gs, $0"
            :: "r"(*self)
            :  "memory"
            :  "intel");
    }

    /// Load this selector into the code segment register.
    ///
    /// N.B. that as we cannot `mov` directly to `cs`, we have to do this
    /// differently. We push the selector and return value onto the stack,
    /// and use `lret` to reload `cs`.
    #[cfg(target_arch = "x86_64")]
    pub unsafe fn load_cs(&self) {
        asm!(  "push $0
                lea rax, [rip + 1]
                push rax
                iret
                1:"
            :: "r"(self.bits as u64)
            :  "rax", "memory"
            :  "intel");
    }

}

impl fmt::Display for Selector {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        // TODO: this could be much less ugly.
        let ring = if self.contains(RPL_RING_3) { "3" }
                   else if self.contains(RPL_RING_2) { "2" }
                   else if self.contains(RPL_RING_1) { "1" }
                   else if self.contains(RPL_RING_0) { "0" }
                   else { unreachable!() };
        let table = if self.contains(TI_GDT) { "GDT" }
                    else { "LDT" };
        write!(f, "Index {} in {} at Ring {}", self.index(), table, ring)
    }
}

/// A segment descriptor is an entry in an IDT or GDT.
///
/// A segment descriptor is a data structure in a GDT or LDT that provides the
/// processor with the size and location of a segment, as well as access control
/// and status information. Segment descriptors are typically created by
/// compilers, linkers, loaders, or the operating system or executive, but not
/// application programs.
///
#[repr(C, packed)]
pub struct Descriptor { /// The last 8 bits of the base address
                        pub base_high: u8
                      , /// The next 16 bits are bitflags
                        pub flags: Flags
                      , /// The middle 8 bits of the base address
                        pub base_mid: u8
                      , /// The first 16 bits of the base address
                        pub base_low: u16
                      , /// the segment limit
                        pub limit: u16
                      }

impl Descriptor {

    /// Constructs a new null `Descriptor`
    pub const fn null() -> Self {
        Descriptor { base_high: 0
                   , flags: Flags::null()
                   , base_mid: 0
                   , base_low: 0
                   , limit: 0
                   }
    }

    /// Constructs a new `Descriptor` from a `limit` and a `base` address
    pub fn new(base: u32, limit: u32) -> Self {
        let (hi, mid, lo): (u8, u8, u16) = unsafe { mem::transmute(base) };
        let (limit_lo, limit_hi): (u16, u16) = unsafe { mem::transmute(limit) };
        // I hope this is right...
        let flags = (limit_hi & 0b1111) << 8;

        Descriptor { base_high: hi
                   , flags: Flags::from_bits_truncate(flags)
                   , base_mid: mid
                   , base_low: lo
                   , limit: limit_lo
                   }
    }

    /// Extract the limit part from the flags and limit fields.
    #[inline]
    pub fn get_limit(&self) -> u32 {
        // TODO: i hope this is right...
        self.flags.get_limit_part() & self.limit as u32
    }

}

bitflags! {
    pub flags Flags: u16 {
        /// 1 if this is a code or data segment that has been accessed
        const CODE_DATA_ACC = 1 << 0
      , const SEGMENT_TYPE  = 0b0000_0000_0000_1111
      , const DESCR_TYPE    = 1 << 4
      , const DPL           = 0b0000_0000_0110_0000
      , const PRESENT       = 1 << 7
      , const LIMIT         = 0b0000_1111_0000_0000
      , const AVAILABLE     = 1 << 12
      , const LENGTH        = 1 << 13
      , const DEFAULT_SIZE  = 1 << 14
      , const GRANULARITY   = 1 << 15
      , /// If this is a code or data segment and the accessed bit is set,
        /// it has been accessed.
        const ACCESSED      = DESCR_TYPE.bits & CODE_DATA_ACC.bits
    }
}

impl Flags {

    const fn null() -> Self {
        Flags { bits: 0 }
    }

    /// Get the Descriptor Privilege Level (DPL) from the flags
    #[inline] pub fn get_dpl(&self) -> PrivilegeLevel {
        unsafe { mem::transmute((*self & DPL).bits >> 5) }
    }

    /// Returns true if this segment is a system segment.
    ///
    /// Returns false if it is a code or data segment.
    #[inline] pub fn is_system(&self) -> bool {
        !self.contains(DESCR_TYPE)
    }

    /// Returns false if this segment is present
    #[inline] pub fn is_present(&self) -> bool {
        !self.contains(PRESENT)
    }

    /// Returns false if this segment is available to system software
    #[inline] pub fn is_available(&self) -> bool {
        self.contains(AVAILABLE)
    }

    /// Returns true if this is a code or data segment that has been accessed.
    ///
    /// Returns false if it has not been accessed OR if it is a system segment.
    #[inline] pub fn is_accessed(&self) -> bool {
        self.contains(ACCESSED)
    }

    /// Returns the system type indicator, if this is a system segment.
    ///
    /// # Returns
    /// + `Some(SysType)` if this is a system segment
    /// + `None` if this is a code or data segment
    pub fn get_system_type(&self) -> Option<SysType> {
        if self.is_system() {
            Some(unsafe { mem::transmute((*self & SEGMENT_TYPE).bits) })
        } else {
            None
        }
    }

    /// Returns the code type indicator.
    ///
    /// # Returns
    /// + `Some(CodeType)` if this is not a system segment
    /// + `None` if this is a system segment
    pub fn get_code_type(&self) -> Option<CodeFlags> {
        if self.is_system() {
            None
        } else {
            Some(CodeFlags::from_bits_truncate(self.bits))
        }
    }

    /// Returns the data type indicator.
    ///
    /// # Returns
    /// + `Some(DataType)` if this is not a system segment
    /// + `None` if this is a system segment
    pub fn get_data_type(&self) -> Option<DataFlags> {
        if self.is_system() {
            None
        } else {
            Some(DataFlags::from_bits_truncate(self.bits))
        }
    }

    #[inline]
    fn get_limit_part(&self) -> u32 {
        ((*self & LIMIT).bits as u32) << 8
    }

}

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
pub enum Type { System(SysType)
              , Code(CodeFlags)
              , Data(DataFlags)
              }

#[derive(Copy, Clone, Eq, PartialEq, Debug)]
#[repr(u16)]
pub enum SysType { Ldt           = 0b0010
                 , TssAvailable  = 0b1001
                 , TssBusy       = 0b1011
                 , CallGate      = 0b1100
                 , InterruptGate = 0b1110
                 , TrapGate      = 0b1111
                 }

bitflags! {
    pub flags DataFlags: u16 {
        const DATA_ACCESSED = 0b0001
      , const WRITE         = 0b0010
      , const EXPAND_DOWN   = 0b0100
    }
}

impl DataFlags {
    /// Returns true if the data segment is read-only
    #[inline] pub fn is_read_only(&self) -> bool {
        !self.contains(WRITE)
    }

    /// Returns true if the data segment has been accessed
    #[inline] pub fn is_accessed(&self) -> bool {
        self.contains(DATA_ACCESSED)
    }

    /// Returns true if the data segment expands down
    #[inline] pub fn is_expand_down(&self) -> bool {
        self.contains(EXPAND_DOWN)
    }
}

bitflags! {
    pub flags CodeFlags: u16 {
        const CODE_ACCESSED = 0b0001
      , const READ          = 0b0010
      , const EXECUTE       = 0b1000
      , const CONFORMING    = 0b0100
      , const EXEC_ONLY     = EXECUTE.bits & !READ.bits
    }
}

impl CodeFlags {
    /// Returns true if the code segment is execute-only (not readable)
    #[inline] pub fn is_exec_only(&self) -> bool {
        self.contains(EXEC_ONLY)
    }

    /// Returns true if the code segment is readable
    #[inline] pub fn is_readable(&self) -> bool {
        self.contains(READ)
    }

    /// Returns true if the code segment has been accessed.
    #[inline] pub fn is_accessed(&self) -> bool {
        self.contains(CODE_ACCESSED)
    }

    /// Returns true if the code segment is conforming.
    #[inline] pub fn is_conforming(&self) -> bool {
        self.contains(CONFORMING)
    }
}
<|endoftext|>


<commit_before><commit_msg>Add sra_r instruction<commit_after><|endoftext|>


<commit_before>use crate::utils::deserialize::deserialize_opt_duration;
use cosmogony::ZoneType;
use geojson::{GeoJson, Geometry};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::time::Duration;

use crate::adapters::primary::common::coord::Coord;
use crate::adapters::primary::common::filters::Filters;
use common::document::ContainerDocument;
use places::{addr::Addr, admin::Admin, poi::Poi, stop::Stop, street::Street, PlaceDocType};

pub const DEFAULT_LIMIT_RESULT_ES: i64 = 10;

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ForwardGeocoderExplainQuery {
    pub doc_id: String,
    pub doc_type: String,

    #[serde(flatten)]
    pub query: ForwardGeocoderQuery,
}

/// This structure contains all the query parameters that
/// can be submitted for the autocomplete endpoint.
///
/// Only the `q` parameter is mandatory.
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ForwardGeocoderQuery {
    pub q: String,
    pub lat: Option<f32>,
    pub lon: Option<f32>,
    pub shape_scope: Option<Vec<PlaceDocType>>,
    #[serde(default, rename = "type")]
    pub types: Option<Vec<Type>>,
    #[serde(default, rename = "zone_type")]
    pub zone_types: Option<Vec<ZoneType>>,
    pub poi_types: Option<Vec<String>>,
    #[serde(default = "default_result_limit")]
    pub limit: i64,
    #[serde(deserialize_with = "deserialize_opt_duration", default)]
    pub timeout: Option<Duration>,
    pub pt_dataset: Option<Vec<String>>,
    pub poi_dataset: Option<Vec<String>>,
    pub request_id: Option<String>,
    #[serde(flatten)]
    pub proximity: Option<Proximity>,
}

fn default_result_limit() -> i64 {
    DEFAULT_LIMIT_RESULT_ES
}

impl From<(ForwardGeocoderQuery, Option<Geometry>)> for Filters {
    fn from(source: (ForwardGeocoderQuery, Option<Geometry>)) -> Self {
        let (query, geometry) = source;
        let zone_types = query
            .zone_types
            .map(|zts| zts.iter().map(|t| t.as_str().to_string()).collect());
        Filters {
            // When option_zip_option becomes available: coord: input.lat.zip_with(input.lon, Coord::new),
            coord: match (query.lat, query.lon) {
                (Some(lat), Some(lon)) => Some(Coord::new(lat, lon)),
                _ => None,
            },
            shape: geometry.map(|geometry| {
                (
                    geometry,
                    query
                        .shape_scope
                        .map(|shape_scope| {
                            shape_scope.iter().map(|t| t.as_str().to_string()).collect()
                        })
                        .unwrap_or_else(|| {
                            vec![
                                Type::House,
                                Type::Poi,
                                Type::StopArea,
                                Type::Street,
                                Type::Zone,
                            ]
                            .iter()
                            .map(|t| t.as_str().to_string())
                            .collect()
                        }),
                )
            }),
            zone_types,
            poi_types: query.poi_types,
            limit: query.limit,
            timeout: query.timeout,
            proximity: query.proximity,
        }
    }
}

/// This structure contains all the query parameters that
/// can be submitted for the features endpoint.
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct FeaturesQuery {
    pub pt_dataset: Option<Vec<String>>,
    pub poi_dataset: Option<Vec<String>>,
    #[serde(deserialize_with = "deserialize_opt_duration")]
    pub timeout: Option<Duration>,
}

/// This structure contains all the query parameters that
/// can be submitted for the reverse endpoint.
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ReverseGeocoderQuery {
    pub lat: f64,
    pub lon: f64,
    #[serde(default = "default_result_limit")]
    pub limit: i64,
    #[serde(deserialize_with = "deserialize_opt_duration")]
    pub timeout: Option<Duration>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct JsonParam {
    pub shape: GeoJson,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ExplainResponseBody {
    pub explanation: JsonValue,
}

impl From<JsonValue> for ExplainResponseBody {
    fn from(explanation: JsonValue) -> Self {
        ExplainResponseBody { explanation }
    }
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct BragiStatus {
    pub version: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct MimirStatus {
    pub version: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ElasticsearchStatus {
    pub version: String,
    pub health: String,
    pub url: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct StatusResponseBody {
    pub bragi: BragiStatus,
    pub mimir: MimirStatus,
    pub elasticsearch: ElasticsearchStatus,
}

/// This macro is used to define the forward_geocoder route.
/// It takes a client (ElasticsearchStorage) and query settings
/// It can be either a GET request, with query parameters,
/// or a POST request, with both query parameters and a GeoJson shape
/// in the body.
#[macro_export]
macro_rules! forward_geocoder {
    ($cl:expr, $st:expr) => {
        routes::forward_geocoder_get()
            .or(routes::forward_geocoder_post())
            .unify()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::forward_geocoder)
    };
}

pub use forward_geocoder;

#[macro_export]
macro_rules! forward_geocoder_explain {
    ($cl:expr, $st:expr) => {
        routes::forward_geocoder_explain_get()
            .or(routes::forward_geocoder_explain_post())
            .unify()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::forward_geocoder_explain)
    };
}
pub use forward_geocoder_explain;

#[macro_export]
macro_rules! reverse_geocoder {
    ($cl:expr, $st:expr) => {
        routes::reverse_geocoder()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::reverse_geocoder)
    };
}
pub use reverse_geocoder;

#[macro_export]
macro_rules! features {
    ($cl:expr, $st:expr) => {
        routes::features()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::features)
    };
}
pub use features;

#[macro_export]
macro_rules! status {
    ($cl:expr, $es:expr) => {
        routes::status()
            .and(routes::with_client($cl))
            .and(routes::with_elasticsearch($es))
            .and_then(handlers::status)
    };
}
pub use status;

#[derive(PartialEq, Copy, Clone, Debug, Deserialize, Serialize)]
pub enum Type {
    #[serde(rename = "house")]
    House,
    #[serde(rename = "poi")]
    Poi,
    #[serde(rename = "public_transport:stop_area")]
    StopArea,
    #[serde(rename = "street")]
    Street,
    #[serde(rename = "zone")]
    Zone,
    // TODO To be deleted when switching to full ES7 (in production)
    #[serde(rename = "city")]
    City,
}

impl Type {
    pub fn as_str(&self) -> &'static str {
        match self {
            Type::House => "house",
            Type::Poi => "poi",
            Type::StopArea => "public_transport:stop_area",
            Type::Street => "street",
            Type::Zone => "zone",
            Type::City => "city",
        }
    }

    pub fn as_index_type(&self) -> &'static str {
        match self {
            Type::House => Addr::static_doc_type(),
            Type::Poi => Poi::static_doc_type(),
            Type::StopArea => Stop::static_doc_type(),
            Type::Street => Street::static_doc_type(),
            Type::Zone | Type::City => Admin::static_doc_type(),
        }
    }
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Proximity {
    #[serde(with = "serde_with::rust::display_fromstr")]
    #[serde(rename = "proximity_scale")]
    pub scale: f64,
    #[serde(with = "serde_with::rust::display_fromstr")]
    #[serde(rename = "proximity_offset")]
    pub offset: f64,
    #[serde(with = "serde_with::rust::display_fromstr")]
    #[serde(rename = "proximity_decay")]
    pub decay: f64,
}
<commit_msg>Fix optional timeout param<commit_after>use crate::utils::deserialize::deserialize_opt_duration;
use cosmogony::ZoneType;
use geojson::{GeoJson, Geometry};
use serde::{Deserialize, Serialize};
use serde_json::Value as JsonValue;
use std::time::Duration;

use crate::adapters::primary::common::coord::Coord;
use crate::adapters::primary::common::filters::Filters;
use common::document::ContainerDocument;
use places::{addr::Addr, admin::Admin, poi::Poi, stop::Stop, street::Street, PlaceDocType};

pub const DEFAULT_LIMIT_RESULT_ES: i64 = 10;

#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ForwardGeocoderExplainQuery {
    pub doc_id: String,
    pub doc_type: String,

    #[serde(flatten)]
    pub query: ForwardGeocoderQuery,
}

/// This structure contains all the query parameters that
/// can be submitted for the autocomplete endpoint.
///
/// Only the `q` parameter is mandatory.
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ForwardGeocoderQuery {
    pub q: String,
    pub lat: Option<f32>,
    pub lon: Option<f32>,
    pub shape_scope: Option<Vec<PlaceDocType>>,
    #[serde(default, rename = "type")]
    pub types: Option<Vec<Type>>,
    #[serde(default, rename = "zone_type")]
    pub zone_types: Option<Vec<ZoneType>>,
    pub poi_types: Option<Vec<String>>,
    #[serde(default = "default_result_limit")]
    pub limit: i64,
    #[serde(deserialize_with = "deserialize_opt_duration", default)]
    pub timeout: Option<Duration>,
    pub pt_dataset: Option<Vec<String>>,
    pub poi_dataset: Option<Vec<String>>,
    pub request_id: Option<String>,
    #[serde(flatten)]
    pub proximity: Option<Proximity>,
}

fn default_result_limit() -> i64 {
    DEFAULT_LIMIT_RESULT_ES
}

impl From<(ForwardGeocoderQuery, Option<Geometry>)> for Filters {
    fn from(source: (ForwardGeocoderQuery, Option<Geometry>)) -> Self {
        let (query, geometry) = source;
        let zone_types = query
            .zone_types
            .map(|zts| zts.iter().map(|t| t.as_str().to_string()).collect());
        Filters {
            // When option_zip_option becomes available: coord: input.lat.zip_with(input.lon, Coord::new),
            coord: match (query.lat, query.lon) {
                (Some(lat), Some(lon)) => Some(Coord::new(lat, lon)),
                _ => None,
            },
            shape: geometry.map(|geometry| {
                (
                    geometry,
                    query
                        .shape_scope
                        .map(|shape_scope| {
                            shape_scope.iter().map(|t| t.as_str().to_string()).collect()
                        })
                        .unwrap_or_else(|| {
                            vec![
                                Type::House,
                                Type::Poi,
                                Type::StopArea,
                                Type::Street,
                                Type::Zone,
                            ]
                            .iter()
                            .map(|t| t.as_str().to_string())
                            .collect()
                        }),
                )
            }),
            zone_types,
            poi_types: query.poi_types,
            limit: query.limit,
            timeout: query.timeout,
            proximity: query.proximity,
        }
    }
}

/// This structure contains all the query parameters that
/// can be submitted for the features endpoint.
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct FeaturesQuery {
    pub pt_dataset: Option<Vec<String>>,
    pub poi_dataset: Option<Vec<String>>,
    #[serde(deserialize_with = "deserialize_opt_duration", default)]
    pub timeout: Option<Duration>,
}

/// This structure contains all the query parameters that
/// can be submitted for the reverse endpoint.
#[derive(Debug, Default, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ReverseGeocoderQuery {
    pub lat: f64,
    pub lon: f64,
    #[serde(default = "default_result_limit")]
    pub limit: i64,
    #[serde(deserialize_with = "deserialize_opt_duration", default)]
    pub timeout: Option<Duration>,
}

#[derive(Serialize, Deserialize, Debug, Clone)]
pub struct JsonParam {
    pub shape: GeoJson,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ExplainResponseBody {
    pub explanation: JsonValue,
}

impl From<JsonValue> for ExplainResponseBody {
    fn from(explanation: JsonValue) -> Self {
        ExplainResponseBody { explanation }
    }
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct BragiStatus {
    pub version: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct MimirStatus {
    pub version: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct ElasticsearchStatus {
    pub version: String,
    pub health: String,
    pub url: String,
}

#[derive(Debug, Serialize, Deserialize)]
#[serde(rename_all = "snake_case")]
pub struct StatusResponseBody {
    pub bragi: BragiStatus,
    pub mimir: MimirStatus,
    pub elasticsearch: ElasticsearchStatus,
}

/// This macro is used to define the forward_geocoder route.
/// It takes a client (ElasticsearchStorage) and query settings
/// It can be either a GET request, with query parameters,
/// or a POST request, with both query parameters and a GeoJson shape
/// in the body.
#[macro_export]
macro_rules! forward_geocoder {
    ($cl:expr, $st:expr) => {
        routes::forward_geocoder_get()
            .or(routes::forward_geocoder_post())
            .unify()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::forward_geocoder)
    };
}

pub use forward_geocoder;

#[macro_export]
macro_rules! forward_geocoder_explain {
    ($cl:expr, $st:expr) => {
        routes::forward_geocoder_explain_get()
            .or(routes::forward_geocoder_explain_post())
            .unify()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::forward_geocoder_explain)
    };
}
pub use forward_geocoder_explain;

#[macro_export]
macro_rules! reverse_geocoder {
    ($cl:expr, $st:expr) => {
        routes::reverse_geocoder()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::reverse_geocoder)
    };
}
pub use reverse_geocoder;

#[macro_export]
macro_rules! features {
    ($cl:expr, $st:expr) => {
        routes::features()
            .and(routes::with_client($cl))
            .and(routes::with_settings($st))
            .and_then(handlers::features)
    };
}
pub use features;

#[macro_export]
macro_rules! status {
    ($cl:expr, $es:expr) => {
        routes::status()
            .and(routes::with_client($cl))
            .and(routes::with_elasticsearch($es))
            .and_then(handlers::status)
    };
}
pub use status;

#[derive(PartialEq, Copy, Clone, Debug, Deserialize, Serialize)]
pub enum Type {
    #[serde(rename = "house")]
    House,
    #[serde(rename = "poi")]
    Poi,
    #[serde(rename = "public_transport:stop_area")]
    StopArea,
    #[serde(rename = "street")]
    Street,
    #[serde(rename = "zone")]
    Zone,
    // TODO To be deleted when switching to full ES7 (in production)
    #[serde(rename = "city")]
    City,
}

impl Type {
    pub fn as_str(&self) -> &'static str {
        match self {
            Type::House => "house",
            Type::Poi => "poi",
            Type::StopArea => "public_transport:stop_area",
            Type::Street => "street",
            Type::Zone => "zone",
            Type::City => "city",
        }
    }

    pub fn as_index_type(&self) -> &'static str {
        match self {
            Type::House => Addr::static_doc_type(),
            Type::Poi => Poi::static_doc_type(),
            Type::StopArea => Stop::static_doc_type(),
            Type::Street => Street::static_doc_type(),
            Type::Zone | Type::City => Admin::static_doc_type(),
        }
    }
}

#[derive(Clone, Debug, Deserialize, Serialize)]
pub struct Proximity {
    #[serde(with = "serde_with::rust::display_fromstr")]
    #[serde(rename = "proximity_scale")]
    pub scale: f64,
    #[serde(with = "serde_with::rust::display_fromstr")]
    #[serde(rename = "proximity_offset")]
    pub offset: f64,
    #[serde(with = "serde_with::rust::display_fromstr")]
    #[serde(rename = "proximity_decay")]
    pub decay: f64,
}
<|endoftext|>


<commit_before><commit_msg>Change max string length to a constant expression<commit_after><|endoftext|>


<commit_before><commit_msg>Improve process name retrieval<commit_after><|endoftext|>


<commit_before><commit_msg>llrb: Add assertions about tree invariants.<commit_after><|endoftext|>


<commit_before><commit_msg>Add blanket implementation for CommunicatorExt.<commit_after><|endoftext|>