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

use std::io;
use specs::{Class, ClassField};

use common;
use common::domain::{Domain, DomainMapper};

type Field<'a> = common::Field<'a, ClassField>;

pub struct HeaderStructWriter<'a> {
    fields: Vec<Field<'a>>,
    has_lifetimes: bool,
}

impl<'a> HeaderStructWriter<'a> {
    pub fn new(class: &'a Class,domain_mapper: &DomainMapper) -> Self {
        let fields = class.fields().iter()
            .map(|field| {
                let ty = Domain::new(domain_mapper.map(field.domain()));
                Field::from_amqp0_field(field, ty)
            })
            .collect::<Vec<_>>();

        let has_lifetimes = fields.iter()
            .map(|f| !f.ty().is_copy())
            .any(|is_copy| is_copy);

        HeaderStructWriter {
            fields: fields,
            has_lifetimes: has_lifetimes,
        }
    }

    pub fn write_to<W>(&self, writer: &mut W) -> io::Result<()>
        where W: io::Write
    {
        try!(self.write_struct(writer));
        try!(self.write_inherent_impl(writer));
        // try!(self.write_amqp0_payload_impl(writer));
        // try!(self.write_nom_bytes_impl(writer));

        Ok(())
    }

    pub fn write_struct<W>(&self, writer: &mut W) -> io::Result<()>
        where W: io::Write
    {
        if self.fields.is_empty() {
            try!(writeln!(writer, "pub struct Header;"));
            return Ok(());
        }

        let lifetimes = if self.has_lifetimes { "<'a>" } else { "" };

        try!(writeln!(writer, "pub struct Header{} {{", lifetimes));
        for field in &self.fields {
            try!(writeln!(writer, "{}: Option<{}>,", field.var_name(), field.ty().cow_definition("a")));
        }
        try!(writeln!(writer, "}} // struct Header"));
        Ok(())
    }

    pub fn write_inherent_impl<W>(&self, writer: &mut W) -> io::Result<()>
        where W: io::Write
    {
        if self.fields.is_empty() {
            return Ok(());
        }

        let lifetimes = if self.has_lifetimes { "<'a>" } else { "" };

        try!(writeln!(writer, "\nimpl{0} Header{0} {{", lifetimes));
        try!(self.write_getters(writer));
        try!(writeln!(writer, "}} // impl Headers"));

        Ok(())
    }

    pub fn write_getters<W>(&self, writer: &mut W) -> io::Result<()>
        where W: io::Write
    {
        if self.fields.is_empty() {
            return Ok(());
        }

        try!(writeln!(writer, "impl_properties! {{"));
        for field in &self.fields {
            try!(write!(writer, "({0}, {0}_mut, set_{0}, take_{0}) -> ", field.var_name()));

            let ty = field.ty().borrowed_type();
            try!(match (field.ty().is_copy(), field.ty().is_owned()) {
                (true, _) => writeln!(writer, "Option<{}>,", ty),
                (_, true) => writeln!(writer, "Option<&{}>,", ty),
                _ => writeln!(writer, "Option< Cow<{}> >,", ty)
            });
        }
        try!(writeln!(writer, "}} // impl_properties"));

        Ok(())
    }
}
<commit_msg>[primitives] Add spacing to avoid the macro system parsing >> as an operator.<commit_after>// Copyright 2016 Alexander Reece
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::io;
use specs::{Class, ClassField};

use common;
use common::domain::{Domain, DomainMapper};

type Field<'a> = common::Field<'a, ClassField>;

pub struct HeaderStructWriter<'a> {
    fields: Vec<Field<'a>>,
    has_lifetimes: bool,
}

impl<'a> HeaderStructWriter<'a> {
    pub fn new(class: &'a Class,domain_mapper: &DomainMapper) -> Self {
        let fields = class.fields().iter()
            .map(|field| {
                let ty = Domain::new(domain_mapper.map(field.domain()));
                Field::from_amqp0_field(field, ty)
            })
            .collect::<Vec<_>>();

        let has_lifetimes = fields.iter()
            .map(|f| !f.ty().is_copy())
            .any(|is_copy| is_copy);

        HeaderStructWriter {
            fields: fields,
            has_lifetimes: has_lifetimes,
        }
    }

    pub fn write_to<W>(&self, writer: &mut W) -> io::Result<()>
        where W: io::Write
    {
        try!(self.write_struct(writer));
        try!(self.write_inherent_impl(writer));
        // try!(self.write_amqp0_payload_impl(writer));
        // try!(self.write_nom_bytes_impl(writer));

        Ok(())
    }

    pub fn write_struct<W>(&self, writer: &mut W) -> io::Result<()>
        where W: io::Write
    {
        if self.fields.is_empty() {
            try!(writeln!(writer, "pub struct Header;"));
            return Ok(());
        }

        let lifetimes = if self.has_lifetimes { "<'a>" } else { "" };

        try!(writeln!(writer, "pub struct Header{} {{", lifetimes));
        for field in &self.fields {
            try!(writeln!(writer, "{}: Option<{}>,", field.var_name(), field.ty().cow_definition("a")));
        }
        try!(writeln!(writer, "}} // struct Header"));
        Ok(())
    }

    pub fn write_inherent_impl<W>(&self, writer: &mut W) -> io::Result<()>
        where W: io::Write
    {
        if self.fields.is_empty() {
            return Ok(());
        }

        let lifetimes = if self.has_lifetimes { "<'a>" } else { "" };

        try!(writeln!(writer, "\nimpl{0} Header{0} {{", lifetimes));
        try!(self.write_getters(writer));
        try!(writeln!(writer, "}} // impl Headers"));

        Ok(())
    }

    pub fn write_getters<W>(&self, writer: &mut W) -> io::Result<()>
        where W: io::Write
    {
        if self.fields.is_empty() {
            return Ok(());
        }

        try!(writeln!(writer, "impl_properties! {{"));
        for field in &self.fields {
            try!(write!(writer, "({0}, {0}_mut, set_{0}, take_{0}) -> ", field.var_name()));

            let ty = field.ty().borrowed_type();
            try!(match (field.ty().is_copy(), field.ty().is_owned()) {
                (true, _) => writeln!(writer, "Option< {} >,", ty),
                (_, true) => writeln!(writer, "Option< &{} >,", ty),
                _ => writeln!(writer, "Option< Cow<{}> >,", ty)
            });
        }
        try!(writeln!(writer, "}} // impl_properties"));

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


<commit_before>extern crate syntex_syntax;

use std::fs::File;
use std::io;
use std::path::Path;

use syntex_syntax::ast;
use syntex_syntax::attr;
use syntex_syntax::codemap::{DUMMY_SP, respan};
use syntex_syntax::ext::base::{
    IdentMacroExpander,
    MultiItemDecorator,
    MultiItemModifier,
    NamedSyntaxExtension,
    SyntaxExtension,
    TTMacroExpander,
};
use syntex_syntax::ext::expand;
use syntex_syntax::feature_gate;
use syntex_syntax::parse::{self, token};
use syntex_syntax::print::{pp, pprust};
use syntex_syntax::ptr::P;

pub type Pass = fn(ast::Crate) -> ast::Crate;

pub struct Registry {
    macros: Vec<ast::MacroDef>,
    syntax_exts: Vec<NamedSyntaxExtension>,
    pre_expansion_passes: Vec<Box<Pass>>,
    post_expansion_passes: Vec<Box<Pass>>,
    cfg: Vec<P<ast::MetaItem>>,
    attrs: Vec<ast::Attribute>,
}

impl Registry {
    pub fn new() -> Registry {
        Registry {
            macros: Vec::new(),
            syntax_exts: Vec::new(),
            pre_expansion_passes: Vec::new(),
            post_expansion_passes: Vec::new(),
            cfg: Vec::new(),
            attrs: Vec::new(),
        }
    }

    pub fn add_cfg(&mut self, cfg: &str) {
        let meta_item = parse::parse_meta_from_source_str(
            "cfgspec".to_string(),
            cfg.to_string(),
            Vec::new(),
            &parse::ParseSess::new());

        self.cfg.push(meta_item);
    }

    pub fn add_attr(&mut self, attr: &str) {
        let meta_item = parse::parse_meta_from_source_str(
            "attrspec".to_string(),
            attr.to_string(),
            Vec::new(),
            &parse::ParseSess::new());

        self.attrs.push(respan(DUMMY_SP, ast::Attribute_ {
            id: attr::mk_attr_id(),
            style: ast::AttrOuter,
            value: meta_item,
            is_sugared_doc: false,
        }));
    }

    pub fn add_macro<F>(&mut self, name: &str, extension: F)
        where F: TTMacroExpander + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::NormalTT(
            Box::new(extension),
            None,
            false
        );
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn add_ident_macro<F>(&mut self, name: &str, extension: F)
        where F: IdentMacroExpander + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::IdentTT(
            Box::new(extension),
            None,
            false
        );
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn add_decorator<F>(&mut self, name: &str, extension: F)
        where F: MultiItemDecorator + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::MultiDecorator(Box::new(extension));
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn add_modifier<F>(&mut self, name: &str, extension: F)
        where F: MultiItemModifier + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::MultiModifier(Box::new(extension));
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn add_pre_expansion_pass(&mut self, pass: Pass) {
        self.pre_expansion_passes.push(Box::new(pass))
    }

    pub fn add_post_expansion_pass(&mut self, pass: Pass) {
        self.post_expansion_passes.push(Box::new(pass))
    }

    pub fn expand(self, crate_name: &str, src: &Path, dst: &Path) -> io::Result<()> {
        let sess = parse::ParseSess::new();

        let mut krate = parse::parse_crate_from_file(
            src,
            self.cfg,
            &sess);

        krate.attrs.extend(self.attrs);

        let features = feature_gate::check_crate_macros(
            &sess.span_diagnostic.cm,
            &sess.span_diagnostic,
            &krate);

        let krate = self.pre_expansion_passes.iter()
            .fold(krate, |krate, f| (f)(krate));

        let mut ecfg = expand::ExpansionConfig::default(crate_name.to_string());
        ecfg.features = Some(&features);

        let krate = expand::expand_crate(
            &sess,
            ecfg,
            self.macros,
            self.syntax_exts,
            &mut Vec::new(),
            krate);

        let krate = self.post_expansion_passes.iter()
            .fold(krate, |krate, f| (f)(krate));

        let dst = try!(File::create(dst));

        let mut printer = pprust::rust_printer(Box::new(dst));
        try!(printer.print_mod(&krate.module, &krate.attrs[..]));
        try!(printer.print_remaining_comments());
        pp::eof(&mut printer.s)
    }
}
<commit_msg>chore(syntex): Update for latest syntex_syntax<commit_after>extern crate syntex_syntax;

use std::fs::File;
use std::io;
use std::path::Path;

use syntex_syntax::ast;
use syntex_syntax::attr;
use syntex_syntax::codemap::{DUMMY_SP, respan};
use syntex_syntax::ext::base::{
    IdentMacroExpander,
    MultiItemDecorator,
    MultiItemModifier,
    NamedSyntaxExtension,
    SyntaxExtension,
    TTMacroExpander,
};
use syntex_syntax::ext::expand;
use syntex_syntax::feature_gate;
use syntex_syntax::parse::{self, token};
use syntex_syntax::print::{pp, pprust};
use syntex_syntax::ptr::P;

pub type Pass = fn(ast::Crate) -> ast::Crate;

pub struct Registry {
    macros: Vec<ast::MacroDef>,
    syntax_exts: Vec<NamedSyntaxExtension>,
    pre_expansion_passes: Vec<Box<Pass>>,
    post_expansion_passes: Vec<Box<Pass>>,
    cfg: Vec<P<ast::MetaItem>>,
    attrs: Vec<ast::Attribute>,
}

impl Registry {
    pub fn new() -> Registry {
        Registry {
            macros: Vec::new(),
            syntax_exts: Vec::new(),
            pre_expansion_passes: Vec::new(),
            post_expansion_passes: Vec::new(),
            cfg: Vec::new(),
            attrs: Vec::new(),
        }
    }

    pub fn add_cfg(&mut self, cfg: &str) {
        let meta_item = parse::parse_meta_from_source_str(
            "cfgspec".to_string(),
            cfg.to_string(),
            Vec::new(),
            &parse::ParseSess::new());

        self.cfg.push(meta_item);
    }

    pub fn add_attr(&mut self, attr: &str) {
        let meta_item = parse::parse_meta_from_source_str(
            "attrspec".to_string(),
            attr.to_string(),
            Vec::new(),
            &parse::ParseSess::new());

        self.attrs.push(respan(DUMMY_SP, ast::Attribute_ {
            id: attr::mk_attr_id(),
            style: ast::AttrStyle::Outer,
            value: meta_item,
            is_sugared_doc: false,
        }));
    }

    pub fn add_macro<F>(&mut self, name: &str, extension: F)
        where F: TTMacroExpander + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::NormalTT(
            Box::new(extension),
            None,
            false
        );
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn add_ident_macro<F>(&mut self, name: &str, extension: F)
        where F: IdentMacroExpander + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::IdentTT(
            Box::new(extension),
            None,
            false
        );
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn add_decorator<F>(&mut self, name: &str, extension: F)
        where F: MultiItemDecorator + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::MultiDecorator(Box::new(extension));
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn add_modifier<F>(&mut self, name: &str, extension: F)
        where F: MultiItemModifier + 'static
    {
        let name = token::intern(name);
        let syntax_extension = SyntaxExtension::MultiModifier(Box::new(extension));
        self.syntax_exts.push((name, syntax_extension));
    }

    pub fn add_pre_expansion_pass(&mut self, pass: Pass) {
        self.pre_expansion_passes.push(Box::new(pass))
    }

    pub fn add_post_expansion_pass(&mut self, pass: Pass) {
        self.post_expansion_passes.push(Box::new(pass))
    }

    pub fn expand(self, crate_name: &str, src: &Path, dst: &Path) -> io::Result<()> {
        let sess = parse::ParseSess::new();

        let mut krate = parse::parse_crate_from_file(
            src,
            self.cfg,
            &sess);

        krate.attrs.extend(self.attrs);

        let features = feature_gate::check_crate_macros(
            &sess.span_diagnostic.cm,
            &sess.span_diagnostic,
            &krate);

        let krate = self.pre_expansion_passes.iter()
            .fold(krate, |krate, f| (f)(krate));

        let mut ecfg = expand::ExpansionConfig::default(crate_name.to_string());
        ecfg.features = Some(&features);

        let krate = expand::expand_crate(
            &sess,
            ecfg,
            self.macros,
            self.syntax_exts,
            &mut Vec::new(),
            krate);

        let krate = self.post_expansion_passes.iter()
            .fold(krate, |krate, f| (f)(krate));

        let dst = try!(File::create(dst));

        let mut printer = pprust::rust_printer(Box::new(dst));
        try!(printer.print_mod(&krate.module, &krate.attrs[..]));
        try!(printer.print_remaining_comments());
        pp::eof(&mut printer.s)
    }
}
<|endoftext|>


<commit_before>use authentication::Authentication;
use config::Config;
use http_headers::*;
use hyper::client::Body;
use hyper::client::Response as HyperResponse;
use hyper::Client as HyperClient;
use hyper::header::{Accept, ContentType, qitem};
use hyper::method::Method;
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::client::IntoUrl;
use std::io::Error as IoError;
use std::io::Read;
use serde_json;
use serde::ser::Serialize;
use serde::de::Deserialize;

#[doc(no_inline)]
pub use serde_json::error::Error as SerdeError;

#[doc(no_inline)]
pub use hyper::error::Error as HyperError;

pub use url::ParseError as UrlError;

#[derive(Debug,Clone)]
pub struct ApiClient {
    pub config: Config,
}

#[derive(Debug)]
pub enum Error {
    UnsuccessfulResponse(Response),
    Json(SerdeError),
    Hyper(HyperError),
    Url(UrlError),
}

impl From<HyperError> for Error {
    fn from(h: HyperError) -> Error {
        Error::Hyper(h)
    }
}

impl From<IoError> for Error {
    fn from(i: IoError) -> Error {
        Error::Hyper(HyperError::Io(i))
    }
}

impl From<UrlError> for Error {
    fn from(u: UrlError) -> Error {
        Error::Url(u)
    }
}

#[derive(Debug)]
pub struct Response {
    pub hyper_response: HyperResponse,
    pub body: String,
}

impl Response {
    fn from_hyper_response(mut hyper_response: HyperResponse) -> Result<Response, IoError> {
        let mut body = String::new();
        hyper_response.read_to_string(&mut body).map(|_| {
            Response {
                hyper_response: hyper_response,
                body: body,
            }
        })
    }

    pub fn from_json<T: Deserialize>(&self) -> Result<T, Error> {
        serde_json::from_str(&*self.body).map_err(|e| Error::Json(e))
    }
}

impl ApiClient {

    pub fn new(config: Config) -> ApiClient {
        ApiClient { config: config }
    }

    pub fn from_json_config(pth: &str) -> ApiClient {
        let cfg = Config::from_json(pth);
        ApiClient::new(cfg)
    }

    pub fn config(mut self, config: Config) -> ApiClient {
        self.config = config;
        self
    }

    pub fn get(&self, path: &str) -> Result<Response, Error> {
        let userid = &self.config.user.clone().unwrap();

        let auth = Authentication::new();
        let auth = auth.path(path);
        let auth = auth.key(self.config.keypath.clone().unwrap().as_ref());
        let auth = auth.method("get");
        let auth = auth.userid(userid.as_ref());

        let url = try!(format!("{}{}", &self.config.url_base(), path).into_url());
        debug!("In get, URL is {:?}", url);
        let client = HyperClient::new();
        let client = client.request(Method::Get, url);
        let headers = auth.as_headers();
        let mut headers = headers.clone();

        let json = Mime(TopLevel::Application, SubLevel::Json, vec![]);
        headers.set(Accept(vec![qitem(json.clone())]));
        headers.set(ContentType(json));
        headers.set(OpsApiInfo(1));
        headers.set(ChefVersion(String::from("12.5.1")));

        let client = client.headers(headers);

        let resp = try!(client.send());
        let resp = try!(Response::from_hyper_response(resp));

        if resp.hyper_response.status.is_success() {
            Ok(resp)
        } else {
            Err(Error::UnsuccessfulResponse(resp))
        }
    }

    pub fn put<B>(&self, path: &str, body: B) -> Result<Response, Error>
        where B: Serialize
    {
        let userid = &self.config.user.clone().unwrap();

        let auth = Authentication::new();
        let auth = auth.path(path);
        let auth = auth.key(self.config.keypath.clone().unwrap().as_ref());
        let auth = auth.method("put");
        let auth = auth.userid(userid.as_ref());

        let url = try!(format!("{}{}", &self.config.url_base(), path).into_url());
        debug!("In get, URL is {:?}", url);

        let body = try!(serde_json::to_string(&body).map_err(|e| Error::Json(e)));

        let auth = auth.body(body.as_ref());

        let client = HyperClient::new();
        let client = client.request(Method::Put, url);
        let client = client.body(body.as_bytes());

        let headers = auth.as_headers();
        let mut headers = headers.clone();

        let json = Mime(TopLevel::Application, SubLevel::Json, vec![]);
        headers.set(Accept(vec![qitem(json.clone())]));
        headers.set(ContentType(json));
        headers.set(OpsApiInfo(1));
        headers.set(ChefVersion(String::from("12.5.1")));

        let client = client.headers(headers);

        let resp = try!(client.send());
        let resp = try!(Response::from_hyper_response(resp));

        if resp.hyper_response.status.is_success() {
            Ok(resp)
        } else {
            Err(Error::UnsuccessfulResponse(resp))
        }
    }

}
<commit_msg>trash a big pile of cut'n'paste code<commit_after>use authentication::Authentication;
use config::Config;
use http_headers::*;
use hyper::client::Response as HyperResponse;
use hyper::Client as HyperClient;
use hyper::header::{Accept, ContentType, qitem};
use hyper::method::Method;
use hyper::mime::{Mime, TopLevel, SubLevel};
use hyper::client::IntoUrl;
use std::io::Error as IoError;
use std::io::Read;
use serde_json;
use serde::ser::Serialize;
use serde::de::Deserialize;

#[doc(no_inline)]
pub use serde_json::error::Error as SerdeError;

#[doc(no_inline)]
pub use hyper::error::Error as HyperError;

pub use url::ParseError as UrlError;

#[derive(Debug,Clone)]
pub struct ApiClient {
    pub config: Config,
}

#[derive(Debug)]
pub enum Error {
    UnsuccessfulResponse(Response),
    Json(SerdeError),
    Hyper(HyperError),
    Url(UrlError),
}

impl From<HyperError> for Error {
    fn from(h: HyperError) -> Error {
        Error::Hyper(h)
    }
}

impl From<IoError> for Error {
    fn from(i: IoError) -> Error {
        Error::Hyper(HyperError::Io(i))
    }
}

impl From<UrlError> for Error {
    fn from(u: UrlError) -> Error {
        Error::Url(u)
    }
}

#[derive(Debug)]
pub struct Response {
    pub hyper_response: HyperResponse,
    pub body: String,
}

impl Response {
    fn from_hyper_response(mut hyper_response: HyperResponse) -> Result<Response, IoError> {
        let mut body = String::new();
        hyper_response.read_to_string(&mut body).map(|_| {
            Response {
                hyper_response: hyper_response,
                body: body,
            }
        })
    }

    pub fn from_json<T: Deserialize>(&self) -> Result<T, Error> {
        serde_json::from_str(&*self.body).map_err(|e| Error::Json(e))
    }
}

impl ApiClient {

    pub fn new(config: Config) -> ApiClient {
        ApiClient { config: config }
    }

    pub fn from_json_config(pth: &str) -> ApiClient {
        let cfg = Config::from_json(pth);
        ApiClient::new(cfg)
    }

    pub fn config(mut self, config: Config) -> ApiClient {
        self.config = config;
        self
    }

    pub fn get(&self, path: &str) -> Result<Response, Error> {
        self.send_with_body(path, "", "get")
    }

    pub fn put<B>(&self, path: &str, body: B) -> Result<Response, Error>
        where B: Serialize
    {
        let body = try!(serde_json::to_string(&body).map_err(|e| Error::Json(e)));
        self.send_with_body(path, body.as_ref(), "put")
    }

    fn send_with_body(&self, path: &str, body: &str, method: &str) -> Result<Response, Error> {
        let userid = &self.config.user.clone().unwrap();

        let auth = Authentication::new();
        let auth = auth.path(path);
        let auth = auth.key(self.config.keypath.clone().unwrap().as_ref());
        let auth = auth.method(method);
        let auth = auth.userid(userid.as_ref());

        let url = try!(format!("{}{}", &self.config.url_base(), path).into_url());

        let auth = auth.body(body.as_ref());

        let mth = match method {
            "put" => Method::Put,
            "post" => Method::Post,
            "delete" => Method::Delete,
            "head" => Method::Head,
            _ => Method::Get,
        };

        let client = HyperClient::new();
        let client = client.request(mth, url);
        let client = client.body(body.as_bytes());

        let headers = auth.as_headers();
        let mut headers = headers.clone();

        let json = Mime(TopLevel::Application, SubLevel::Json, vec![]);
        headers.set(Accept(vec![qitem(json.clone())]));
        headers.set(ContentType(json));
        headers.set(OpsApiInfo(1));
        headers.set(ChefVersion(String::from("12.5.1")));

        let client = client.headers(headers);

        let resp = try!(client.send());
        let resp = try!(Response::from_hyper_response(resp));

        if resp.hyper_response.status.is_success() {
            Ok(resp)
        } else {
            Err(Error::UnsuccessfulResponse(resp))
        }
    }

}
<|endoftext|>


<commit_before>/* AES-128 CBC mode
 *
 * Dmitry Vasiliev <dima@hlabs.org>
 */

extern crate serialize;

extern crate aes_lib;

use std::path::Path;
use std::io::fs::File;
use std::iter::repeat;

use serialize::base64::FromBase64;

use aes_lib::{decrypt_aes_cbc, encrypt_aes_cbc};

fn read_hex_file(path: &Path) -> Vec<u8> {
    match File::open(path) {
        Ok(mut file) => {
            let data = file.read_to_end().unwrap();
            let text = String::from_utf8(data).unwrap();
            text.from_base64().unwrap()
        },
        Err(err) => panic!("Unable to open {}: {}", path.display(), err)
    }
}

/*
 * Main entry point
 */
fn main() {
    let path = Path::new("10.txt");
    let data = read_hex_file(&path);
    let key = b"YELLOW SUBMARINE";
    let iv: Vec<u8> = repeat(0u8).take(16).collect();
    let decrypted = decrypt_aes_cbc(data.as_slice(), key.as_slice(),
                                    iv.as_slice());
    println!("Decrypted => \"{}\"",
             String::from_utf8(decrypted.clone()).unwrap());
    assert_eq!(data, encrypt_aes_cbc(decrypted.as_slice(), key.as_slice(),
                                     iv.as_slice()));
    println!("Encryption OK!");
}
<commit_msg>Replace repeat() with static array<commit_after>/* AES-128 CBC mode
 *
 * Dmitry Vasiliev <dima@hlabs.org>
 */

extern crate serialize;

extern crate aes_lib;

use std::path::Path;
use std::io::fs::File;

use serialize::base64::FromBase64;

use aes_lib::{decrypt_aes_cbc, encrypt_aes_cbc};

fn read_hex_file(path: &Path) -> Vec<u8> {
    match File::open(path) {
        Ok(mut file) => {
            let data = file.read_to_end().unwrap();
            let text = String::from_utf8(data).unwrap();
            text.from_base64().unwrap()
        },
        Err(err) => panic!("Unable to open {}: {}", path.display(), err)
    }
}

/*
 * Main entry point
 */
fn main() {
    let path = Path::new("10.txt");
    let data = read_hex_file(&path);
    let key = b"YELLOW SUBMARINE";
    let iv: Vec<u8> = [0u8; 16].to_vec();
    let decrypted = decrypt_aes_cbc(data.as_slice(), key.as_slice(),
                                    iv.as_slice());
    println!("Decrypted => \"{}\"",
             String::from_utf8(decrypted.clone()).unwrap());
    assert_eq!(data, encrypt_aes_cbc(decrypted.as_slice(), key.as_slice(),
                                     iv.as_slice()));
    println!("Encryption OK!");
}
<|endoftext|>


<commit_before>use std::{
    error::Error as StdError,
    fmt::{self, Display},
    str::FromStr,
};

use mime::Mime;

use super::{Header, HeaderName};
use crate::BoxError;

/// `Content-Type` of the body
///
/// Defined in [RFC2045](https://tools.ietf.org/html/rfc2045#section-5)
#[derive(Debug, Clone, PartialEq)]
pub struct ContentType(Mime);

impl ContentType {
    /// A `ContentType` of type `text/plain; charset=utf-8`
    ///
    /// Indicates that the body is in utf-8 encoded plain text.
    pub const TEXT_PLAIN: ContentType = Self::from_mime(mime::TEXT_PLAIN_UTF_8);

    /// A `ContentType` of type `text/html; charset=utf-8`
    ///
    /// Indicates that the body is in utf-8 encoded html.
    pub const TEXT_HTML: ContentType = Self::from_mime(mime::TEXT_HTML_UTF_8);

    /// Parse `s` into `ContentType`
    pub fn parse(s: &str) -> Result<ContentType, ContentTypeErr> {
        Ok(Self::from_mime(s.parse().map_err(ContentTypeErr)?))
    }

    pub(crate) const fn from_mime(mime: Mime) -> Self {
        Self(mime)
    }

    pub(crate) fn as_ref(&self) -> &Mime {
        &self.0
    }
}

impl Header for ContentType {
    fn name() -> HeaderName {
        HeaderName::new_from_ascii_str("Content-Type")
    }

    fn parse(s: &str) -> Result<Self, BoxError> {
        Ok(Self(s.parse()?))
    }

    fn display(&self) -> String {
        self.0.to_string()
    }
}

impl FromStr for ContentType {
    type Err = ContentTypeErr;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Self::parse(s)
    }
}

/// An error occurred while trying to [`ContentType::parse`].
#[derive(Debug)]
pub struct ContentTypeErr(mime::FromStrError);

impl StdError for ContentTypeErr {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        Some(&self.0)
    }
}

impl Display for ContentTypeErr {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        Display::fmt(&self.0, f)
    }
}

#[cfg(test)]
mod test {
    use super::ContentType;
    use crate::message::header::{HeaderName, Headers};

    #[test]
    fn format_content_type() {
        let mut headers = Headers::new();

        headers.set(ContentType::TEXT_PLAIN);

        assert_eq!(
            headers.to_string(),
            "Content-Type: text/plain; charset=utf-8\r\n"
        );

        headers.set(ContentType::TEXT_HTML);

        assert_eq!(
            headers.to_string(),
            "Content-Type: text/html; charset=utf-8\r\n"
        );
    }

    #[test]
    fn parse_content_type() {
        let mut headers = Headers::new();

        headers.insert_raw(
            HeaderName::new_from_ascii_str("Content-Type"),
            "text/plain; charset=utf-8".to_string(),
        );

        assert_eq!(headers.get::<ContentType>(), Some(ContentType::TEXT_PLAIN));

        headers.insert_raw(
            HeaderName::new_from_ascii_str("Content-Type"),
            "text/html; charset=utf-8".to_string(),
        );

        assert_eq!(headers.get::<ContentType>(), Some(ContentType::TEXT_HTML));
    }
}
<commit_msg>Implement Serialize and Deserialize for ContentType (#643)<commit_after>use std::{
    error::Error as StdError,
    fmt::{self, Display},
    str::FromStr,
};

use mime::Mime;

use super::{Header, HeaderName};
use crate::BoxError;

/// `Content-Type` of the body
///
/// Defined in [RFC2045](https://tools.ietf.org/html/rfc2045#section-5)
#[derive(Debug, Clone, PartialEq, Eq)]
pub struct ContentType(Mime);

impl ContentType {
    /// A `ContentType` of type `text/plain; charset=utf-8`
    ///
    /// Indicates that the body is in utf-8 encoded plain text.
    pub const TEXT_PLAIN: ContentType = Self::from_mime(mime::TEXT_PLAIN_UTF_8);

    /// A `ContentType` of type `text/html; charset=utf-8`
    ///
    /// Indicates that the body is in utf-8 encoded html.
    pub const TEXT_HTML: ContentType = Self::from_mime(mime::TEXT_HTML_UTF_8);

    /// Parse `s` into `ContentType`
    pub fn parse(s: &str) -> Result<ContentType, ContentTypeErr> {
        Ok(Self::from_mime(s.parse().map_err(ContentTypeErr)?))
    }

    pub(crate) const fn from_mime(mime: Mime) -> Self {
        Self(mime)
    }

    pub(crate) fn as_ref(&self) -> &Mime {
        &self.0
    }
}

impl Header for ContentType {
    fn name() -> HeaderName {
        HeaderName::new_from_ascii_str("Content-Type")
    }

    fn parse(s: &str) -> Result<Self, BoxError> {
        Ok(Self(s.parse()?))
    }

    fn display(&self) -> String {
        self.0.to_string()
    }
}

impl FromStr for ContentType {
    type Err = ContentTypeErr;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        Self::parse(s)
    }
}

/// An error occurred while trying to [`ContentType::parse`].
#[derive(Debug)]
pub struct ContentTypeErr(mime::FromStrError);

impl StdError for ContentTypeErr {
    fn source(&self) -> Option<&(dyn StdError + 'static)> {
        Some(&self.0)
    }
}

impl Display for ContentTypeErr {
    fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
        Display::fmt(&self.0, f)
    }
}

// --------------------------------------
// Serialization and Deserialization
// --------------------------------------
#[cfg(feature = "serde")]
mod serde {
    use serde::de::{self, Deserialize, Deserializer, Visitor};
    use serde::ser::{Serialize, Serializer};

    use std::fmt;

    use super::ContentType;

    impl Serialize for ContentType {
        fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
        where
            S: Serializer,
        {
            serializer.serialize_newtype_struct("ContentType", &format!("{}", &self.0))
        }
    }

    impl<'de> Deserialize<'de> for ContentType {
        fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
        where
            D: Deserializer<'de>,
        {
            struct ContentTypeVisitor;

            impl<'de> Visitor<'de> for ContentTypeVisitor {
                type Value = ContentType;

                // The error message which states what the Visitor expects to
                // receive
                fn expecting(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
                    formatter.write_str("a ContentType string like `text/plain`")
                }

                fn visit_str<E>(self, mime: &str) -> Result<ContentType, E>
                where
                    E: de::Error,
                {
                    match ContentType::parse(mime) {
                        Ok(content_type) => Ok(content_type),
                        Err(_) => Err(E::custom(format!(
                            "Couldn't parse the following MIME-Type: {}",
                            mime
                        ))),
                    }
                }
            }

            deserializer.deserialize_str(ContentTypeVisitor)
        }
    }
}

#[cfg(test)]
mod test {
    use super::ContentType;
    use crate::message::header::{HeaderName, Headers};

    #[test]
    fn format_content_type() {
        let mut headers = Headers::new();

        headers.set(ContentType::TEXT_PLAIN);

        assert_eq!(
            headers.to_string(),
            "Content-Type: text/plain; charset=utf-8\r\n"
        );

        headers.set(ContentType::TEXT_HTML);

        assert_eq!(
            headers.to_string(),
            "Content-Type: text/html; charset=utf-8\r\n"
        );
    }

    #[test]
    fn parse_content_type() {
        let mut headers = Headers::new();

        headers.insert_raw(
            HeaderName::new_from_ascii_str("Content-Type"),
            "text/plain; charset=utf-8".to_string(),
        );

        assert_eq!(headers.get::<ContentType>(), Some(ContentType::TEXT_PLAIN));

        headers.insert_raw(
            HeaderName::new_from_ascii_str("Content-Type"),
            "text/html; charset=utf-8".to_string(),
        );

        assert_eq!(headers.get::<ContentType>(), Some(ContentType::TEXT_HTML));
    }
}
<|endoftext|>


<commit_before>struct Stack {
    content: Vec<i32>,
}

impl Stack {
    fn push(&mut self, d: i32) {
        self.content.push(d);
    }

    fn multiply(&mut self) {
        let r = self.content.pop().expect("Stack empty!");
        let l = self.content.pop().expect("Stack empty!");

        self.content.push(l * r);
    }

    fn add(&mut self) {
        let r = self.content.pop().expect("Stack empty!");
        let l = self.content.pop().expect("Stack empty!");

        self.content.push(l + r);
    }

    fn subtract(&mut self) {
        let r = self.content.pop().expect("Stack empty!");
        let l = self.content.pop().expect("Stack empty!");

        self.content.push(l - r);
    }

    fn divide(&mut self) {
        let r = self.content.pop().expect("Stack empty!");
        let l = self.content.pop().expect("Stack empty!");

        self.content.push(l / r);
    }
}

fn evaluate(program: Vec<char>) {
    let mut stack = Stack { content: vec![] };

    for c in program {
        match c {
            '*' => stack.multiply(),
            '+' => stack.add(),
            '-' => stack.subtract(),
            '/' => stack.divide(),
            '1' => stack.push(1),
            '2' => stack.push(2),
            '3' => stack.push(3),
            '4' => stack.push(4),
            '5' => stack.push(5),
            '6' => stack.push(6),
            '7' => stack.push(7),
            '8' => stack.push(8),
            '9' => stack.push(9),
            _   => println!("DIE..."),
        }
    }

    for c in stack.content {
        println!("{}", c);
    }
}

fn main() {
    let program: Vec<char> = "3 4 * 2 * 1 /".chars().filter(|&c| c != ' ').collect();

    evaluate(program);
}
<commit_msg>Only one more compile error left<commit_after>struct Stack {
    content: Vec<u32>,
}

impl Stack {
    fn push(&mut self, d: u32) -> Result<u32, &str> {
        self.content.push(d);
        Ok(d);
    }

    fn pop(&mut self) -> u32 {
        self.content.pop().expect("Stack empty!")
    }

    fn addDigit(&mut self, c: char) -> Result<u32, &str> {
        let d = c.to_digit(10);

        match d {
            Some(n) => self.push(n),
            None    => Err("Invalid character"),
        }
    }

    fn multiply(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        self.push(l * r);
    }

    fn add(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        self.push(l + r);
    }

    fn subtract(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        self.push(l - r);
    }

    fn divide(&mut self) -> Result<u32, &str> {
        let r = self.pop();
        let l = self.pop();

        self.push(l / r);
    }
}

fn evaluate(program: Vec<char>) {
    let mut stack = Stack { content: vec![] };

    for c in program {
        let answer: Result<u32, &str> = match c {
            '*' => stack.multiply(),
            '+' => stack.add(),
            '-' => stack.subtract(),
            '/' => stack.divide(),
            _   => stack.addDigit(c),
        };

        match answer {
            Ok(n) => continue,
            Err(e) => {
                println!("{}", e);
                break;
            }
        };
    }

    for c in stack.content {
        println!("{}", c);
    }
}

fn main() {
    let program: Vec<char> = "3 4 * 2 * 1 /".chars().filter(|&c| c != ' ').collect();

    evaluate(program);
}
<|endoftext|>


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

//! Starts a service from an installed Habitat package.
//!
//! Services run by the Supervisor support one or more *topologies*, which are state machines that
//! handle the lifecycle of a service; they are members of a *group*, which is a namespace for
//! their configuration and state.
//!
//! # Examples
//!
//! ```bash
//! $ hab-sup start acme/redis
//! ```
//!
//! Will start the `redis` service in the `default` group, using the `standalone` topology.
//!
//! ```bash
//! $ hab-sup start acme/redis -g production
//! ```
//!
//! Will do the same, but in the `production` group.
//!
//! ```bash
//! $ hab-sup start acme/redis -t leader
//! ```
//!
//! Will start the `redis` service using the `leader` topology.
//!
//! ```bash
//! $ hab-sup start acme/redis -t leader -g production
//! ```
//!
//! Will start the `redis` service using the `leader` topology in the `production` group.
//!
//! See the [documentation on topologies](../topology) for a deeper discussion of how they function.
//!

use std;
use std::path::Path;

use ansi_term::Colour::Yellow;
use common;
use common::ui::UI;
use hcore::fs::{self, FS_ROOT_PATH};

use {PRODUCT, VERSION};
use error::{Error, Result};
use feat;
use manager::{Manager, ManagerConfig};
use manager::ServiceSpec;

static LOGKEY: &'static str = "CS";

pub fn package(cfg: ManagerConfig,
               service_spec: Option<ServiceSpec>,
               local_artifact: Option<&str>)
               -> Result<()> {
    let mut ui = UI::default();
    if !fs::am_i_root() {
        ui.warn("Running the Habitat Supervisor with root or superuser privileges is recommended")?;
        ui.br()?;
    }

    // TODO fn: once we remove the `Multi` feature flag a refactoring of this function will clean
    // things up substantially. If it looks slightly awkward, this was done with an eye to the end
    // state, not this intermediate state. Cheers!

    if let Some(spec) = service_spec.as_ref() {
        if let Some(artifact) = local_artifact {
            outputln!("Installing local artifact {}",
                      Yellow.bold().paint(artifact));
            common::command::package::install::start(&mut ui,
                                                     &spec.depot_url,
                                                     artifact,
                                                     PRODUCT,
                                                     VERSION,
                                                     Path::new(&*FS_ROOT_PATH),
                                                     &fs::cache_artifact_path(None),
                                                     false)?;
        }
    }

    if feat::is_enabled(feat::Multi) {
        if let Some(spec) = service_spec {
            // If we're starting with a package, then we assume that any prior specs are out of
            // date.  TODO fn: there are some assumptions to be tested here...
            let specs_path = Manager::specs_path_for(&cfg);
            if specs_path.exists() && specs_path.is_dir() {
                std::fs::remove_dir_all(specs_path)?;
            }
            Manager::save_spec_for(&cfg, spec)?;
        }

        let mut manager = Manager::load(cfg)?;
        manager.run()
    } else {
        let mut manager = Manager::load(cfg)?;
        if let Some(spec) = service_spec {
            manager.add_service(spec)?;
        }
        manager.run()
    }
}
<commit_msg>removes unused import Error from the start command<commit_after>// Copyright (c) 2016-2017 Chef Software Inc. and/or applicable contributors
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
//     http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.

//! Starts a service from an installed Habitat package.
//!
//! Services run by the Supervisor support one or more *topologies*, which are state machines that
//! handle the lifecycle of a service; they are members of a *group*, which is a namespace for
//! their configuration and state.
//!
//! # Examples
//!
//! ```bash
//! $ hab-sup start acme/redis
//! ```
//!
//! Will start the `redis` service in the `default` group, using the `standalone` topology.
//!
//! ```bash
//! $ hab-sup start acme/redis -g production
//! ```
//!
//! Will do the same, but in the `production` group.
//!
//! ```bash
//! $ hab-sup start acme/redis -t leader
//! ```
//!
//! Will start the `redis` service using the `leader` topology.
//!
//! ```bash
//! $ hab-sup start acme/redis -t leader -g production
//! ```
//!
//! Will start the `redis` service using the `leader` topology in the `production` group.
//!
//! See the [documentation on topologies](../topology) for a deeper discussion of how they function.
//!

use std;
use std::path::Path;

use ansi_term::Colour::Yellow;
use common;
use common::ui::UI;
use hcore::fs::{self, FS_ROOT_PATH};

use {PRODUCT, VERSION};
use error::Result;
use feat;
use manager::{Manager, ManagerConfig};
use manager::ServiceSpec;

static LOGKEY: &'static str = "CS";

pub fn package(cfg: ManagerConfig,
               service_spec: Option<ServiceSpec>,
               local_artifact: Option<&str>)
               -> Result<()> {
    let mut ui = UI::default();
    if !fs::am_i_root() {
        ui.warn("Running the Habitat Supervisor with root or superuser privileges is recommended")?;
        ui.br()?;
    }

    // TODO fn: once we remove the `Multi` feature flag a refactoring of this function will clean
    // things up substantially. If it looks slightly awkward, this was done with an eye to the end
    // state, not this intermediate state. Cheers!

    if let Some(spec) = service_spec.as_ref() {
        if let Some(artifact) = local_artifact {
            outputln!("Installing local artifact {}",
                      Yellow.bold().paint(artifact));
            common::command::package::install::start(&mut ui,
                                                     &spec.depot_url,
                                                     artifact,
                                                     PRODUCT,
                                                     VERSION,
                                                     Path::new(&*FS_ROOT_PATH),
                                                     &fs::cache_artifact_path(None),
                                                     false)?;
        }
    }

    if feat::is_enabled(feat::Multi) {
        if let Some(spec) = service_spec {
            // If we're starting with a package, then we assume that any prior specs are out of
            // date.  TODO fn: there are some assumptions to be tested here...
            let specs_path = Manager::specs_path_for(&cfg);
            if specs_path.exists() && specs_path.is_dir() {
                std::fs::remove_dir_all(specs_path)?;
            }
            Manager::save_spec_for(&cfg, spec)?;
        }

        let mut manager = Manager::load(cfg)?;
        manager.run()
    } else {
        let mut manager = Manager::load(cfg)?;
        if let Some(spec) = service_spec {
            manager.add_service(spec)?;
        }
        manager.run()
    }
}
<|endoftext|>


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

//! Implementation of ElasticSearch [highlight](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html)

use std::collections::HashMap;

use serde::ser::{Serialize, Serializer};

macro_rules! serialize_enum {
    ($n:ident) => (
        impl Serialize for $n {
            fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
                where S: Serializer {

                self.to_string().serialize(serializer)
            }
        }
    )
}

#[derive(Debug, Clone)]
pub enum SettingTypes {
    Plain,
    FVH,
    Postings
}

impl ToString for SettingTypes {
    fn to_string(&self) -> String {
        match self {
            &SettingTypes::Plain    => "plain",
            &SettingTypes::FVH      => "fvh",
            &SettingTypes::Postings => "postings"
        }.to_owned()
    }
}

serialize_enum!(SettingTypes);

#[derive(Debug, Clone)]
pub enum IndexOptions {
    Offsets
}

impl ToString for IndexOptions {
    fn to_string(&self) -> String {
        match self {
            &IndexOptions::Offsets => "offsets"
        }.to_owned()
    }
}

serialize_enum!(IndexOptions);

#[derive(Debug, Clone)]
pub enum TermVector {
    WithPositionsOffsets,
    BoundaryChars,
    BoundaryMaxScan,
}

impl ToString for TermVector {
    fn to_string(&self) -> String {
        match self {
            &TermVector::WithPositionsOffsets => "with_positions_offsets",
            &TermVector::BoundaryChars        => "boundary_chars",
            &TermVector::BoundaryMaxScan      => "boundary_max_scan"
        }.to_owned()
    }
}

serialize_enum!(TermVector);

#[derive(Debug, Serialize, Clone)]
pub struct Setting {
    #[serde(rename="type")]
    pub setting_type: Option<SettingTypes>,
    pub index_options: Option<IndexOptions>,
    pub term_vector: Option<TermVector>,
    pub force_source: bool,
    pub fragment_size: u32,
    pub number_of_fragments: u32,
    pub no_match_size: u32,
    pub matched_fields: Vec<String>
}

impl Setting {
    pub fn new() -> Setting {
        Setting {
            setting_type: None,
            index_options: None,
            term_vector: None,
            force_source: false,
            fragment_size: 150,
            number_of_fragments: 5,
            no_match_size: 0,
            matched_fields: vec![]
        }
    }

    pub fn with_type(&mut self, setting_type: SettingTypes) -> &mut Setting {
        self.setting_type = Some(setting_type);
        self
    }

    pub fn with_index_options(&mut self, index_options: IndexOptions) -> &mut Setting {
        self.index_options = Some(index_options);
        self
    }

    pub fn with_term_vector(&mut self, term_vector: TermVector) -> &mut Setting {
        self.term_vector = Some(term_vector);
        self
    }

    pub fn with_force_source(&mut self, force_source: bool) -> &mut Setting {
        self.force_source = force_source;
        self
    }

    pub fn with_fragment_size(&mut self, fragment_size: u32) -> &mut Setting {
        self.fragment_size = fragment_size;
        self
    }

    pub fn with_number_of_fragments(&mut self, number_of_fragments: u32) -> &mut Setting {
        self.number_of_fragments = number_of_fragments;
        self
    }

    pub fn with_no_match_size(&mut self, no_match_size: u32) -> &mut Setting {
        self.no_match_size = no_match_size;
        self
    }

    pub fn with_matched_fields<'a>(&mut self, matched_fields: Vec<String>) -> &mut Setting {
        self.matched_fields = matched_fields;
        self
    }
}

#[derive(Debug, Serialize)]
pub struct Highlight {
    pub fields: HashMap<String, Setting>
}

impl Highlight {
    /// Create an Highlight entity without any field or setting
    /// specified as they are supposed to be added via the `add`
    /// method.
    ///
    /// # Examples
    ///
    /// ```
    /// use rs_es::operations::search::highlight::{Highlight, Setting, SettingTypes};
    ///
    /// let mut highlight = Highlight::new();
    /// let setting = Setting::new().with_type(SettingTypes::Plain).to_owned();
    /// highlight.add("first_name".to_owned(), setting);
    /// ```
    pub fn new() -> Highlight {
        Highlight { fields: HashMap::new() }
    }

    /// Add a field to highlight to the set
    pub fn add(&mut self, name: String, setting: Setting) {
        self.fields.insert(name, setting);
    }
}

/// The fields containing found terms
pub type HighlightResult = HashMap<String, Vec<String>>;
<commit_msg>Add support to encoders and tags to Highlight<commit_after>/*
 * Copyright 2015-2016 Ben Ashford
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

//! Implementation of ElasticSearch [highlight](https://www.elastic.co/guide/en/elasticsearch/reference/current/search-request-highlighting.html)

use std::collections::HashMap;

use serde::ser::{Serialize, Serializer};

macro_rules! serialize_enum {
    ($n:ident) => (
        impl Serialize for $n {
            fn serialize<S>(&self, serializer: &mut S) -> Result<(), S::Error>
                where S: Serializer {

                self.to_string().serialize(serializer)
            }
        }
    )
}

#[derive(Debug, Clone)]
pub enum Encoders {
    Default,
    HTML
}

impl ToString for Encoders {
    fn to_string(&self) -> String {
        match self {
            &Encoders::Default => "default",
            &Encoders::HTML    => "html"
        }.to_owned()
    }
}

serialize_enum!(Encoders);

#[derive(Debug, Clone)]
pub enum SettingTypes {
    Plain,
    FVH,
    Postings
}

impl ToString for SettingTypes {
    fn to_string(&self) -> String {
        match self {
            &SettingTypes::Plain    => "plain",
            &SettingTypes::FVH      => "fvh",
            &SettingTypes::Postings => "postings"
        }.to_owned()
    }
}

serialize_enum!(SettingTypes);

#[derive(Debug, Clone)]
pub enum IndexOptions {
    Offsets
}

impl ToString for IndexOptions {
    fn to_string(&self) -> String {
        match self {
            &IndexOptions::Offsets => "offsets"
        }.to_owned()
    }
}

serialize_enum!(IndexOptions);

#[derive(Debug, Clone)]
pub enum TermVector {
    WithPositionsOffsets,
    BoundaryChars,
    BoundaryMaxScan,
}

impl ToString for TermVector {
    fn to_string(&self) -> String {
        match self {
            &TermVector::WithPositionsOffsets => "with_positions_offsets",
            &TermVector::BoundaryChars        => "boundary_chars",
            &TermVector::BoundaryMaxScan      => "boundary_max_scan"
        }.to_owned()
    }
}

serialize_enum!(TermVector);

#[derive(Debug, Serialize, Clone)]
pub struct Setting {
    #[serde(rename="type")]
    pub setting_type: Option<SettingTypes>,
    pub index_options: Option<IndexOptions>,
    pub term_vector: Option<TermVector>,
    pub force_source: bool,
    pub fragment_size: u32,
    pub number_of_fragments: u32,
    pub no_match_size: u32,
    pub matched_fields: Option<Vec<String>>
}

impl Setting {
    pub fn new() -> Setting {
        Setting {
            setting_type: None,
            index_options: None,
            term_vector: None,
            force_source: false,
            fragment_size: 150,
            number_of_fragments: 5,
            no_match_size: 0,
            matched_fields: None
        }
    }

    pub fn with_type(&mut self, setting_type: SettingTypes) -> &mut Setting {
        self.setting_type = Some(setting_type);
        self
    }

    pub fn with_index_options(&mut self, index_options: IndexOptions) -> &mut Setting {
        self.index_options = Some(index_options);
        self
    }

    pub fn with_term_vector(&mut self, term_vector: TermVector) -> &mut Setting {
        self.term_vector = Some(term_vector);
        self
    }

    pub fn with_force_source(&mut self, force_source: bool) -> &mut Setting {
        self.force_source = force_source;
        self
    }

    pub fn with_fragment_size(&mut self, fragment_size: u32) -> &mut Setting {
        self.fragment_size = fragment_size;
        self
    }

    pub fn with_number_of_fragments(&mut self, number_of_fragments: u32) -> &mut Setting {
        self.number_of_fragments = number_of_fragments;
        self
    }

    pub fn with_no_match_size(&mut self, no_match_size: u32) -> &mut Setting {
        self.no_match_size = no_match_size;
        self
    }

    pub fn with_matched_fields(&mut self, matched_fields: Vec<String>) -> &mut Setting {
        self.matched_fields = Some(matched_fields);
        self
    }
}

#[derive(Debug, Serialize, Clone)]
pub struct Highlight {
    pub fields: HashMap<String, Setting>,
    pub pre_tags: Option<Vec<String>>,
    pub post_tags: Option<Vec<String>>,
    pub encoder: Option<Encoders>
}

impl Highlight {
    /// Create an Highlight entity without any field or setting
    /// specified as they are supposed to be added via the `add`
    /// method.
    ///
    /// # Examples
    ///
    /// ```
    /// use rs_es::operations::search::highlight::{Highlight, Setting, SettingTypes, Encoders};
    ///
    /// let mut highlight = Highlight::new().with_encoder(Encoders::HTML).to_owned();
    /// let setting = Setting::new().with_type(SettingTypes::Plain).to_owned();
    /// highlight.add("first_name".to_owned(), setting);
    /// ```
    pub fn new() -> Highlight {
        Highlight {
            fields: HashMap::new(),
            pre_tags: None,
            post_tags: None,
            encoder: None
        }
    }

    pub fn with_encoder(&mut self, encoder: Encoders) -> &mut Highlight {
        self.encoder = Some(encoder);
        self
    }

    pub fn with_pre_tags(&mut self, pre_tags: Vec<String>) -> &mut Highlight {
        self.pre_tags = Some(pre_tags);
        self
    }

    pub fn with_post_tags(&mut self, post_tags: Vec<String>) -> &mut Highlight {
        self.post_tags = Some(post_tags);
        self
    }

    /// Add a field to highlight to the set
    pub fn add(&mut self, name: String, setting: Setting) {
        self.fields.insert(name, setting);
    }
}

/// The fields containing found terms
pub type HighlightResult = HashMap<String, Vec<String>>;
<|endoftext|>


<commit_before>use std::{
    io::{self, Error, ErrorKind},
    mem,
    net::SocketAddr,
    os::unix::io::AsRawFd,
    ptr,
    task::{Context, Poll},
};

use async_trait::async_trait;
use futures::{future::poll_fn, ready};
use mio::net::UdpSocket;
use socket2::{Domain, Protocol, SockAddr, Socket, Type};

use crate::{config::RedirType, local::redir::redir_ext::UdpSocketRedirExt, sys::sockaddr_to_std};

pub fn check_support_tproxy() -> io::Result<()> {
    Ok(())
}

pub struct UdpRedirSocket {
    io: PollEvented<mio::net::UdpSocket>,
}

impl UdpRedirSocket {
    /// Create a new UDP socket binded to `addr`
    ///
    /// This will allow binding to `addr` that is not in local host
    pub fn bind(ty: RedirType, addr: SocketAddr) -> io::Result<UdpRedirSocket> {
        if ty == RedirType::NotSupported {
            return Err(Error::new(
                ErrorKind::InvalidInput,
                "not supported udp transparent proxy type",
            ));
        }

        let domain = match addr {
            SocketAddr::V4(..) => Domain::ipv4(),
            SocketAddr::V6(..) => Domain::ipv6(),
        };
        let socket = Socket::new(domain, Type::dgram(), Some(Protocol::udp()))?;
        set_socket_before_bind(&addr, &socket)?;

        socket.set_nonblocking(true)?;
        socket.set_reuse_address(true)?;

        socket.bind(&SockAddr::from(addr))?;

        let msock = mio::net::UdpSocket::from_socket(socket.into_udp_socket())?;
        let io = PollEvented::new(msock)?;
        Ok(UdpRedirSocket { io })
    }

    /// Send data to the socket to the given target address
    pub async fn send_to(&mut self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {
        poll_fn(|cx| self.poll_send_to(cx, buf, target)).await
    }

    fn poll_send_to(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>> {
        ready!(self.io.poll_write_ready(cx))?;

        match self.io.get_ref().send_to(buf, target) {
            Err(ref e) if e.kind() == ErrorKind::WouldBlock => {
                self.io.clear_write_ready(cx)?;
                Poll::Pending
            }
            x => Poll::Ready(x),
        }
    }

    /// Returns the local address that this socket is bound to.
    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.io.get_ref().local_addr()
    }

    fn poll_recv_from(
        &self,
        cx: &mut Context<'_>,
        buf: &mut [u8],
    ) -> Poll<io::Result<(usize, SocketAddr, SocketAddr)>> {
        ready!(self.io.poll_read_ready(cx, mio::Ready::readable()))?;

        match recv_from_with_destination(self.io.get_ref(), buf) {
            Err(ref e) if e.kind() == ErrorKind::WouldBlock => {
                self.io.clear_read_ready(cx, mio::Ready::readable())?;
                Poll::Pending
            }
            x => Poll::Ready(x),
        }
    }
}

#[async_trait]
impl UdpSocketRedirExt for UdpRedirSocket {
    async fn recv_from_redir(&mut self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr, SocketAddr)> {
        poll_fn(|cx| self.poll_recv_from(cx, buf)).await
    }
}

#[cfg(target_os = "freebsd")]
fn set_bindany(level: libc::c_int, socket: &Socket) -> io::Result<()> {
    let fd = socket.as_raw_fd();

    let enable: libc::c_int = 1;

    // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE
    let opt = match level {
        libc::IPPROTO_IP => libc::IP_BINDANY,
        libc::IPPROTO_IPV6 => libc::IPV6_BINDANY,
        _ => unreachable!("level can only be IPPROTO_IP or IPPROTO_IPV6"),
    };

    let ret = libc::setsockopt(
        fd,
        level,
        opt,
        &enable as *const _ as *const _,
        mem::size_of_val(&enable) as libc::socklen_t,
    );
    if ret != 0 {
        return Err(Error::last_os_error());
    }

    Ok(())
}

#[cfg(target_os = "openbsd")]
fn set_bindany(_level: libc::c_int, socket: &Socket) -> io::Result<()> {
    let fd = socket.as_raw_fd();

    let enable: libc::c_int = 1;

    // https://man.openbsd.org/getsockopt.2
    let ret = libc::setsockopt(
        fd,
        libc::SOL_SOCKET,
        libc::SO_BINDANY,
        &enable as *const _ as *const _,
        mem::size_of_val(&enable) as libc::socklen_t,
    );
    if ret != 0 {
        return Err(Error::last_os_error());
    }

    Ok(())
}

fn set_socket_before_bind(addr: &SocketAddr, socket: &Socket) -> io::Result<()> {
    let fd = socket.as_raw_fd();

    let enable: libc::c_int = 1;

    unsafe {
        // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE
        let (level, opt) = match *addr {
            SocketAddr::V4(..) => (libc::IPPROTO_IP, libc::IP_ORIGDSTADDR),
            SocketAddr::V6(..) => (libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR),
        };

        // 1. BINDANY
        set_bindany(level, socket)?;

        // 2. set ORIGDSTADDR for retrieving original destination address
        let ret = libc::setsockopt(
            fd,
            level,
            opt,
            &enable as *const _ as *const _,
            mem::size_of_val(&enable) as libc::socklen_t,
        );
        if ret != 0 {
            return Err(Error::last_os_error());
        }
    }

    Ok(())
}

fn get_destination_addr(msg: &libc::msghdr) -> Option<libc::sockaddr_storage> {
    // https://www.freebsd.org/cgi/man.cgi?ip(4)
    //
    // Called `recvmsg` with `IP_ORIGDSTADDR` set

    unsafe {
        let mut cmsg: *mut libc::cmsghdr = libc::CMSG_FIRSTHDR(msg);
        while !cmsg.is_null() {
            let rcmsg = &*cmsg;
            match (rcmsg.cmsg_level, rcmsg.cmsg_type) {
                (libc::IPPROTO_IP, libc::IP_ORIGDSTADDR) => {
                    let mut dst_addr: libc::sockaddr_storage = mem::zeroed();

                    ptr::copy(
                        libc::CMSG_DATA(cmsg),
                        &mut dst_addr as *mut _ as *mut _,
                        mem::size_of::<libc::sockaddr_in>(),
                    );

                    return Some(dst_addr);
                }
                (libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR) => {
                    let mut dst_addr: libc::sockaddr_storage = mem::zeroed();

                    ptr::copy(
                        libc::CMSG_DATA(cmsg),
                        &mut dst_addr as *mut _ as *mut _,
                        mem::size_of::<libc::sockaddr_in6>(),
                    );

                    return Some(dst_addr);
                }
                _ => {}
            }
            cmsg = libc::CMSG_NXTHDR(msg, cmsg);
        }
    }

    None
}

fn recv_from_with_destination(socket: &UdpSocket, buf: &mut [u8]) -> io::Result<(usize, SocketAddr, SocketAddr)> {
    unsafe {
        let mut control_buf = [0u8; 64];
        let mut src_addr: libc::sockaddr_storage = mem::zeroed();

        let mut msg: libc::msghdr = mem::zeroed();
        msg.msg_name = &mut src_addr as *mut _ as *mut _;
        msg.msg_namelen = mem::size_of_val(&src_addr) as libc::socklen_t;

        let mut iov = libc::iovec {
            iov_base: buf.as_mut_ptr() as *mut _,
            iov_len: buf.len() as libc::size_t,
        };
        msg.msg_iov = &mut iov;
        msg.msg_iovlen = 1;

        msg.msg_control = control_buf.as_mut_ptr() as *mut _;
        msg.msg_controllen = control_buf.len() as libc::size_t;

        let fd = socket.as_raw_fd();
        let ret = libc::recvmsg(fd, &mut msg, 0);
        if ret < 0 {
            return Err(Error::last_os_error());
        }

        let dst_addr = match get_destination_addr(&msg) {
            None => {
                let err = Error::new(ErrorKind::InvalidData, "missing destination address in msghdr");
                return Err(err);
            }
            Some(d) => d,
        };

        Ok((ret as usize, sockaddr_to_std(&src_addr)?, sockaddr_to_std(&dst_addr)?))
    }
}
<commit_msg>fixed bsd udp redir build<commit_after>use std::{
    io::{self, Error, ErrorKind},
    mem,
    net::SocketAddr,
    os::unix::io::AsRawFd,
    ptr,
    task::{Context, Poll},
};

use async_trait::async_trait;
use futures::{future::poll_fn, ready};
use mio::net::UdpSocket;
use socket2::{Domain, Protocol, SockAddr, Socket, Type};
use tokio::io::unix::AsyncFd;

use crate::{config::RedirType, local::redir::redir_ext::UdpSocketRedirExt, sys::sockaddr_to_std};

pub fn check_support_tproxy() -> io::Result<()> {
    Ok(())
}

pub struct UdpRedirSocket {
    io: AsyncFd<mio::net::UdpSocket>,
}

impl UdpRedirSocket {
    /// Create a new UDP socket binded to `addr`
    ///
    /// This will allow binding to `addr` that is not in local host
    pub fn bind(ty: RedirType, addr: SocketAddr) -> io::Result<UdpRedirSocket> {
        if ty == RedirType::NotSupported {
            return Err(Error::new(
                ErrorKind::InvalidInput,
                "not supported udp transparent proxy type",
            ));
        }

        let domain = match addr {
            SocketAddr::V4(..) => Domain::ipv4(),
            SocketAddr::V6(..) => Domain::ipv6(),
        };
        let socket = Socket::new(domain, Type::dgram(), Some(Protocol::udp()))?;
        set_socket_before_bind(&addr, &socket)?;

        socket.set_nonblocking(true)?;
        socket.set_reuse_address(true)?;

        socket.bind(&SockAddr::from(addr))?;

        let msock = mio::net::UdpSocket::from_socket(socket.into_udp_socket())?;
        let io = AsyncFd::new(msock)?;
        Ok(UdpRedirSocket { io })
    }

    /// Send data to the socket to the given target address
    pub async fn send_to(&mut self, buf: &[u8], target: SocketAddr) -> io::Result<usize> {
        poll_fn(|cx| self.poll_send_to(cx, buf, target)).await
    }

    fn poll_send_to(&self, cx: &mut Context<'_>, buf: &[u8], target: SocketAddr) -> Poll<io::Result<usize>> {
        let mut write_guard = ready!(self.io.poll_write_ready(cx))?;

        match self.io.get_ref().send_to(buf, target) {
            Err(ref e) if e.kind() == ErrorKind::WouldBlock => {
                write_guard.clear_ready();
                Poll::Pending
            }
            x => Poll::Ready(x),
        }
    }

    /// Returns the local address that this socket is bound to.
    pub fn local_addr(&self) -> io::Result<SocketAddr> {
        self.io.get_ref().local_addr()
    }

    fn poll_recv_from(
        &self,
        cx: &mut Context<'_>,
        buf: &mut [u8],
    ) -> Poll<io::Result<(usize, SocketAddr, SocketAddr)>> {
        let mut read_guard = ready!(self.io.poll_read_ready(cx))?;

        match recv_from_with_destination(self.io.get_ref(), buf) {
            Err(ref e) if e.kind() == ErrorKind::WouldBlock => {
                read_guard.clear_ready();
                Poll::Pending
            }
            x => Poll::Ready(x),
        }
    }
}

#[async_trait]
impl UdpSocketRedirExt for UdpRedirSocket {
    async fn recv_from_redir(&mut self, buf: &mut [u8]) -> io::Result<(usize, SocketAddr, SocketAddr)> {
        poll_fn(|cx| self.poll_recv_from(cx, buf)).await
    }
}

#[cfg(target_os = "freebsd")]
fn set_bindany(level: libc::c_int, socket: &Socket) -> io::Result<()> {
    let fd = socket.as_raw_fd();

    let enable: libc::c_int = 1;

    // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE
    let opt = match level {
        libc::IPPROTO_IP => libc::IP_BINDANY,
        libc::IPPROTO_IPV6 => libc::IPV6_BINDANY,
        _ => unreachable!("level can only be IPPROTO_IP or IPPROTO_IPV6"),
    };

    let ret = libc::setsockopt(
        fd,
        level,
        opt,
        &enable as *const _ as *const _,
        mem::size_of_val(&enable) as libc::socklen_t,
    );
    if ret != 0 {
        return Err(Error::last_os_error());
    }

    Ok(())
}

#[cfg(target_os = "openbsd")]
fn set_bindany(_level: libc::c_int, socket: &Socket) -> io::Result<()> {
    let fd = socket.as_raw_fd();

    let enable: libc::c_int = 1;

    // https://man.openbsd.org/getsockopt.2
    let ret = libc::setsockopt(
        fd,
        libc::SOL_SOCKET,
        libc::SO_BINDANY,
        &enable as *const _ as *const _,
        mem::size_of_val(&enable) as libc::socklen_t,
    );
    if ret != 0 {
        return Err(Error::last_os_error());
    }

    Ok(())
}

fn set_socket_before_bind(addr: &SocketAddr, socket: &Socket) -> io::Result<()> {
    let fd = socket.as_raw_fd();

    let enable: libc::c_int = 1;

    unsafe {
        // https://www.freebsd.org/cgi/man.cgi?query=ip&sektion=4&manpath=FreeBSD+9.0-RELEASE
        let (level, opt) = match *addr {
            SocketAddr::V4(..) => (libc::IPPROTO_IP, libc::IP_ORIGDSTADDR),
            SocketAddr::V6(..) => (libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR),
        };

        // 1. BINDANY
        set_bindany(level, socket)?;

        // 2. set ORIGDSTADDR for retrieving original destination address
        let ret = libc::setsockopt(
            fd,
            level,
            opt,
            &enable as *const _ as *const _,
            mem::size_of_val(&enable) as libc::socklen_t,
        );
        if ret != 0 {
            return Err(Error::last_os_error());
        }
    }

    Ok(())
}

fn get_destination_addr(msg: &libc::msghdr) -> Option<libc::sockaddr_storage> {
    // https://www.freebsd.org/cgi/man.cgi?ip(4)
    //
    // Called `recvmsg` with `IP_ORIGDSTADDR` set

    unsafe {
        let mut cmsg: *mut libc::cmsghdr = libc::CMSG_FIRSTHDR(msg);
        while !cmsg.is_null() {
            let rcmsg = &*cmsg;
            match (rcmsg.cmsg_level, rcmsg.cmsg_type) {
                (libc::IPPROTO_IP, libc::IP_ORIGDSTADDR) => {
                    let mut dst_addr: libc::sockaddr_storage = mem::zeroed();

                    ptr::copy(
                        libc::CMSG_DATA(cmsg),
                        &mut dst_addr as *mut _ as *mut _,
                        mem::size_of::<libc::sockaddr_in>(),
                    );

                    return Some(dst_addr);
                }
                (libc::IPPROTO_IPV6, libc::IPV6_ORIGDSTADDR) => {
                    let mut dst_addr: libc::sockaddr_storage = mem::zeroed();

                    ptr::copy(
                        libc::CMSG_DATA(cmsg),
                        &mut dst_addr as *mut _ as *mut _,
                        mem::size_of::<libc::sockaddr_in6>(),
                    );

                    return Some(dst_addr);
                }
                _ => {}
            }
            cmsg = libc::CMSG_NXTHDR(msg, cmsg);
        }
    }

    None
}

fn recv_from_with_destination(socket: &UdpSocket, buf: &mut [u8]) -> io::Result<(usize, SocketAddr, SocketAddr)> {
    unsafe {
        let mut control_buf = [0u8; 64];
        let mut src_addr: libc::sockaddr_storage = mem::zeroed();

        let mut msg: libc::msghdr = mem::zeroed();
        msg.msg_name = &mut src_addr as *mut _ as *mut _;
        msg.msg_namelen = mem::size_of_val(&src_addr) as libc::socklen_t;

        let mut iov = libc::iovec {
            iov_base: buf.as_mut_ptr() as *mut _,
            iov_len: buf.len() as libc::size_t,
        };
        msg.msg_iov = &mut iov;
        msg.msg_iovlen = 1;

        msg.msg_control = control_buf.as_mut_ptr() as *mut _;
        msg.msg_controllen = control_buf.len() as libc::size_t;

        let fd = socket.as_raw_fd();
        let ret = libc::recvmsg(fd, &mut msg, 0);
        if ret < 0 {
            return Err(Error::last_os_error());
        }

        let dst_addr = match get_destination_addr(&msg) {
            None => {
                let err = Error::new(ErrorKind::InvalidData, "missing destination address in msghdr");
                return Err(err);
            }
            Some(d) => d,
        };

        Ok((ret as usize, sockaddr_to_std(&src_addr)?, sockaddr_to_std(&dst_addr)?))
    }
}
<|endoftext|>


<commit_before>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::ptr;
use std::slice;
use std::ffi;

use htslib;

pub struct Record {
    pub inner: *mut htslib::vcf::bcf1_t,
    pub header: *mut htslib::vcf::bcf_hdr_t,
    buffer: *mut ::libc::c_void,
}

impl Record {
    pub fn new() -> Self {
        let inner = unsafe { htslib::vcf::bcf_init() };
        Record { inner: inner, header: ptr::null_mut(), buffer: ptr::null_mut() }
    }

    pub fn rid(&self) -> Option<u32> {
        match unsafe { *self.inner }.rid {
            -1  => None,
            rid => Some(rid as u32)
        }
    }

    // 0-based position.
    pub fn pos(&self) -> u32 {
        unsafe { *self.inner }.pos as u32
    }

    pub fn set_pos(&mut self, pos: i32) {
        unsafe { (*self.inner).pos = pos; }
    }

    pub fn alleles(&self) -> Vec<&[u8]> {
        unsafe { htslib::vcf::bcf_unpack(self.inner, htslib::vcf::BCF_UN_STR) };
        let n = unsafe { *self.inner }.n_allele as usize;
        let dec = unsafe { *self.inner }.d;
        let alleles = unsafe { slice::from_raw_parts(dec.allele, n) };
        (0..n).map(|i| unsafe { ffi::CStr::from_ptr(alleles[i]).to_bytes() }).collect()
    }

    pub fn qual(&self) -> f32 {
        unsafe { *self.inner }.qual
    }

    pub fn set_qual(&mut self, qual: f32) {
        unsafe { (*self.inner).qual = qual; }
    }

    /// Get the value of the given info tag.
    pub fn info<'a>(&'a mut self, tag: &'a [u8]) -> Info {
        Info { record: self, tag: tag }
    }

    pub fn sample_count(&self) -> u32 {
        unsafe { *self.inner }.n_fmt_n_sample >> 8
    }

    pub fn allele_count(&self) -> u16 {
        unsafe { *self.inner }.n_allele
    }

    /// Get the value of the given format tag for each sample.
    pub fn format<'a>(&'a mut self, tag: &'a [u8]) -> Format {
        Format::new(self, tag)
    }

    /// Add an integer format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    /// Returns error if tag is not present in header.
    pub fn push_format_integer(&mut self, tag: &[u8], data: &[i32]) -> Result<(), ()> {
        self.push_format(tag, data, htslib::vcf::BCF_HT_INT)
    }

    /// Add a float format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    /// Returns error if tag is not present in header.
    pub fn push_format_float(&mut self, tag: &[u8], data: &[f32]) -> Result<(), ()> {
        self.push_format(tag, data, htslib::vcf::BCF_HT_REAL)
    }

    /// Add a format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    fn push_format<T>(&mut self, tag: &[u8], data: &[T], ht: i32) -> Result<(), ()> {
        assert!(data.len() > 0);
        unsafe {
            if htslib::vcf::bcf_update_format(
                self.header,
                self.inner,
                ffi::CString::new(tag).unwrap().as_ptr() as *mut i8,
                data.as_ptr() as *const ::libc::c_void,
                data.len() as i32,
                ht
            ) == 0 {
                Ok(())
            }
            else {
                Err(())
            }
        }
    }

    /// Add a info tag.
    pub fn push_info<T>(&mut self, tag: &[u8], data: &[T], ht: i32) -> Result<(), ()> {
        assert!(data.len() > 0);
        unsafe {
            if htslib::vcf::bcf_update_info(
                self.header,
                self.inner,
                ffi::CString::new(tag).unwrap().as_ptr() as *mut i8,
                data.as_ptr() as *const ::libc::c_void,
                data.len() as i32,
                ht
            ) == 0 {
                Ok(())
            }
            else {
                Err(())
            }
        }
    }

    /// Remove unused alleles.
    pub fn trim_alleles(&mut self) -> Result<(), ()> {
        match unsafe { htslib::vcfutils::bcf_trim_alleles(self.header, self.inner) } {
            -1 => Err(()),
            _  => Ok(())
        }
    }
}

impl Drop for Record {
    fn drop(&mut self) {
        if !self.buffer.is_null() {
            unsafe { ::libc::free(self.buffer) };
        }
        unsafe { htslib::vcf::bcf_destroy(self.inner) };
    }
}

unsafe impl Send for Record {}

pub struct Info<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
}

impl<'a> Info<'a> {
    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_info_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<&mut [i32], TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe { slice::from_raw_parts_mut(self.record.buffer as *mut i32, n) }
        })
    }

    pub fn float(&mut self) -> Result<&mut [f32], TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe { slice::from_raw_parts_mut(self.record.buffer as *mut f32, n) }
        })
    }

    pub fn flag(&mut self) -> Result<bool, TagError> {
        self.data(htslib::vcf::BCF_HT_FLAG).map(|(_, ret)| {
            ret == 1
        })
    }

    pub fn string(&mut self) -> Result<&mut [u8], TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(_, ret)| {
            unsafe { slice::from_raw_parts_mut(self.record.buffer as *mut u8, ret as usize) }
        })
    }
}

// TODO implement format.
pub struct Format<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
    inner: *mut htslib::vcf::bcf_fmt_t,
}

impl<'a> Format<'a> {
    fn new(record: &'a mut Record, tag: &'a [u8]) -> Format<'a> {
        let inner = unsafe { htslib::vcf::bcf_get_fmt(
            record.header,
            record.inner,
            ffi::CString::new(tag).unwrap().as_ptr() as *mut i8
        ) };
        Format { record: record, tag: tag, inner: inner }
    }

    fn values_per_sample(&self) -> usize {
        unsafe { (*self.inner).n as usize }
    }

    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_format_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<Vec<&mut [i32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut i32, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }

    pub fn float(&mut self) -> Result<Vec<&mut [f32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut f32, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }

    pub fn string(&mut self) -> Result<Vec<&mut [u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut u8, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }
}

pub enum TagError {
    UndefinedTag,
    UnexpectedType,
    MissingTag,
}
<commit_msg>Refactored format and info to allow immutable access. In that case, remove padding zeroes from strings.<commit_after>// Copyright 2014 Johannes Köster.
// Licensed under the MIT license (http://opensource.org/licenses/MIT)
// This file may not be copied, modified, or distributed
// except according to those terms.

use std::ptr;
use std::slice;
use std::ffi;

use htslib;

pub struct Record {
    pub inner: *mut htslib::vcf::bcf1_t,
    pub header: *mut htslib::vcf::bcf_hdr_t,
    buffer: *mut ::libc::c_void,
}

impl Record {
    pub fn new() -> Self {
        let inner = unsafe { htslib::vcf::bcf_init() };
        Record { inner: inner, header: ptr::null_mut(), buffer: ptr::null_mut() }
    }

    pub fn rid(&self) -> Option<u32> {
        match unsafe { *self.inner }.rid {
            -1  => None,
            rid => Some(rid as u32)
        }
    }

    // 0-based position.
    pub fn pos(&self) -> u32 {
        unsafe { *self.inner }.pos as u32
    }

    pub fn set_pos(&mut self, pos: i32) {
        unsafe { (*self.inner).pos = pos; }
    }

    pub fn alleles(&self) -> Vec<&[u8]> {
        unsafe { htslib::vcf::bcf_unpack(self.inner, htslib::vcf::BCF_UN_STR) };
        let n = unsafe { *self.inner }.n_allele as usize;
        let dec = unsafe { *self.inner }.d;
        let alleles = unsafe { slice::from_raw_parts(dec.allele, n) };
        (0..n).map(|i| unsafe { ffi::CStr::from_ptr(alleles[i]).to_bytes() }).collect()
    }

    pub fn qual(&self) -> f32 {
        unsafe { *self.inner }.qual
    }

    pub fn set_qual(&mut self, qual: f32) {
        unsafe { (*self.inner).qual = qual; }
    }

    /// Get the value of the given info tag.
    pub fn info<'a>(&'a mut self, tag: &'a [u8]) -> Info {
        Info { record: self, tag: tag }
    }

    pub fn sample_count(&self) -> u32 {
        unsafe { *self.inner }.n_fmt_n_sample >> 8
    }

    pub fn allele_count(&self) -> u16 {
        unsafe { *self.inner }.n_allele
    }

    /// Get the value of the given format tag for each sample.
    pub fn format<'a>(&'a mut self, tag: &'a [u8]) -> Format {
        Format::new(self, tag)
    }

    /// Add an integer format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    /// Returns error if tag is not present in header.
    pub fn push_format_integer(&mut self, tag: &[u8], data: &[i32]) -> Result<(), ()> {
        self.push_format(tag, data, htslib::vcf::BCF_HT_INT)
    }

    /// Add a float format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    /// Returns error if tag is not present in header.
    pub fn push_format_float(&mut self, tag: &[u8], data: &[f32]) -> Result<(), ()> {
        self.push_format(tag, data, htslib::vcf::BCF_HT_REAL)
    }

    /// Add a format tag. Data is a flattened two-dimensional array.
    /// The first dimension contains one array for each sample.
    fn push_format<T>(&mut self, tag: &[u8], data: &[T], ht: i32) -> Result<(), ()> {
        assert!(data.len() > 0);
        unsafe {
            if htslib::vcf::bcf_update_format(
                self.header,
                self.inner,
                ffi::CString::new(tag).unwrap().as_ptr() as *mut i8,
                data.as_ptr() as *const ::libc::c_void,
                data.len() as i32,
                ht
            ) == 0 {
                Ok(())
            }
            else {
                Err(())
            }
        }
    }

    /// Add a info tag.
    pub fn push_info<T>(&mut self, tag: &[u8], data: &[T], ht: i32) -> Result<(), ()> {
        assert!(data.len() > 0);
        unsafe {
            if htslib::vcf::bcf_update_info(
                self.header,
                self.inner,
                ffi::CString::new(tag).unwrap().as_ptr() as *mut i8,
                data.as_ptr() as *const ::libc::c_void,
                data.len() as i32,
                ht
            ) == 0 {
                Ok(())
            }
            else {
                Err(())
            }
        }
    }

    /// Remove unused alleles.
    pub fn trim_alleles(&mut self) -> Result<(), ()> {
        match unsafe { htslib::vcfutils::bcf_trim_alleles(self.header, self.inner) } {
            -1 => Err(()),
            _  => Ok(())
        }
    }
}

impl Drop for Record {
    fn drop(&mut self) {
        if !self.buffer.is_null() {
            unsafe { ::libc::free(self.buffer) };
        }
        unsafe { htslib::vcf::bcf_destroy(self.inner) };
    }
}

unsafe impl Send for Record {}

pub struct Info<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
}

impl<'a> Info<'a> {
    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_info_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<&[i32], TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe { slice::from_raw_parts(self.record.buffer as *const i32, n) }
        })
    }

    pub fn integer_mut(&mut self) -> Result<&mut [i32], TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe { slice::from_raw_parts_mut(self.record.buffer as *mut i32, n) }
        })
    }

    pub fn float(&mut self) -> Result<&[f32], TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe { slice::from_raw_parts(self.record.buffer as *const f32, n) }
        })
    }

    pub fn float_mut(&mut self) -> Result<&mut [f32], TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe { slice::from_raw_parts_mut(self.record.buffer as *mut f32, n) }
        })
    }

    pub fn flag(&mut self) -> Result<bool, TagError> {
        self.data(htslib::vcf::BCF_HT_FLAG).map(|(_, ret)| {
            ret == 1
        })
    }

    pub fn string(&mut self) -> Result<Vec<&[u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, ret)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const u8, ret as usize)
            }.chunks(n).map(|s| {
                unsafe { ffi::CStr::from_ptr(s.as_ptr() as *const i8).to_bytes() }
            }).collect()
        })
    }

    pub fn string_mut(&mut self) -> Result<Vec<&mut [u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, ret)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut u8, ret as usize)
            }.chunks_mut(n).collect()
        })
    }
}

// TODO implement format.
pub struct Format<'a> {
    record: &'a mut Record,
    tag: &'a [u8],
    inner: *mut htslib::vcf::bcf_fmt_t,
}

impl<'a> Format<'a> {
    fn new(record: &'a mut Record, tag: &'a [u8]) -> Format<'a> {
        let inner = unsafe { htslib::vcf::bcf_get_fmt(
            record.header,
            record.inner,
            ffi::CString::new(tag).unwrap().as_ptr() as *mut i8
        ) };
        Format { record: record, tag: tag, inner: inner }
    }

    fn values_per_sample(&self) -> usize {
        unsafe { (*self.inner).n as usize }
    }

    fn data(&mut self, data_type: i32) -> Result<(usize, i32), TagError> {
        let mut n: i32 = 0;
        match unsafe {
            htslib::vcf::bcf_get_format_values(
                self.record.header,
                self.record.inner,
                ffi::CString::new(self.tag).unwrap().as_ptr() as *mut i8,
                &mut self.record.buffer,
                &mut n,
                data_type
            )
        } {
            -1 => Err(TagError::UndefinedTag),
            -2 => Err(TagError::UnexpectedType),
            -3 => Err(TagError::MissingTag),
            ret  => Ok((n as usize, ret)),
        }
    }

    pub fn integer(&mut self) -> Result<Vec<&[i32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const i32, n)
            }.chunks(self.values_per_sample()).collect()
        })
    }

    pub fn integer_mut(&mut self) -> Result<Vec<&mut [i32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_INT).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut i32, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }

    pub fn float(&mut self) -> Result<Vec<&[f32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const f32, n)
            }.chunks(self.values_per_sample()).collect()
        })
    }

    pub fn float_mut(&mut self) -> Result<Vec<&mut [f32]>, TagError> {
        self.data(htslib::vcf::BCF_HT_REAL).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut f32, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }

    pub fn string(&mut self) -> Result<Vec<&[u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts(self.record.buffer as *const u8, n)
            }.chunks(self.values_per_sample()).map(|s| {
                unsafe { ffi::CStr::from_ptr(s.as_ptr() as *const i8).to_bytes() }
            }).collect()
        })
    }

    pub fn string_mut(&mut self) -> Result<Vec<&mut [u8]>, TagError> {
        self.data(htslib::vcf::BCF_HT_STR).map(|(n, _)| {
            unsafe {
                slice::from_raw_parts_mut(self.record.buffer as *mut u8, n)
            }.chunks_mut(self.values_per_sample()).collect()
        })
    }
}

pub enum TagError {
    UndefinedTag,
    UnexpectedType,
    MissingTag,
}
<|endoftext|>