<commit_before>use rustc_middle::thir::*;
use rustc_middle::ty::Const;

pub trait Visitor<'a, 'tcx: 'a>: Sized {
    fn thir(&self) -> &'a Thir<'tcx>;

    fn visit_expr(&mut self, expr: &Expr<'tcx>) {
        walk_expr(self, expr);
    }

    fn visit_stmt(&mut self, stmt: &Stmt<'tcx>) {
        walk_stmt(self, stmt);
    }

    fn visit_block(&mut self, block: &Block) {
        walk_block(self, block);
    }

    fn visit_arm(&mut self, arm: &Arm<'tcx>) {
        walk_arm(self, arm);
    }

    fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {}
}

pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) {
    use ExprKind::*;
    match expr.kind {
        Scope { value, region_scope: _, lint_level: _ } => {
            visitor.visit_expr(&visitor.thir()[value])
        }
        Box { value } => visitor.visit_expr(&visitor.thir()[value]),
        If { cond, then, else_opt } => {
            visitor.visit_expr(&visitor.thir()[cond]);
            visitor.visit_expr(&visitor.thir()[then]);
            if let Some(else_expr) = else_opt {
                visitor.visit_expr(&visitor.thir()[else_expr]);
            }
        }
        Call { fun, ref args, ty: _, from_hir_call: _, fn_span: _ } => {
            visitor.visit_expr(&visitor.thir()[fun]);
            for &arg in &**args {
                visitor.visit_expr(&visitor.thir()[arg]);
            }
        }
        Deref { arg } => visitor.visit_expr(&visitor.thir()[arg]),
        Binary { lhs, rhs, op: _ } | LogicalOp { lhs, rhs, op: _ } => {
            visitor.visit_expr(&visitor.thir()[lhs]);
            visitor.visit_expr(&visitor.thir()[rhs]);
        }
        Unary { arg, op: _ } => visitor.visit_expr(&visitor.thir()[arg]),
        Cast { source } => visitor.visit_expr(&visitor.thir()[source]),
        Use { source } => visitor.visit_expr(&visitor.thir()[source]),
        NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
        Pointer { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
        Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
        Match { scrutinee, ref arms } => {
            visitor.visit_expr(&visitor.thir()[scrutinee]);
            for &arm in &**arms {
                visitor.visit_arm(&visitor.thir()[arm]);
            }
        }
        Block { ref body } => visitor.visit_block(body),
        Assign { lhs, rhs } | AssignOp { lhs, rhs, op: _ } => {
            visitor.visit_expr(&visitor.thir()[lhs]);
            visitor.visit_expr(&visitor.thir()[rhs]);
        }
        Field { lhs, name: _ } => visitor.visit_expr(&visitor.thir()[lhs]),
        Index { lhs, index } => {
            visitor.visit_expr(&visitor.thir()[lhs]);
            visitor.visit_expr(&visitor.thir()[index]);
        }
        VarRef { id: _ } | UpvarRef { closure_def_id: _, var_hir_id: _ } => {}
        Borrow { arg, borrow_kind: _ } => visitor.visit_expr(&visitor.thir()[arg]),
        AddressOf { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]),
        Break { value, label: _ } => {
            if let Some(value) = value {
                visitor.visit_expr(&visitor.thir()[value])
            }
        }
        Continue { label: _ } => {}
        Return { value } => {
            if let Some(value) = value {
                visitor.visit_expr(&visitor.thir()[value])
            }
        }
        ConstBlock { value } => visitor.visit_const(value),
        Repeat { value, count } => {
            visitor.visit_expr(&visitor.thir()[value]);
            visitor.visit_const(count);
        }
        Array { ref fields } | Tuple { ref fields } => {
            for &field in &**fields {
                visitor.visit_expr(&visitor.thir()[field]);
            }
        }
        Adt { ref fields, ref base, adt_def: _, variant_index: _, substs: _, user_ty: _ } => {
            for field in &**fields {
                visitor.visit_expr(&visitor.thir()[field.expr]);
            }
            if let Some(base) = base {
                visitor.visit_expr(&visitor.thir()[base.base]);
            }
        }
        PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => {
            visitor.visit_expr(&visitor.thir()[source])
        }
        Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
        Literal { literal, user_ty: _, const_id: _ } => visitor.visit_const(literal),
        StaticRef { literal, def_id: _ } => visitor.visit_const(literal),
        InlineAsm { ref operands, template: _, options: _, line_spans: _ } => {
            for op in &**operands {
                use InlineAsmOperand::*;
                match op {
                    In { expr, reg: _ }
                    | Out { expr: Some(expr), reg: _, late: _ }
                    | InOut { expr, reg: _, late: _ }
                    | SymFn { expr } => visitor.visit_expr(&visitor.thir()[*expr]),
                    SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
                        visitor.visit_expr(&visitor.thir()[*in_expr]);
                        if let Some(out_expr) = out_expr {
                            visitor.visit_expr(&visitor.thir()[*out_expr]);
                        }
                    }
                    Out { expr: None, reg: _, late: _ }
                    | Const { value: _, span: _ }
                    | SymStatic { def_id: _ } => {}
                }
            }
        }
        ThreadLocalRef(_) => {}
        LlvmInlineAsm { ref outputs, ref inputs, asm: _ } => {
            for &out_expr in &**outputs {
                visitor.visit_expr(&visitor.thir()[out_expr]);
            }
            for &in_expr in &**inputs {
                visitor.visit_expr(&visitor.thir()[in_expr]);
            }
        }
        Yield { value } => visitor.visit_expr(&visitor.thir()[value]),
    }
}

pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stmt<'tcx>) {
    match stmt.kind {
        StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(&visitor.thir()[expr]),
        StmtKind::Let {
            initializer,
            remainder_scope: _,
            init_scope: _,
            pattern: _,
            lint_level: _,
        } => {
            if let Some(init) = initializer {
                visitor.visit_expr(&visitor.thir()[init]);
            }
        }
    }
}

pub fn walk_block<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, block: &Block) {
    for &stmt in &*block.stmts {
        visitor.visit_stmt(&visitor.thir()[stmt]);
    }
    if let Some(expr) = block.expr {
        visitor.visit_expr(&visitor.thir()[expr]);
    }
}

pub fn walk_arm<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, arm: &Arm<'tcx>) {
    match arm.guard {
        Some(Guard::If(expr)) => visitor.visit_expr(&visitor.thir()[expr]),
        Some(Guard::IfLet(ref _pat, expr)) => {
            visitor.visit_expr(&visitor.thir()[expr]);
        }
        None => {}
    }
    visitor.visit_expr(&visitor.thir()[arm.body]);
}
<commit_msg>Add pattern walking support to THIR walker<commit_after>use rustc_middle::thir::*;
use rustc_middle::ty::Const;

pub trait Visitor<'a, 'tcx: 'a>: Sized {
    fn thir(&self) -> &'a Thir<'tcx>;

    fn visit_expr(&mut self, expr: &Expr<'tcx>) {
        walk_expr(self, expr);
    }

    fn visit_stmt(&mut self, stmt: &Stmt<'tcx>) {
        walk_stmt(self, stmt);
    }

    fn visit_block(&mut self, block: &Block) {
        walk_block(self, block);
    }

    fn visit_arm(&mut self, arm: &Arm<'tcx>) {
        walk_arm(self, arm);
    }

    fn visit_pat(&mut self, pat: &Pat<'tcx>) {
        walk_pat(self, pat);
    }

    fn visit_const(&mut self, _cnst: &'tcx Const<'tcx>) {}
}

pub fn walk_expr<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, expr: &Expr<'tcx>) {
    use ExprKind::*;
    match expr.kind {
        Scope { value, region_scope: _, lint_level: _ } => {
            visitor.visit_expr(&visitor.thir()[value])
        }
        Box { value } => visitor.visit_expr(&visitor.thir()[value]),
        If { cond, then, else_opt } => {
            visitor.visit_expr(&visitor.thir()[cond]);
            visitor.visit_expr(&visitor.thir()[then]);
            if let Some(else_expr) = else_opt {
                visitor.visit_expr(&visitor.thir()[else_expr]);
            }
        }
        Call { fun, ref args, ty: _, from_hir_call: _, fn_span: _ } => {
            visitor.visit_expr(&visitor.thir()[fun]);
            for &arg in &**args {
                visitor.visit_expr(&visitor.thir()[arg]);
            }
        }
        Deref { arg } => visitor.visit_expr(&visitor.thir()[arg]),
        Binary { lhs, rhs, op: _ } | LogicalOp { lhs, rhs, op: _ } => {
            visitor.visit_expr(&visitor.thir()[lhs]);
            visitor.visit_expr(&visitor.thir()[rhs]);
        }
        Unary { arg, op: _ } => visitor.visit_expr(&visitor.thir()[arg]),
        Cast { source } => visitor.visit_expr(&visitor.thir()[source]),
        Use { source } => visitor.visit_expr(&visitor.thir()[source]),
        NeverToAny { source } => visitor.visit_expr(&visitor.thir()[source]),
        Pointer { source, cast: _ } => visitor.visit_expr(&visitor.thir()[source]),
        Loop { body } => visitor.visit_expr(&visitor.thir()[body]),
        Match { scrutinee, ref arms } => {
            visitor.visit_expr(&visitor.thir()[scrutinee]);
            for &arm in &**arms {
                visitor.visit_arm(&visitor.thir()[arm]);
            }
        }
        Block { ref body } => visitor.visit_block(body),
        Assign { lhs, rhs } | AssignOp { lhs, rhs, op: _ } => {
            visitor.visit_expr(&visitor.thir()[lhs]);
            visitor.visit_expr(&visitor.thir()[rhs]);
        }
        Field { lhs, name: _ } => visitor.visit_expr(&visitor.thir()[lhs]),
        Index { lhs, index } => {
            visitor.visit_expr(&visitor.thir()[lhs]);
            visitor.visit_expr(&visitor.thir()[index]);
        }
        VarRef { id: _ } | UpvarRef { closure_def_id: _, var_hir_id: _ } => {}
        Borrow { arg, borrow_kind: _ } => visitor.visit_expr(&visitor.thir()[arg]),
        AddressOf { arg, mutability: _ } => visitor.visit_expr(&visitor.thir()[arg]),
        Break { value, label: _ } => {
            if let Some(value) = value {
                visitor.visit_expr(&visitor.thir()[value])
            }
        }
        Continue { label: _ } => {}
        Return { value } => {
            if let Some(value) = value {
                visitor.visit_expr(&visitor.thir()[value])
            }
        }
        ConstBlock { value } => visitor.visit_const(value),
        Repeat { value, count } => {
            visitor.visit_expr(&visitor.thir()[value]);
            visitor.visit_const(count);
        }
        Array { ref fields } | Tuple { ref fields } => {
            for &field in &**fields {
                visitor.visit_expr(&visitor.thir()[field]);
            }
        }
        Adt { ref fields, ref base, adt_def: _, variant_index: _, substs: _, user_ty: _ } => {
            for field in &**fields {
                visitor.visit_expr(&visitor.thir()[field.expr]);
            }
            if let Some(base) = base {
                visitor.visit_expr(&visitor.thir()[base.base]);
            }
        }
        PlaceTypeAscription { source, user_ty: _ } | ValueTypeAscription { source, user_ty: _ } => {
            visitor.visit_expr(&visitor.thir()[source])
        }
        Closure { closure_id: _, substs: _, upvars: _, movability: _, fake_reads: _ } => {}
        Literal { literal, user_ty: _, const_id: _ } => visitor.visit_const(literal),
        StaticRef { literal, def_id: _ } => visitor.visit_const(literal),
        InlineAsm { ref operands, template: _, options: _, line_spans: _ } => {
            for op in &**operands {
                use InlineAsmOperand::*;
                match op {
                    In { expr, reg: _ }
                    | Out { expr: Some(expr), reg: _, late: _ }
                    | InOut { expr, reg: _, late: _ }
                    | SymFn { expr } => visitor.visit_expr(&visitor.thir()[*expr]),
                    SplitInOut { in_expr, out_expr, reg: _, late: _ } => {
                        visitor.visit_expr(&visitor.thir()[*in_expr]);
                        if let Some(out_expr) = out_expr {
                            visitor.visit_expr(&visitor.thir()[*out_expr]);
                        }
                    }
                    Out { expr: None, reg: _, late: _ }
                    | Const { value: _, span: _ }
                    | SymStatic { def_id: _ } => {}
                }
            }
        }
        ThreadLocalRef(_) => {}
        LlvmInlineAsm { ref outputs, ref inputs, asm: _ } => {
            for &out_expr in &**outputs {
                visitor.visit_expr(&visitor.thir()[out_expr]);
            }
            for &in_expr in &**inputs {
                visitor.visit_expr(&visitor.thir()[in_expr]);
            }
        }
        Yield { value } => visitor.visit_expr(&visitor.thir()[value]),
    }
}

pub fn walk_stmt<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, stmt: &Stmt<'tcx>) {
    match &stmt.kind {
        StmtKind::Expr { expr, scope: _ } => visitor.visit_expr(&visitor.thir()[*expr]),
        StmtKind::Let {
            initializer,
            remainder_scope: _,
            init_scope: _,
            pattern,
            lint_level: _,
        } => {
            if let Some(init) = initializer {
                visitor.visit_expr(&visitor.thir()[*init]);
            }
            visitor.visit_pat(&pattern);
        }
    }
}

pub fn walk_block<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, block: &Block) {
    for &stmt in &*block.stmts {
        visitor.visit_stmt(&visitor.thir()[stmt]);
    }
    if let Some(expr) = block.expr {
        visitor.visit_expr(&visitor.thir()[expr]);
    }
}

pub fn walk_arm<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, arm: &Arm<'tcx>) {
    match arm.guard {
        Some(Guard::If(expr)) => visitor.visit_expr(&visitor.thir()[expr]),
        Some(Guard::IfLet(ref pat, expr)) => {
            visitor.visit_pat(pat);
            visitor.visit_expr(&visitor.thir()[expr]);
        }
        None => {}
    }
    visitor.visit_pat(&arm.pattern);
    visitor.visit_expr(&visitor.thir()[arm.body]);
}

pub fn walk_pat<'a, 'tcx: 'a, V: Visitor<'a, 'tcx>>(visitor: &mut V, pat: &Pat<'tcx>) {
    use PatKind::*;
    match pat.kind.as_ref() {
        AscribeUserType { subpattern, .. }
        | Deref { subpattern, .. }
        | Binding { subpattern: Some(subpattern), .. } => visitor.visit_pat(&subpattern),
        Binding { .. } | Wild => {}
        Variant { subpatterns, .. } | Leaf { subpatterns } => {
            for subpattern in subpatterns {
                visitor.visit_pat(&subpattern.pattern);
            }
        }
        Constant { value } => visitor.visit_const(value),
        Range(range) => {
            visitor.visit_const(range.lo);
            visitor.visit_const(range.hi);
        }
        Slice { prefix, slice, suffix } | Array { prefix, slice, suffix } => {
            for subpattern in prefix {
                visitor.visit_pat(&subpattern);
            }
            if let Some(pat) = slice {
                visitor.visit_pat(pat);
            }
            for subpattern in suffix {
                visitor.visit_pat(&subpattern);
            }
        }
        Or { pats } => {
            for pat in pats {
                visitor.visit_pat(&pat);
            }
        }
    };
}
<|endoftext|>


<commit_before>use threescalers::{
    api_call::*,
    application::*,
    credentials::*,
    extensions::Extensions,
    http::{
        request::FromRequest,
        Request,
    },
    service::*,
    transaction::Transaction,
    usage::Usage,
};

use reqwest::{
    Client,
    RequestBuilder,
    Response,
};

fn main() -> Result<(), threescalers::errors::Error> {
    let creds = Credentials::ServiceToken(ServiceToken::from("12[3]token"));
    let svc = Service::new("svc123", creds);
    let uks = ["userkey_1", "userkey_2", "userkey_3", "userkey 4", "userkey 5"];
    let apps = uks.into_iter()
                  .map(|uk| Application::from(UserKey::from(*uk)))
                  .collect::<Vec<_>>();

    println!("Apps: {:#?}", apps);

    let usages = [("metric11", 11),
                  ("metric12", 12),
                  ("metric21", 21),
                  ("metric22", 22),
                  ("metric31", 31),
                  ("metric32", 32),
                  ("metric41", 41),
                  ("metric42", 42),
                  ("metric51", 51),
                  ("metric52", 52)].chunks(2)
                                   .map(|metrics_and_values| Usage::new(metrics_and_values))
                                   .collect::<Vec<_>>();

    println!("Usages: {:#?}", usages);

    let ts = Default::default();

    let txns = apps.iter()
                   .zip(&usages)
                   .map(|(a, u)| Transaction::new(a, None, Some(u), Some(&ts)))
                   .collect::<Vec<_>>();

    let mut extensions = Extensions::new();
    extensions.insert("no_body", "1");
    extensions.insert("testing[=]", "0[=:=]0");
    let mut apicall = ApiCall::builder(&svc);
    let apicall = apicall.transactions(&txns)
                         .extensions(&extensions)
                         .kind(Kind::Report)
                         .build()?;
    let request = Request::from(&apicall);

    println!("apicall: {:#?}", apicall);
    println!("request: {:#?}", request);

    let _ = run_request(request);

    Ok(())
}

fn run_request(request: Request) -> Result<Response, reqwest::Error> {
    let client = Client::new();
    let reqbuilder = RequestBuilder::from_request(request, (&client, "https://echo-api.3scale.net"));
    let result = exec_request(reqbuilder);
    show_response(result)
}

fn exec_request(reqb: RequestBuilder) -> Result<Response, reqwest::Error> {
    println!("RequestBuilder: {:#?}", reqb);
    reqb.send()
}

fn show_response(res: Result<Response, reqwest::Error>) -> Result<Response, reqwest::Error> {
    match res {
        Ok(mut response) => {
            println!("*** SUCCESS ***\n{:#?}", response);
            let jsonval = response.json::<serde_json::Value>().unwrap();
            println!("*** BODY ***\n{}",
                     serde_json::to_string_pretty(&jsonval).unwrap());
            Ok(response)
        }
        Err(e) => {
            println!("*** ERROR ***\n{:#?}", e);
            Err(e)
        }
    }
}
<commit_msg>examples/reqwest-report: move to new SetupRequest trait<commit_after>use threescalers::{
    api_call::*,
    application::*,
    credentials::*,
    extensions::Extensions,
    http::{
        request::SetupRequest,
        Request,
    },
    service::*,
    transaction::Transaction,
    usage::Usage,
};

use reqwest::{
    Client,
    RequestBuilder,
    Response,
};

fn main() -> Result<(), threescalers::errors::Error> {
    let creds = Credentials::ServiceToken(ServiceToken::from("12[3]token"));
    let svc = Service::new("svc123", creds);
    let uks = ["userkey_1", "userkey_2", "userkey_3", "userkey 4", "userkey 5"];
    let apps = uks.into_iter()
                  .map(|uk| Application::from(UserKey::from(*uk)))
                  .collect::<Vec<_>>();

    println!("Apps: {:#?}", apps);

    let usages = [("metric11", 11),
                  ("metric12", 12),
                  ("metric21", 21),
                  ("metric22", 22),
                  ("metric31", 31),
                  ("metric32", 32),
                  ("metric41", 41),
                  ("metric42", 42),
                  ("metric51", 51),
                  ("metric52", 52)].chunks(2)
                                   .map(|metrics_and_values| Usage::new(metrics_and_values))
                                   .collect::<Vec<_>>();

    println!("Usages: {:#?}", usages);

    let ts = Default::default();

    let txns = apps.iter()
                   .zip(&usages)
                   .map(|(a, u)| Transaction::new(a, None, Some(u), Some(&ts)))
                   .collect::<Vec<_>>();

    let mut extensions = Extensions::new();
    extensions.insert("no_body", "1");
    extensions.insert("testing[=]", "0[=:=]0");
    let mut apicall = ApiCall::builder(&svc);
    let apicall = apicall.transactions(&txns)
                         .extensions(&extensions)
                         .kind(Kind::Report)
                         .build()?;
    let request = Request::from(&apicall);

    println!("apicall: {:#?}", apicall);
    println!("request: {:#?}", request);

    let _ = run_request(request);

    Ok(())
}

fn run_request(request: Request) -> Result<Response, reqwest::Error> {
    let mut client = Client::new();
    let reqbuilder = client.setup_request(request, "https://echo-api.3scale.net");
    let result = exec_request(reqbuilder);
    show_response(result)
}

fn exec_request(reqb: RequestBuilder) -> Result<Response, reqwest::Error> {
    println!("RequestBuilder: {:#?}", reqb);
    reqb.send()
}

fn show_response(res: Result<Response, reqwest::Error>) -> Result<Response, reqwest::Error> {
    match res {
        Ok(mut response) => {
            println!("*** SUCCESS ***\n{:#?}", response);
            let jsonval = response.json::<serde_json::Value>().unwrap();
            println!("*** BODY ***\n{}",
                     serde_json::to_string_pretty(&jsonval).unwrap());
            Ok(response)
        }
        Err(e) => {
            println!("*** ERROR ***\n{:#?}", e);
            Err(e)
        }
    }
}
<|endoftext|>


<commit_before>use std::sync::Arc;

use descriptor_set::AbstractDescriptorSet;
use descriptor_set::AbstractDescriptorSetLayout;
use descriptor_set::DescriptorBind;
use descriptor_set::DescriptorDesc;
use descriptor_set::SetLayout;
use descriptor_set::SetLayoutInit;
use descriptor_set::SetLayoutWrite;
use descriptor_set::DescriptorWrite;
use descriptor_set::PipelineLayoutDesc;

/// FIXME: it should be unsafe to create this struct
pub struct RuntimeDesc;

unsafe impl PipelineLayoutDesc for RuntimeDesc {
    type DescriptorSets = Vec<Arc<AbstractDescriptorSet>>;
    type DescriptorSetLayouts = Vec<Arc<AbstractDescriptorSetLayout>>;
    type PushConstants = ();

    #[inline]
    fn decode_descriptor_sets(&self, sets: Self::DescriptorSets) -> Vec<Arc<AbstractDescriptorSet>> {
        sets
    }

    #[inline]
    fn decode_descriptor_set_layouts(&self, layouts: Self::DescriptorSetLayouts)
                                     -> Vec<Arc<AbstractDescriptorSetLayout>>
    {
        layouts
    }
}

/// Implementation of `PipelineLayoutDesc` that describes an empty pipeline.
#[derive(Debug, Copy, Clone, Default)]
pub struct EmptyPipelineDesc;
unsafe impl PipelineLayoutDesc for EmptyPipelineDesc {
    type DescriptorSets = ();
    type DescriptorSetLayouts = ();
    type PushConstants = ();

    #[inline]
    fn decode_descriptor_set_layouts(&self, _: Self::DescriptorSetLayouts)
                                     -> Vec<Arc<AbstractDescriptorSetLayout>> { vec![] }
    #[inline]
    fn decode_descriptor_sets(&self, _: Self::DescriptorSets)
                              -> Vec<Arc<AbstractDescriptorSet>> { vec![] }
}

/// FIXME: should be unsafe to create this struct
pub struct RuntimeDescriptorSetDesc {
    pub descriptors: Vec<DescriptorDesc>,
}

unsafe impl SetLayout for RuntimeDescriptorSetDesc {
    fn descriptors(&self) -> Vec<DescriptorDesc> {
        self.descriptors.clone()
    }
}

unsafe impl SetLayoutWrite<Vec<(u32, DescriptorBind)>> for RuntimeDescriptorSetDesc {
    fn decode(&self, data: Vec<(u32, DescriptorBind)>) -> Vec<DescriptorWrite> {
        data.into_iter().map(|(binding, bind)| {
            // TODO: check correctness?

            DescriptorWrite {
                binding: binding,
                array_element: 0,       // FIXME:
                content: bind,
            }
        }).collect()
    }
}

unsafe impl SetLayoutInit<Vec<(u32, DescriptorBind)>> for RuntimeDescriptorSetDesc {
    fn decode(&self, data: Vec<(u32, DescriptorBind)>) -> Vec<DescriptorWrite> {
        SetLayoutWrite::decode(self, data)
    }
}
<commit_msg>RuntimeDescriptorSetDesc now more generic with what is accepts<commit_after>use std::sync::Arc;

use descriptor_set::AbstractDescriptorSet;
use descriptor_set::AbstractDescriptorSetLayout;
use descriptor_set::DescriptorBind;
use descriptor_set::DescriptorDesc;
use descriptor_set::SetLayout;
use descriptor_set::SetLayoutInit;
use descriptor_set::SetLayoutWrite;
use descriptor_set::DescriptorWrite;
use descriptor_set::PipelineLayoutDesc;

/// FIXME: it should be unsafe to create this struct
pub struct RuntimeDesc;

unsafe impl PipelineLayoutDesc for RuntimeDesc {
    type DescriptorSets = Vec<Arc<AbstractDescriptorSet>>;
    type DescriptorSetLayouts = Vec<Arc<AbstractDescriptorSetLayout>>;
    type PushConstants = ();

    #[inline]
    fn decode_descriptor_sets(&self, sets: Self::DescriptorSets) -> Vec<Arc<AbstractDescriptorSet>> {
        sets
    }

    #[inline]
    fn decode_descriptor_set_layouts(&self, layouts: Self::DescriptorSetLayouts)
                                     -> Vec<Arc<AbstractDescriptorSetLayout>>
    {
        layouts
    }
}

/// Implementation of `PipelineLayoutDesc` that describes an empty pipeline.
#[derive(Debug, Copy, Clone, Default)]
pub struct EmptyPipelineDesc;
unsafe impl PipelineLayoutDesc for EmptyPipelineDesc {
    type DescriptorSets = ();
    type DescriptorSetLayouts = ();
    type PushConstants = ();

    #[inline]
    fn decode_descriptor_set_layouts(&self, _: Self::DescriptorSetLayouts)
                                     -> Vec<Arc<AbstractDescriptorSetLayout>> { vec![] }
    #[inline]
    fn decode_descriptor_sets(&self, _: Self::DescriptorSets)
                              -> Vec<Arc<AbstractDescriptorSet>> { vec![] }
}

/// FIXME: should be unsafe to create this struct
pub struct RuntimeDescriptorSetDesc {
    pub descriptors: Vec<DescriptorDesc>,
}

unsafe impl SetLayout for RuntimeDescriptorSetDesc {
    fn descriptors(&self) -> Vec<DescriptorDesc> {
        self.descriptors.clone()
    }
}

unsafe impl<T> SetLayoutWrite<T> for RuntimeDescriptorSetDesc
    where T: IntoIterator<Item = (u32, DescriptorBind)>
{
    fn decode(&self, data: T) -> Vec<DescriptorWrite> {
        data.into_iter().map(|(binding, bind)| {
            // TODO: check correctness?

            DescriptorWrite {
                binding: binding,
                array_element: 0,       // FIXME:
                content: bind,
            }
        }).collect()
    }
}

unsafe impl<T> SetLayoutInit<T> for RuntimeDescriptorSetDesc
    where T: IntoIterator<Item = (u32, DescriptorBind)>
{
    fn decode(&self, data: T) -> Vec<DescriptorWrite> {
        SetLayoutWrite::decode(self, data)
    }
}
<|endoftext|>


<commit_before>use perlin_core::index::posting::DocId;

mod stemmers;
pub mod integers;
mod stopword_filter;

pub use language::stopword_filter::StopwordFilter;
pub use language::stemmers::Stemmer;

/// The single central trait of the push-based splittable pipeline!
/// Any element in it can be called passing a typed and generic input and a common value
pub trait CanApply<Input> {
    type Output;
    fn apply(&mut self, Input);
}

pub struct WhitespaceTokenizer<TCallback>
{
    callback: TCallback,
}

impl<TCallback> WhitespaceTokenizer<TCallback> {
    pub fn create(callback: TCallback) -> Self {
        WhitespaceTokenizer {
            callback: callback
        }
    }
}

impl<'a, TCallback> CanApply<&'a str> for WhitespaceTokenizer<TCallback>
    where TCallback: CanApply<&'a str> {
    type Output = TCallback::Output;
    fn apply(&mut self, input: &'a str) {
        for token in input.split_whitespace() {
            self.callback.apply(token);
        }
    }
}

pub struct LowercaseFilter<TCallback>
{
    callback: TCallback,
}

impl<TCallback> LowercaseFilter<TCallback> {
    pub fn create(callback: TCallback) -> Self {
        LowercaseFilter{
            callback: callback,
        }
    }
}

impl<'a, TCallback> CanApply<&'a str> for LowercaseFilter<TCallback>
    where TCallback: CanApply<String>
{
    type Output = TCallback::Output;
    fn apply(&mut self, input: &str) {
        self.callback.apply(input.to_lowercase())
    }
}

use perlin_core::index::Index;
use std::hash::Hash;

pub struct IndexerFunnel<'a, T: 'a + Hash + Eq>
{
    doc_id: DocId,
    index: &'a mut Index<T>
}

impl<'a, T: Hash + Eq> IndexerFunnel<'a, T> {
    pub fn create(doc_id: DocId, index: &'a mut Index<T>) -> Self {
        IndexerFunnel {
            doc_id: doc_id,
            index: index
        }
    }
}
use std::fmt::Debug;
impl<'a, TTerm: 'a + Debug + Hash + Ord + Eq> CanApply<TTerm> for IndexerFunnel<'a, TTerm>{

    type Output = TTerm;

    fn apply(&mut self, input: TTerm) {
        self.index.index_term(input, self.doc_id);
    }
}

#[macro_export]
macro_rules! funnel {
    ($doc_id:expr, $index:expr) => {
        IndexerFunnel::create($doc_id, $index)
    }
}

#[macro_export]
macro_rules! inner_pipeline {
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident;
     $element:ident($($param:expr),+) | [$this_field:ident] > $($x:tt)*) =>
    // ;doc_id; ;field_id; Element(params) | [field] > Next
    {
        $element::create($($param),+ ,
                         funnel!($doc_id, &mut $INDEX.$this_field),
                         inner_pipeline!(;$INDEX; ;$doc_id; ;$field_id; ($x)*))
    };
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident;
     $element:ident | [$this_field:ident] > $($x:tt)*) =>
    // ;doc_id; ;field_id; Element | [field] > Next
    {
        $element::create(
            funnel!($doc_id, &mut $INDEX.$this_field),
            inner_pipeline!(;$INDEX; ;$doc_id; ;$field; $($x)*))
    };
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident; $element:ident($($param:expr),+) > $($x:tt)*) =>
    // ;doc_id; ;field_id; Element(params) > Next
    {
        $element::create($($param),+ , inner_pipeline!(;$INDEX; ;$doc_id; ;$field; $($x)*))
    };
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident; $element:ident > $($x:tt)*) =>
    // ;doc_id; ;field_id; Element > Next
    {
        $element::create(inner_pipeline!(;$INDEX; ;$doc_id; ;$field; $($x)*))
    };
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident; $element:ident($($param:expr),+)) =>
    // ;doc_id; ;field_id; Element(params)
    {
        $element::create(
            $($param),+ ,
            inner_pipeline!(;$INDEX; ;$doc_id; ;$field;))
    };
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident; $element:ident) =>
    // ;doc_id; ;field_id; Element
    {
        $element::create(inner_pipeline!(;$INDEX; ;$doc_id; ;$field;))
    };

    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident;) => {
        IndexerFunnel::create($doc_id, &mut $INDEX.$field)
    };
    () => {}
}

#[macro_export]
macro_rules! pipeline {
    ($field:ident $($x:tt)*) => {
        Box::new(move |doc_id, index, content| {
            use $crate::language::CanApply;
            use $crate::language::IndexerFunnel;
            use std::marker::PhantomData;
            let mut pipe = inner_pipeline!(;index; ;doc_id; ;$field; $($x)*);
            pipe.apply(content);
            PhantomData
        })
    }
}

<commit_msg>simplified inner_pipeline macro<commit_after>use perlin_core::index::posting::DocId;

mod stemmers;
pub mod integers;
mod stopword_filter;

pub use language::stopword_filter::StopwordFilter;
pub use language::stemmers::Stemmer;

/// The single central trait of the push-based splittable pipeline!
/// Any element in it can be called passing a typed and generic input and a common value
pub trait CanApply<Input> {
    type Output;
    fn apply(&mut self, Input);
}

pub struct WhitespaceTokenizer<TCallback>
{
    callback: TCallback,
}

impl<TCallback> WhitespaceTokenizer<TCallback> {
    pub fn create(callback: TCallback) -> Self {
        WhitespaceTokenizer {
            callback: callback
        }
    }
}

impl<'a, TCallback> CanApply<&'a str> for WhitespaceTokenizer<TCallback>
    where TCallback: CanApply<&'a str> {
    type Output = TCallback::Output;
    fn apply(&mut self, input: &'a str) {
        for token in input.split_whitespace() {
            self.callback.apply(token);
        }
    }
}

pub struct LowercaseFilter<TCallback>
{
    callback: TCallback,
}

impl<TCallback> LowercaseFilter<TCallback> {
    pub fn create(callback: TCallback) -> Self {
        LowercaseFilter{
            callback: callback,
        }
    }
}

impl<'a, TCallback> CanApply<&'a str> for LowercaseFilter<TCallback>
    where TCallback: CanApply<String>
{
    type Output = TCallback::Output;
    fn apply(&mut self, input: &str) {
        self.callback.apply(input.to_lowercase())
    }
}

use perlin_core::index::Index;
use std::hash::Hash;

pub struct IndexerFunnel<'a, T: 'a + Hash + Eq>
{
    doc_id: DocId,
    index: &'a mut Index<T>
}

impl<'a, T: Hash + Eq> IndexerFunnel<'a, T> {
    pub fn create(doc_id: DocId, index: &'a mut Index<T>) -> Self {
        IndexerFunnel {
            doc_id: doc_id,
            index: index
        }
    }
}
use std::fmt::Debug;
impl<'a, TTerm: 'a + Debug + Hash + Ord + Eq> CanApply<TTerm> for IndexerFunnel<'a, TTerm>{

    type Output = TTerm;

    fn apply(&mut self, input: TTerm) {
        self.index.index_term(input, self.doc_id);
    }
}

#[macro_export]
macro_rules! inner_pipeline {
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident;
     > $($x:tt)*) => {
        // >
        inner_pipeline!(;$INDEX; ;$doc_id; ;$field; $($x)*)
    };
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident;
     $element:ident($($param:expr),+) | [$this_field:ident] $($x:tt)*) =>
    // ;doc_id; ;field_id; Element(params) | [field]
    {
        $element::create($($param),+ ,
                         IndexerFunnel::create($doc_id, &mut $INDEX.$this_field),
                         inner_pipeline!(;$INDEX; ;$doc_id; ;$field_id; ($x)*))
    };
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident;
     $element:ident($($param:expr),+) $($x:tt)*) =>
    // ;doc_id; ;field_id; Element(params)
    {
        $element::create($($param),+ , inner_pipeline!(;$INDEX; ;$doc_id; ;$field; $($x)*))
    };
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident;
     $element:ident | [$this_field:ident] $($x:tt)*) =>
    // ;doc_id; ;field_id; Element | [field]
    {
        $element::create(
            IndexerFunnel::create($doc_id, &mut $INDEX.$this_field),
            inner_pipeline!(;$INDEX; ;$doc_id; ;$field; $($x)*))
    };
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident;
     $element:ident $($x:tt)*) =>
    // ;doc_id; ;field_id; Element
    {
        $element::create(inner_pipeline!(;$INDEX; ;$doc_id; ;$field; $($x)*))
    };
    (;$INDEX:ident; ;$doc_id:expr; ;$field:ident;) => {
        IndexerFunnel::create($doc_id, &mut $INDEX.$field)
    };
    () => {}
}

#[macro_export]
macro_rules! pipeline {
    ($field:ident $($x:tt)*) => {
        Box::new(move |doc_id, index, content| {
            use $crate::language::CanApply;
            use $crate::language::IndexerFunnel;
            use std::marker::PhantomData;
            let mut pipe = inner_pipeline!(;index; ;doc_id; ;$field; $($x)*);
            pipe.apply(content);
            PhantomData
        })
    }
}

<|endoftext|>


<commit_before>//! Tests for containers.rs

#[cfg(test)]
mod tests {
    use super::super::containers::*;
    use std::rc::*;
    use rustwlc::handle::*;

    #[cfg(test)]
    /// Sets up a root node with 10 workspaces
    fn root_setup() -> Node {
        let mut root = Container::new_root();
        for _ in 0..10 {
            Container::new_workspace(&mut root);
        }
        root
    }

    #[test]
    #[should_panic(expected = "Can only be one root")]
    /// Test to make sure that there can be only one root node
    fn test_one_root() {
        let _root = Container::new_root();
        // Should panic
        let _root2 = Container::new_root();
        // remove when we fix it
        panic!("Can only be one root");
    }

    #[test]
    /// Verify that root node has required properties
    fn root_validity_test() {
        let main: Node = Container::new_root();
        let root = main.borrow_mut();
        // Make sure it starts with no children (but can have children)
        assert_eq!(root.get_children().unwrap().len(), 0);
        // This is the tippity-top of the tree
        assert!(root.get_parent().is_none());
        assert_eq!(root.get_type(), ContainerType::Root);
        // Should this be true? It makes sense, but it might cause complications
        // so we'll go with false for now
        assert!(! root.is_focused());
        // Root is parent of all nodes, including itself
        assert!(root.is_parent_of(main.clone()));
        // Root is not a child of anything, including itself
        // NOTE Add more test when we have more container types
        assert!(! root.is_child_of(main.clone()));
        assert_eq!(root.get_position(), (0, 0));
        assert_eq!(root.get_dimensions(), (0, 0));
        assert!(root.is_root());
    }

    #[test]
    fn workspace_validity_test() {
        let root = root_setup();
        let root_copy = Rc::make_mut(&mut root.clone()).clone().into_inner();
        assert_eq!(root.borrow().get_children().unwrap().len(), 10);
        for container_ in root.borrow().get_children().unwrap() {
            // Workspaces start out empty
            let mut container = container_.borrow_mut();
            assert_eq!(container.get_children().unwrap().len(), 0);
            let container_copy = Rc::make_mut(&mut container.get_parent().unwrap().clone()).clone().into_inner();
            assert_eq!(container_copy, root_copy);
            // NOTE add test for add_child
            assert_eq!(container.get_type(), ContainerType::Workspace);
            assert!(! container.is_focused());
            // NOTE add test for remove_child_at
            assert!(! container.get_visibility());
            container.set_visibility(true);
            assert!(container.get_visibility());
            container.set_visibility(false);
            assert!(! container.get_visibility());
            // NOTE change these once they can be set properly
            assert_eq!(container.get_dimensions(), (0,0));
            assert_eq!(container.get_position(), (0,0));
            // NOTE add test for is_parent_of
            assert!(container.is_child_of(root.clone()));
            assert!(! container.is_root());
            assert_eq!(container.get_parent_by_type(ContainerType::Root).unwrap(), root);
        }
    }

    #[test]
    fn remove_container_test() {
        let root = root_setup();
        let mut workspace = &mut root.borrow().get_children().unwrap()[0];
        let container = Container::new_container(&mut workspace, WlcView::root());

        let container_ref = Rc::downgrade(&workspace.borrow().get_children().unwrap()[0].clone());
        // Still points to the container
        assert!(container_ref.clone().upgrade().is_some());
        // removes workspace's reference to it
        container.borrow().remove_container().ok();
        // We still can see it, so it's still alive
        assert!(container_ref.clone().upgrade().is_some());
        // drop our reference to it
        drop(container);
        assert!(! container_ref.clone().upgrade().is_some());
    }

    #[test]
    #[should_panic(expect = "Cannot remove root container")]
    fn ensure_root_container_unremovable_test() {
        let root = root_setup();
        root.borrow_mut().remove_container().expect("Cannot remove root container");
    }

    #[test]
    #[should_panic(expect = "Cannot remove root container")]
    fn ensure_workspace_container_unremovable_test() {
        let root = root_setup();
        let workspace = root.borrow().get_children().unwrap()[0].clone();
        workspace.borrow_mut().remove_container().expect("Cannot remove root container");
    }

    #[test]
    #[should_panic(expect = "Only workspaces can be added to the root node")]
    /// Tests to make sure only workspaces can be children of the top node
    fn root_workspace_only() {
        let root = root_setup();
        let container = &mut root.borrow().get_children().unwrap()[0];
        Container::new_workspace(container);
    }

    #[test]
    #[should_panic(expect = "Only containers can be children of a workspace")]
    /// Tests to ensure that only containers can be the children of a workspace
    fn only_containers_for_workspace_children_test() {
        let root = root_setup();
        let container = root.borrow().get_children().unwrap()[0].clone();
        container.borrow_mut().add_child(container.clone());
    }

    #[test]
    /// Tests that you can have a root with some workspaces, that the workspaces
    /// can be removed, and that you can add simple containers to the
    /// workspaces. (Does not test views)
    fn basic_tree_test() {
        let mut root = Container::new_root();
        for _ in 0..10 {
            Container::new_workspace(&mut root);
        }
        assert_eq!(root.borrow().get_children().unwrap().len(),10);
        // Remove half the nodes
        for _ in 0..5 {
            root.borrow_mut().remove_child_at(0).ok();
        }
        assert_eq!(root.borrow().get_children().unwrap().len(),5);
        // NOTE Enhance with adding containers to the workspaces
    }

}
<commit_msg>Moved ok's to unwraps in the test so that they properly fail<commit_after>//! Tests for containers.rs

#[cfg(test)]
mod tests {
    use super::super::containers::*;
    use std::rc::*;
    use rustwlc::handle::*;

    #[cfg(test)]
    /// Sets up a root node with 10 workspaces
    fn root_setup() -> Node {
        let mut root = Container::new_root();
        for _ in 0..10 {
            Container::new_workspace(&mut root);
        }
        root
    }

    #[test]
    #[should_panic(expected = "Can only be one root")]
    /// Test to make sure that there can be only one root node
    fn test_one_root() {
        let _root = Container::new_root();
        // Should panic
        let _root2 = Container::new_root();
        // remove when we fix it
        panic!("Can only be one root");
    }

    #[test]
    /// Verify that root node has required properties
    fn root_validity_test() {
        let main: Node = Container::new_root();
        let root = main.borrow_mut();
        // Make sure it starts with no children (but can have children)
        assert_eq!(root.get_children().unwrap().len(), 0);
        // This is the tippity-top of the tree
        assert!(root.get_parent().is_none());
        assert_eq!(root.get_type(), ContainerType::Root);
        // Should this be true? It makes sense, but it might cause complications
        // so we'll go with false for now
        assert!(! root.is_focused());
        // Root is parent of all nodes, including itself
        assert!(root.is_parent_of(main.clone()));
        // Root is not a child of anything, including itself
        // NOTE Add more test when we have more container types
        assert!(! root.is_child_of(main.clone()));
        assert_eq!(root.get_position(), (0, 0));
        assert_eq!(root.get_dimensions(), (0, 0));
        assert!(root.is_root());
    }

    #[test]
    fn workspace_validity_test() {
        let root = root_setup();
        let root_copy = Rc::make_mut(&mut root.clone()).clone().into_inner();
        assert_eq!(root.borrow().get_children().unwrap().len(), 10);
        for container_ in root.borrow().get_children().unwrap() {
            // Workspaces start out empty
            let mut container = container_.borrow_mut();
            assert_eq!(container.get_children().unwrap().len(), 0);
            let container_copy = Rc::make_mut(&mut container.get_parent().unwrap().clone()).clone().into_inner();
            assert_eq!(container_copy, root_copy);
            // NOTE add test for add_child
            assert_eq!(container.get_type(), ContainerType::Workspace);
            assert!(! container.is_focused());
            // NOTE add test for remove_child_at
            assert!(! container.get_visibility());
            container.set_visibility(true);
            assert!(container.get_visibility());
            container.set_visibility(false);
            assert!(! container.get_visibility());
            // NOTE change these once they can be set properly
            assert_eq!(container.get_dimensions(), (0,0));
            assert_eq!(container.get_position(), (0,0));
            // NOTE add test for is_parent_of
            assert!(container.is_child_of(root.clone()));
            assert!(! container.is_root());
            assert_eq!(container.get_parent_by_type(ContainerType::Root).unwrap(), root);
        }
    }

    #[test]
    fn remove_container_test() {
        let root = root_setup();
        let mut workspace = &mut root.borrow().get_children().unwrap()[0];
        let container = Container::new_container(&mut workspace, WlcView::root());

        let container_ref = Rc::downgrade(&workspace.borrow().get_children().unwrap()[0].clone());
        // Still points to the container
        assert!(container_ref.clone().upgrade().is_some());
        // removes workspace's reference to it
        container.borrow().remove_container().unwrap();
        // We still can see it, so it's still alive
        assert!(container_ref.clone().upgrade().is_some());
        // drop our reference to it
        drop(container);
        assert!(! container_ref.clone().upgrade().is_some());
    }

    #[test]
    #[should_panic(expect = "Cannot remove root container")]
    fn ensure_root_container_unremovable_test() {
        let root = root_setup();
        root.borrow_mut().remove_container().expect("Cannot remove root container");
    }

    #[test]
    #[should_panic(expect = "Cannot remove root container")]
    fn ensure_workspace_container_unremovable_test() {
        let root = root_setup();
        let workspace = root.borrow().get_children().unwrap()[0].clone();
        workspace.borrow_mut().remove_container().expect("Cannot remove root container");
    }

    #[test]
    #[should_panic(expect = "Only workspaces can be added to the root node")]
    /// Tests to make sure only workspaces can be children of the top node
    fn root_workspace_only() {
        let root = root_setup();
        let container = &mut root.borrow().get_children().unwrap()[0];
        Container::new_workspace(container);
    }

    #[test]
    #[should_panic(expect = "Only containers can be children of a workspace")]
    /// Tests to ensure that only containers can be the children of a workspace
    fn only_containers_for_workspace_children_test() {
        let root = root_setup();
        let container = root.borrow().get_children().unwrap()[0].clone();
        container.borrow_mut().add_child(container.clone());
    }

    #[test]
    /// Tests that you can have a root with some workspaces, that the workspaces
    /// can be removed, and that you can add simple containers to the
    /// workspaces. (Does not test views)
    fn basic_tree_test() {
        let mut root = root_setup();
        assert_eq!(root.borrow().get_children().unwrap().len(),10);
        // Remove half the nodes
        for _ in 0..5 {
            root.borrow_mut().remove_child_at(0).unwrap();
        }
        assert_eq!(root.borrow().get_children().unwrap().len(),5);
        // NOTE Enhance with adding containers to the workspaces
    }

}
<|endoftext|>


<commit_before>extern crate hyper;
extern crate multipart;

use hyper::Client;

use multipart::client::lazy::Multipart;

fn main() {
    let mut binary = "Hello world in binary!".as_bytes();

    let _response = Multipart::new()
        .add_text("text", "Hello, world!")
        .add_file("file", "lorem_ipsum.txt")
        // A little extra type info needed.
        .add_stream("binary", &mut binary, None as Option<&str>, None)
        .client_request(&Client::new(), "http://localhost:80")
        .expect("Error sending multipart request");
}<commit_msg>Add comment to hyper_reqbuilder example<commit_after>extern crate hyper;
extern crate multipart;

use hyper::Client;

use multipart::client::lazy::Multipart;

fn main() {
    let mut binary = "Hello world in binary!".as_bytes();

    let _response = Multipart::new()
        .add_text("text", "Hello, world!")
        .add_file("file", "lorem_ipsum.txt")
        // A little extra type info needed.
        .add_stream("binary", &mut binary, None as Option<&str>, None)
        // Request is sent here
        .client_request(&Client::new(), "http://localhost:80")
        .expect("Error sending multipart request");
}<|endoftext|>


<commit_before>use std::collections::HashMap;

#[derive(Serialize, Deserialize, Debug)]
pub struct Account {
    pub short_name: String,
    pub author_name: String,
    pub author_url: String,

    #[serde(default)]
    pub access_token: String,

    #[serde(default)]
    pub auth_url: String,

    #[serde(default)]
    pub page_count: i32,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct CreateAccountResponse {
    pub ok: bool,
    pub result: Account,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Page {
    pub path: String,
    pub url: String,
    pub title: String,
    pub description: String,

    #[serde(default)]
    pub author_name: String,

    #[serde(default)]
    pub author_url: String,

    #[serde(default)]
    pub image_url: String,

    #[serde(default)]
    pub content: Vec<Node>,
    pub views: i32,

    #[serde(default)]
    pub can_edit: bool,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct PageList {
    pub total_count: i32,
    pub pages: Vec<Page>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct PageViews {
    pub views: i32,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Node {}

#[derive(Serialize, Deserialize, Debug)]
pub struct NodeElement {
    pub tag: String,

    #[serde(default)]
    pub attrs: HashMap<String, String>,

    #[serde(default)]
    pub children: Vec<Node>,
}
<commit_msg>added EditAccountResponse type and did all Account fields optional<commit_after>use std::collections::HashMap;

#[derive(Serialize, Deserialize, Debug)]
pub struct Account {
    #[serde(default)]
    pub short_name: String,

    #[serde(default)]
    pub author_name: String,

    #[serde(default)]
    pub author_url: String,

    #[serde(default)]
    pub access_token: String,

    #[serde(default)]
    pub auth_url: String,

    #[serde(default)]
    pub page_count: i32,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct CreateAccountResponse {
    pub ok: bool,
    pub result: Account,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct EditAccountResponse {
    pub ok: bool,
    pub result: Account,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Page {
    pub path: String,
    pub url: String,
    pub title: String,
    pub description: String,

    #[serde(default)]
    pub author_name: String,

    #[serde(default)]
    pub author_url: String,

    #[serde(default)]
    pub image_url: String,

    #[serde(default)]
    pub content: Vec<Node>,
    pub views: i32,

    #[serde(default)]
    pub can_edit: bool,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct PageList {
    pub total_count: i32,
    pub pages: Vec<Page>,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct PageViews {
    pub views: i32,
}

#[derive(Serialize, Deserialize, Debug)]
pub struct Node {}

#[derive(Serialize, Deserialize, Debug)]
pub struct NodeElement {
    pub tag: String,

    #[serde(default)]
    pub attrs: HashMap<String, String>,

    #[serde(default)]
    pub children: Vec<Node>,
}
<|endoftext|>


<commit_before>// Copyright 2017 The Exonum Team
//
// 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.

use std::io;

use bytes::BytesMut;
use byteorder::{LittleEndian, ByteOrder};
use tokio_io::codec::{Decoder, Encoder};

use messages::{HEADER_LENGTH, MessageBuffer, RawMessage};
use super::error::other_error;

pub const MAX_MESSAGE_LEN: usize = 1024 * 1024; // 1 MB

#[derive(Debug)]
pub struct MessagesCodec;

impl Decoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
        // Read header
        if buf.len() < HEADER_LENGTH {
            return Ok(None);
        }
        // Check payload len
        let total_len = LittleEndian::read_u32(&buf[6..10]) as usize;
        if total_len > MAX_MESSAGE_LEN {
            return Err(other_error(format!(
                "Received message is too long: {}, maximum allowed length is {}",
                total_len,
                MAX_MESSAGE_LEN
            )));
        }

        // Read message
        if buf.len() >= total_len {
            let data = buf.split_to(total_len).to_vec();
            let raw = RawMessage::new(MessageBuffer::from_vec(data));
            return Ok(Some(raw));
        }
        Ok(None)
    }
}

impl Encoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> io::Result<()> {
        buf.extend_from_slice(msg.as_ref());
        Ok(())
    }
}
<commit_msg>Fix a bug with codec that cause node to panic.<commit_after>// Copyright 2017 The Exonum Team
//
// 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.

use std::io;

use bytes::BytesMut;
use byteorder::{LittleEndian, ByteOrder};
use tokio_io::codec::{Decoder, Encoder};

use messages::{HEADER_LENGTH, MessageBuffer, RawMessage};
use super::error::other_error;

pub const MAX_MESSAGE_LEN: usize = 1024 * 1024; // 1 MB

#[derive(Debug)]
pub struct MessagesCodec;

impl Decoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn decode(&mut self, buf: &mut BytesMut) -> Result<Option<Self::Item>, io::Error> {
        // Read header
        if buf.len() < HEADER_LENGTH {
            return Ok(None);
        }
        // Check payload len
        let total_len = LittleEndian::read_u32(&buf[6..10]) as usize;

        if total_len > MAX_MESSAGE_LEN {
            return Err(other_error(format!(
                "Received message is too long: {}, maximum allowed length is {}",
                total_len,
                MAX_MESSAGE_LEN
            )));
        }
        if total_len < HEADER_LENGTH {
            return Err(other_error(format!(
                "Received malicious message with insufficient \
                size in header: {}, expected header size {}",
                total_len,
                HEADER_LENGTH
            )));
        }
        // Read message
        if buf.len() >= total_len {
            let data = buf.split_to(total_len).to_vec();
            let raw = RawMessage::new(MessageBuffer::from_vec(data));
            return Ok(Some(raw));
        }
        Ok(None)
    }
}

impl Encoder for MessagesCodec {
    type Item = RawMessage;
    type Error = io::Error;

    fn encode(&mut self, msg: Self::Item, buf: &mut BytesMut) -> io::Result<()> {
        buf.extend_from_slice(msg.as_ref());
        Ok(())
    }
}

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

    use messages::{MessageBuffer, RawMessage};
    use bytes::BytesMut;
    use tokio_io::codec::Decoder;
    #[test]
    fn decode_message_valid_header_size() {
        let data = vec![0u8, 0, 0, 0, 0, 0, 10, 0, 0, 0];
        let mut bytes: BytesMut = data.as_slice().into();
        let mut codec = MessagesCodec;
        match codec.decode(&mut bytes) {
            Ok(Some(ref r)) if r == &RawMessage::new(MessageBuffer::from_vec(data)) => {}
            _ => panic!("Wrong input"),
        };
    }

    #[test]
    fn decode_message_small_size_in_header() {
        let data = vec![0u8, 0, 0, 0, 0, 0, 0, 0, 0, 0];
        let mut bytes: BytesMut = data.as_slice().into();
        let mut codec = MessagesCodec;
        assert!(codec.decode(&mut bytes).is_err());
    }
}
<|endoftext|>


<commit_before>use std::sync::Arc;

use ra_syntax::ast::{NameOwner};

use crate::{
    Name, AsName, Const, ConstSignature, Static,
    type_ref::{TypeRef},
    PersistentHirDatabase,
};

impl ConstSignature {
    pub(crate) fn const_signature_query(
        db: &impl PersistentHirDatabase,
        konst: Const,
    ) -> Arc<ConstSignature> {
        let (_, node) = konst.source(db);

        let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);

        let type_ref = TypeRef::from_ast_opt(node.type_ref());

        let sig = ConstSignature { name, type_ref };

        Arc::new(sig)
    }

    pub(crate) fn static_signature_query(
        db: &impl PersistentHirDatabase,
        konst: Static,
    ) -> Arc<ConstSignature> {
        let (_, node) = konst.source(db);

        let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);

        let type_ref = TypeRef::from_ast_opt(node.type_ref());

        let sig = ConstSignature { name, type_ref };

        Arc::new(sig)
    }
}
<commit_msg>Move ConstSignature creation to a single method<commit_after>use std::sync::Arc;

use ra_syntax::ast::{self, NameOwner};

use crate::{
    Name, AsName, Const, ConstSignature, Static,
    type_ref::{TypeRef},
    PersistentHirDatabase,
};

fn const_signature_for<N: NameOwner>(
    node: &N,
    type_ref: Option<&ast::TypeRef>,
) -> Arc<ConstSignature> {
    let name = node.name().map(|n| n.as_name()).unwrap_or_else(Name::missing);
    let type_ref = TypeRef::from_ast_opt(type_ref);
    let sig = ConstSignature { name, type_ref };
    Arc::new(sig)
}

impl ConstSignature {
    pub(crate) fn const_signature_query(
        db: &impl PersistentHirDatabase,
        konst: Const,
    ) -> Arc<ConstSignature> {
        let (_, node) = konst.source(db);
        const_signature_for(&*node, node.type_ref())
    }

    pub(crate) fn static_signature_query(
        db: &impl PersistentHirDatabase,
        konst: Static,
    ) -> Arc<ConstSignature> {
        let (_, node) = konst.source(db);
        const_signature_for(&*node, node.type_ref())
    }
}
<|endoftext|>


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

use std::{convert::TryInto, fs::File, io::Write, path::Path};

use indexmap::map::IndexMap as HashMap;

use assert_cmd::Command;
use autocxx_integration_tests::{build_from_folder, RsFindMode};
use itertools::Itertools;
use tempdir::TempDir;

static MAIN_RS: &str = concat!(
    include_str!("../../../demo/src/main.rs"),
    "#[link(name = \"autocxx-demo\")]\nextern \"C\" {}"
);
static INPUT_H: &str = include_str!("../../../demo/src/input.h");
static BLANK: &str = "// Blank autocxx placeholder";

static MAIN2_RS: &str = concat!(
    include_str!("data/main2.rs"),
    "#[link(name = \"autocxx-demo\")]\nextern \"C\" {}"
);
static DIRECTIVE1_RS: &str = include_str!("data/directive1.rs");
static DIRECTIVE2_RS: &str = include_str!("data/directive2.rs");
static INPUT2_H: &str = include_str!("data/input2.h");
static INPUT3_H: &str = include_str!("data/input3.h");

const KEEP_TEMPDIRS: bool = false;

#[test]
fn test_help() -> Result<(), Box<dyn std::error::Error>> {
    let mut cmd = Command::cargo_bin("autocxx-gen")?;
    cmd.arg("-h").assert().success();
    Ok(())
}

enum RsGenMode {
    Single,
    Archive,
}

fn base_test<F>(
    tmp_dir: &TempDir,
    rs_gen_mode: RsGenMode,
    arg_modifier: F,
) -> Result<(), Box<dyn std::error::Error>>
where
    F: FnOnce(&mut Command),
{
    let mut standard_files = HashMap::new();
    standard_files.insert("input.h", INPUT_H.as_bytes());
    standard_files.insert("main.rs", MAIN_RS.as_bytes());
    let result = base_test_ex(
        tmp_dir,
        rs_gen_mode,
        arg_modifier,
        standard_files,
        vec!["main.rs"],
    );
    assert_contentful(tmp_dir, "gen0.cc");
    result
}

fn base_test_ex<F>(
    tmp_dir: &TempDir,
    rs_gen_mode: RsGenMode,
    arg_modifier: F,
    files_to_write: HashMap<&str, &[u8]>,
    files_to_process: Vec<&str>,
) -> Result<(), Box<dyn std::error::Error>>
where
    F: FnOnce(&mut Command),
{
    let demo_code_dir = tmp_dir.path().join("demo");
    std::fs::create_dir(&demo_code_dir).unwrap();
    for (filename, content) in files_to_write {
        write_to_file(&demo_code_dir, filename, content);
    }
    let mut cmd = Command::cargo_bin("autocxx-gen")?;
    arg_modifier(&mut cmd);
    cmd.arg("--inc")
        .arg(demo_code_dir.to_str().unwrap())
        .arg("--outdir")
        .arg(tmp_dir.path().to_str().unwrap())
        .arg("--gen-cpp");
    cmd.arg(match rs_gen_mode {
        RsGenMode::Single => "--gen-rs-include",
        RsGenMode::Archive => "--gen-rs-archive",
    });
    for file in files_to_process {
        cmd.arg(demo_code_dir.join(file));
    }
    let output = cmd.output();
    if let Ok(output) = output {
        eprintln!("Cmd stdout: {:?}", std::str::from_utf8(&output.stdout));
        eprintln!("Cmd stderr: {:?}", std::str::from_utf8(&output.stderr));
    }
    cmd.assert().success();
    Ok(())
}

#[test]
fn test_gen() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    base_test(&tmp_dir, RsGenMode::Single, |_| {})?;
    File::create(tmp_dir.path().join("cxx.h"))
        .and_then(|mut cxx_h| cxx_h.write_all(autocxx_engine::HEADER.as_bytes()))?;
    std::env::set_var("OUT_DIR", tmp_dir.path().to_str().unwrap());
    let r = build_from_folder(
        tmp_dir.path(),
        &tmp_dir.path().join("demo/main.rs"),
        vec![tmp_dir.path().join("autocxx-ffi-default-gen.rs")],
        &["gen0.cc"],
        RsFindMode::AutocxxRs,
    );
    if KEEP_TEMPDIRS {
        println!("Tempdir: {:?}", tmp_dir.into_path().to_str());
    }
    r.unwrap();
    Ok(())
}

#[test]
fn test_gen_archive() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    base_test(&tmp_dir, RsGenMode::Archive, |_| {})?;
    File::create(tmp_dir.path().join("cxx.h"))
        .and_then(|mut cxx_h| cxx_h.write_all(autocxx_engine::HEADER.as_bytes()))?;
    let r = build_from_folder(
        tmp_dir.path(),
        &tmp_dir.path().join("demo/main.rs"),
        vec![tmp_dir.path().join("gen.rs.json")],
        &["gen0.cc"],
        RsFindMode::AutocxxRsArchive,
    );
    if KEEP_TEMPDIRS {
        println!("Tempdir: {:?}", tmp_dir.into_path().to_str());
    }
    r.unwrap();
    Ok(())
}

#[test]
fn test_gen_multiple_in_archive() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;

    let mut files = HashMap::new();
    files.insert("input2.h", INPUT2_H.as_bytes());
    files.insert("input3.h", INPUT3_H.as_bytes());
    files.insert("main.rs", MAIN2_RS.as_bytes());
    files.insert("directive1.rs", DIRECTIVE1_RS.as_bytes());
    files.insert("directive2.rs", DIRECTIVE2_RS.as_bytes());
    base_test_ex(
        &tmp_dir,
        RsGenMode::Archive,
        |cmd| {
            cmd.arg("--generate-exact").arg("8");
        },
        files,
        vec!["directive1.rs", "directive2.rs"],
    )?;
    File::create(tmp_dir.path().join("cxx.h"))
        .and_then(|mut cxx_h| cxx_h.write_all(autocxx_engine::HEADER.as_bytes()))?;
    // We've asked to create 8 C++ files, mostly blank. Build 'em all.
    let cpp_files = (0..7).map(|id| format!("gen{}.cc", id)).collect_vec();
    let cpp_files = cpp_files.iter().map(|s| s.as_str()).collect_vec();
    let r = build_from_folder(
        tmp_dir.path(),
        &tmp_dir.path().join("demo/main.rs"),
        vec![tmp_dir.path().join("gen.rs.json")],
        &cpp_files,
        RsFindMode::AutocxxRsArchive,
    );
    if KEEP_TEMPDIRS {
        println!("Tempdir: {:?}", tmp_dir.into_path().to_str());
    }
    r.unwrap();
    Ok(())
}

#[test]
fn test_include_prefixes() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    base_test(&tmp_dir, RsGenMode::Single, |cmd| {
        cmd.arg("--cxx-h-path")
            .arg("foo/")
            .arg("--cxxgen-h-path")
            .arg("bar/")
            .arg("--generate-exact")
            .arg("3");
    })?;
    assert_contains(&tmp_dir, "autocxxgen0.h", "foo/cxx.h");
    // Currently we don't test cxxgen-h-path because we build the demo code
    // which doesn't refer to generated cxx header code.
    Ok(())
}

#[test]
fn test_gen_fixed_num() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    let depfile = tmp_dir.path().join("test.d");
    base_test(&tmp_dir, RsGenMode::Single, |cmd| {
        cmd.arg("--generate-exact")
            .arg("2")
            .arg("--depfile")
            .arg(depfile);
    })?;
    assert_contentful(&tmp_dir, "gen0.cc");
    assert_contentful(&tmp_dir, "gen0.h");
    assert_not_contentful(&tmp_dir, "gen1.cc");
    assert_contentful(&tmp_dir, "autocxxgen0.h");
    assert_not_contentful(&tmp_dir, "gen1.h");
    assert_not_contentful(&tmp_dir, "autocxxgen1.h");
    assert_contentful(&tmp_dir, "autocxx-ffi-default-gen.rs");
    assert_contentful(&tmp_dir, "test.d");
    File::create(tmp_dir.path().join("cxx.h"))
        .and_then(|mut cxx_h| cxx_h.write_all(autocxx_engine::HEADER.as_bytes()))?;
    let r = build_from_folder(
        tmp_dir.path(),
        &tmp_dir.path().join("demo/main.rs"),
        vec![tmp_dir.path().join("autocxx-ffi-default-gen.rs")],
        &["gen0.cc"],
        RsFindMode::AutocxxRs,
    );
    if KEEP_TEMPDIRS {
        println!("Tempdir: {:?}", tmp_dir.into_path().to_str());
    }
    r.unwrap();
    Ok(())
}

#[test]
fn test_gen_preprocess() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    let prepro_path = tmp_dir.path().join("preprocessed.h");
    base_test(&tmp_dir, RsGenMode::Single, |cmd| {
        cmd.env("AUTOCXX_PREPROCESS", prepro_path.to_str().unwrap());
    })?;
    assert_contentful(&tmp_dir, "preprocessed.h");
    // Check that a random thing from one of the headers in
    // `ALL_KNOWN_SYSTEM_HEADERS` is included.
    assert!(std::fs::read_to_string(prepro_path)?.contains("integer_sequence"));
    Ok(())
}

#[test]
fn test_gen_repro() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    let repro_path = tmp_dir.path().join("repro.json");
    base_test(&tmp_dir, RsGenMode::Single, |cmd| {
        cmd.env("AUTOCXX_REPRO_CASE", repro_path.to_str().unwrap());
    })?;
    assert_contentful(&tmp_dir, "repro.json");
    // Check that a random thing from one of the headers in
    // `ALL_KNOWN_SYSTEM_HEADERS` is included.
    assert!(std::fs::read_to_string(repro_path)?.contains("integer_sequence"));
    Ok(())
}

fn write_to_file(dir: &Path, filename: &str, content: &[u8]) {
    let path = dir.join(filename);
    let mut f = File::create(&path).expect("Unable to create file");
    f.write_all(content).expect("Unable to write file");
}

fn assert_contentful(outdir: &TempDir, fname: &str) {
    let p = outdir.path().join(fname);
    if !p.exists() {
        panic!("File {} didn't exist", p.to_string_lossy());
    }
    assert!(
        p.metadata().unwrap().len() > BLANK.len().try_into().unwrap(),
        "File {} is empty",
        fname
    );
}

fn assert_not_contentful(outdir: &TempDir, fname: &str) {
    let p = outdir.path().join(fname);
    if !p.exists() {
        panic!("File {} didn't exist", p.to_string_lossy());
    }
    assert!(
        p.metadata().unwrap().len() <= BLANK.len().try_into().unwrap(),
        "File {} is not empty; it contains {}",
        fname,
        std::fs::read_to_string(&p).unwrap_or_default()
    );
}

fn assert_contains(outdir: &TempDir, fname: &str, pattern: &str) {
    let p = outdir.path().join(fname);
    let content = std::fs::read_to_string(&p).expect(fname);
    eprintln!("content = {}", content);
    assert!(content.contains(pattern));
}
<commit_msg>Fix gen tests.<commit_after>// Copyright 2020 Google LLC
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// https://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or https://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use std::{convert::TryInto, fs::File, io::Write, path::Path};

use indexmap::map::IndexMap as HashMap;

use assert_cmd::Command;
use autocxx_integration_tests::{build_from_folder, RsFindMode};
use itertools::Itertools;
use tempdir::TempDir;

static MAIN_RS: &str = concat!(
    include_str!("../../../demo/src/main.rs"),
    "#[link(name = \"autocxx-demo\")]\nextern \"C\" {}"
);
static INPUT_H: &str = include_str!("../../../demo/src/input.h");
static BLANK: &str = "// Blank autocxx placeholder";

static MAIN2_RS: &str = concat!(
    include_str!("data/main2.rs"),
    "#[link(name = \"autocxx-demo\")]\nextern \"C\" {}"
);
static DIRECTIVE1_RS: &str = include_str!("data/directive1.rs");
static DIRECTIVE2_RS: &str = include_str!("data/directive2.rs");
static INPUT2_H: &str = include_str!("data/input2.h");
static INPUT3_H: &str = include_str!("data/input3.h");

const KEEP_TEMPDIRS: bool = false;

#[test]
fn test_help() -> Result<(), Box<dyn std::error::Error>> {
    let mut cmd = Command::cargo_bin("autocxx-gen")?;
    cmd.arg("-h").assert().success();
    Ok(())
}

enum RsGenMode {
    Single,
    Archive,
}

fn base_test<F>(
    tmp_dir: &TempDir,
    rs_gen_mode: RsGenMode,
    arg_modifier: F,
) -> Result<(), Box<dyn std::error::Error>>
where
    F: FnOnce(&mut Command),
{
    let mut standard_files = HashMap::new();
    standard_files.insert("input.h", INPUT_H.as_bytes());
    standard_files.insert("main.rs", MAIN_RS.as_bytes());
    let result = base_test_ex(
        tmp_dir,
        rs_gen_mode,
        arg_modifier,
        standard_files,
        vec!["main.rs"],
    );
    assert_contentful(tmp_dir, "gen0.cc");
    result
}

fn base_test_ex<F>(
    tmp_dir: &TempDir,
    rs_gen_mode: RsGenMode,
    arg_modifier: F,
    files_to_write: HashMap<&str, &[u8]>,
    files_to_process: Vec<&str>,
) -> Result<(), Box<dyn std::error::Error>>
where
    F: FnOnce(&mut Command),
{
    let demo_code_dir = tmp_dir.path().join("demo");
    std::fs::create_dir(&demo_code_dir).unwrap();
    for (filename, content) in files_to_write {
        write_to_file(&demo_code_dir, filename, content);
    }
    let mut cmd = Command::cargo_bin("autocxx-gen")?;
    arg_modifier(&mut cmd);
    cmd.arg("--inc")
        .arg(demo_code_dir.to_str().unwrap())
        .arg("--outdir")
        .arg(tmp_dir.path().to_str().unwrap())
        .arg("--gen-cpp");
    cmd.arg(match rs_gen_mode {
        RsGenMode::Single => "--gen-rs-include",
        RsGenMode::Archive => "--gen-rs-archive",
    });
    for file in files_to_process {
        cmd.arg(demo_code_dir.join(file));
    }
    let output = cmd.output();
    if let Ok(output) = output {
        eprintln!("Cmd stdout: {:?}", std::str::from_utf8(&output.stdout));
        eprintln!("Cmd stderr: {:?}", std::str::from_utf8(&output.stderr));
    }
    cmd.assert().success();
    Ok(())
}

#[test]
fn test_gen() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    base_test(&tmp_dir, RsGenMode::Single, |_| {})?;
    File::create(tmp_dir.path().join("cxx.h"))
        .and_then(|mut cxx_h| cxx_h.write_all(autocxx_engine::HEADER.as_bytes()))?;
    std::env::set_var("OUT_DIR", tmp_dir.path().to_str().unwrap());
    let r = build_from_folder(
        tmp_dir.path(),
        &tmp_dir.path().join("demo/main.rs"),
        vec![tmp_dir.path().join("autocxx-ffi-default-gen.rs")],
        &["gen0.cc"],
        RsFindMode::AutocxxRs,
    );
    if KEEP_TEMPDIRS {
        println!("Tempdir: {:?}", tmp_dir.into_path().to_str());
    }
    r.unwrap();
    Ok(())
}

#[test]
fn test_gen_archive() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    base_test(&tmp_dir, RsGenMode::Archive, |_| {})?;
    File::create(tmp_dir.path().join("cxx.h"))
        .and_then(|mut cxx_h| cxx_h.write_all(autocxx_engine::HEADER.as_bytes()))?;
    let r = build_from_folder(
        tmp_dir.path(),
        &tmp_dir.path().join("demo/main.rs"),
        vec![tmp_dir.path().join("gen.rs.json")],
        &["gen0.cc"],
        RsFindMode::AutocxxRsArchive,
    );
    if KEEP_TEMPDIRS {
        println!("Tempdir: {:?}", tmp_dir.into_path().to_str());
    }
    r.unwrap();
    Ok(())
}

#[test]
fn test_gen_multiple_in_archive() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;

    let mut files = HashMap::new();
    files.insert("input2.h", INPUT2_H.as_bytes());
    files.insert("input3.h", INPUT3_H.as_bytes());
    files.insert("main.rs", MAIN2_RS.as_bytes());
    files.insert("directive1.rs", DIRECTIVE1_RS.as_bytes());
    files.insert("directive2.rs", DIRECTIVE2_RS.as_bytes());
    base_test_ex(
        &tmp_dir,
        RsGenMode::Archive,
        |cmd| {
            cmd.arg("--generate-exact").arg("8");
        },
        files,
        vec!["directive1.rs", "directive2.rs"],
    )?;
    File::create(tmp_dir.path().join("cxx.h"))
        .and_then(|mut cxx_h| cxx_h.write_all(autocxx_engine::HEADER.as_bytes()))?;
    // We've asked to create 8 C++ files, mostly blank. Build 'em all.
    let cpp_files = (0..7).map(|id| format!("gen{}.cc", id)).collect_vec();
    let cpp_files = cpp_files.iter().map(|s| s.as_str()).collect_vec();
    let r = build_from_folder(
        tmp_dir.path(),
        &tmp_dir.path().join("demo/main.rs"),
        vec![tmp_dir.path().join("gen.rs.json")],
        &cpp_files,
        RsFindMode::AutocxxRsArchive,
    );
    if KEEP_TEMPDIRS {
        println!("Tempdir: {:?}", tmp_dir.into_path().to_str());
    }
    r.unwrap();
    Ok(())
}

#[test]
fn test_include_prefixes() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    base_test(&tmp_dir, RsGenMode::Single, |cmd| {
        cmd.arg("--cxx-h-path")
            .arg("foo/")
            .arg("--cxxgen-h-path")
            .arg("bar/")
            .arg("--generate-exact")
            .arg("3")
            .arg("--fix-rs-include-name");
    })?;
    assert_contains(&tmp_dir, "autocxxgen0.h", "foo/cxx.h");
    // Currently we don't test cxxgen-h-path because we build the demo code
    // which doesn't refer to generated cxx header code.
    Ok(())
}

#[test]
fn test_gen_fixed_num() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    let depfile = tmp_dir.path().join("test.d");
    base_test(&tmp_dir, RsGenMode::Single, |cmd| {
        cmd.arg("--generate-exact")
            .arg("2")
            .arg("--fix-rs-include-name")
            .arg("--depfile")
            .arg(depfile);
    })?;
    assert_contentful(&tmp_dir, "gen0.cc");
    assert_contentful(&tmp_dir, "gen0.h");
    assert_not_contentful(&tmp_dir, "gen1.cc");
    assert_contentful(&tmp_dir, "autocxxgen0.h");
    assert_not_contentful(&tmp_dir, "gen1.h");
    assert_not_contentful(&tmp_dir, "autocxxgen1.h");
    assert_contentful(&tmp_dir, "gen0.include.rs");
    assert_contentful(&tmp_dir, "test.d");
    File::create(tmp_dir.path().join("cxx.h"))
        .and_then(|mut cxx_h| cxx_h.write_all(autocxx_engine::HEADER.as_bytes()))?;
    let r = build_from_folder(
        tmp_dir.path(),
        &tmp_dir.path().join("demo/main.rs"),
        vec![tmp_dir.path().join("autocxx-ffi-default-gen.rs")],
        &["gen0.cc"],
        RsFindMode::AutocxxRs,
    );
    if KEEP_TEMPDIRS {
        println!("Tempdir: {:?}", tmp_dir.into_path().to_str());
    }
    r.unwrap();
    Ok(())
}

#[test]
fn test_gen_preprocess() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    let prepro_path = tmp_dir.path().join("preprocessed.h");
    base_test(&tmp_dir, RsGenMode::Single, |cmd| {
        cmd.env("AUTOCXX_PREPROCESS", prepro_path.to_str().unwrap());
    })?;
    assert_contentful(&tmp_dir, "preprocessed.h");
    // Check that a random thing from one of the headers in
    // `ALL_KNOWN_SYSTEM_HEADERS` is included.
    assert!(std::fs::read_to_string(prepro_path)?.contains("integer_sequence"));
    Ok(())
}

#[test]
fn test_gen_repro() -> Result<(), Box<dyn std::error::Error>> {
    let tmp_dir = TempDir::new("example")?;
    let repro_path = tmp_dir.path().join("repro.json");
    base_test(&tmp_dir, RsGenMode::Single, |cmd| {
        cmd.env("AUTOCXX_REPRO_CASE", repro_path.to_str().unwrap());
    })?;
    assert_contentful(&tmp_dir, "repro.json");
    // Check that a random thing from one of the headers in
    // `ALL_KNOWN_SYSTEM_HEADERS` is included.
    assert!(std::fs::read_to_string(repro_path)?.contains("integer_sequence"));
    Ok(())
}

fn write_to_file(dir: &Path, filename: &str, content: &[u8]) {
    let path = dir.join(filename);
    let mut f = File::create(&path).expect("Unable to create file");
    f.write_all(content).expect("Unable to write file");
}

fn assert_contentful(outdir: &TempDir, fname: &str) {
    let p = outdir.path().join(fname);
    if !p.exists() {
        panic!("File {} didn't exist", p.to_string_lossy());
    }
    assert!(
        p.metadata().unwrap().len() > BLANK.len().try_into().unwrap(),
        "File {} is empty",
        fname
    );
}

fn assert_not_contentful(outdir: &TempDir, fname: &str) {
    let p = outdir.path().join(fname);
    if !p.exists() {
        panic!("File {} didn't exist", p.to_string_lossy());
    }
    assert!(
        p.metadata().unwrap().len() <= BLANK.len().try_into().unwrap(),
        "File {} is not empty; it contains {}",
        fname,
        std::fs::read_to_string(&p).unwrap_or_default()
    );
}

fn assert_contains(outdir: &TempDir, fname: &str, pattern: &str) {
    let p = outdir.path().join(fname);
    let content = std::fs::read_to_string(&p).expect(fname);
    eprintln!("content = {}", content);
    assert!(content.contains(pattern));
}
<|endoftext|>


<commit_before>extern crate crossbeam;
extern crate clap;
#[macro_use] extern crate version;
#[macro_use] extern crate log;
extern crate walkdir;

extern crate libimagrt;
extern crate libimagerror;

use std::env;
use std::process::exit;
use std::process::Command;
use std::process::Stdio;
use std::io::ErrorKind;

use walkdir::WalkDir;
use crossbeam::*;
use clap::{Arg, AppSettings, SubCommand};

use libimagrt::runtime::Runtime;
use libimagerror::trace::trace_error;

fn help_text(cmds: Vec<String>) -> String {
    let text = format!(r#"

     _
    (_)_ __ ___   __ _  __ _
    | | '_ \` _ \/ _\`|/ _\`|
    | | | | | | | (_| | (_| |
    |_|_| |_| |_|\__,_|\__, |
                       |___/
    -------------------------

    Usage: imag [--version | --versions | -h | --help] <command> <args...>

    imag - the personal information management suite for the commandline

    imag is a PIM suite for the commandline. It consists of several commands,
    called "modules". Each module implements one PIM aspect and all of these
    modules can be used independently.

    Available commands:

    {imagbins}

    Call a command with 'imag <command> <args>'
    Each command can be called with "--help" to get the respective helptext.

    Please visit https://github.com/matthiasbeyer/imag to view the source code,
    follow the development of imag or maybe even contribute to imag.

    imag is free software. It is released under the terms of LGPLv2.1

    (c) 2016 Matthias Beyer and contributors"#, imagbins = cmds.into_iter()
        .map(|cmd| format!("\t{}\n", cmd))
        .fold(String::new(), |s, c| {
            let s = s + c.as_str();
            s
        }));
    text
}

fn get_commands() -> Vec<String> {
    let path = env::var("PATH");
    if path.is_err() {
        println!("PATH error: {:?}", path);
        exit(1);
    }
    let pathelements = path.unwrap();
    let pathelements = pathelements.split(":");

    let joinhandles : Vec<ScopedJoinHandle<Vec<String>>> = pathelements
        .map(|elem| {
            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    WalkDir::new(elem)
                        .max_depth(1)
                        .into_iter()
                        .filter(|path| {
                            match path {
                                &Ok(ref p) => p.file_name()
                                    .to_str()
                                    .map_or(false, |filename| filename.starts_with("imag-")),
                                &Err(_)   => false,
                            }
                        })
                        .filter_map(|x| x.ok())
                        .filter_map(|path| {
                           path.file_name()
                               .to_str()
                               .and_then(|s| s.splitn(2, "-").nth(1).map(String::from))
                        })
                        .collect()
                })
            })
        })
        .collect();

    let mut execs = vec![];
    for joinhandle in joinhandles.into_iter() {
        let mut v = joinhandle.join();
        execs.append(&mut v);
    }

    execs
}

fn main() {
    let appname  = "imag";
    let version  = &version!();
    let about    = "imag - the PIM suite for the commandline";
    let commands = get_commands();
    let helptext = help_text(commands);
    let app      = Runtime::get_default_cli_builder(appname, version, about)
        .settings(&[AppSettings::AllowExternalSubcommands, AppSettings::ArgRequiredElseHelp])
        .arg(Arg::with_name("version")
             .long("version")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Get the version of imag"))
        .arg(Arg::with_name("versions")
             .long("versions")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Get the versions of the imag commands"))
        .subcommand(SubCommand::with_name("help").help("Show help"))
        .help(helptext.as_str());
    let rt = Runtime::new(app)
        .unwrap_or_else(|e| {
            println!("Runtime couldn't be setup. Exiting");
            trace_error(&e);
            exit(1);
        });
    let matches = rt.cli();

    debug!("matches: {:?}", matches);

    if matches.is_present("version") {
        debug!("Showing version");
        println!("imag {}", &version!()[..]);
        exit(0);
    }

    if matches.is_present("versions") {
        debug!("Showing versions");
        let mut result = vec![];
        for command in get_commands().iter() {
            result.push(crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let v = Command::new(command).arg("--version").output();
                    match v {
                        Ok(v) => match String::from_utf8(v.stdout) {
                            Ok(s) => format!("{} -> {}", command, s),
                            Err(e) => format!("Failed calling {} -> {:?}", command, e),
                        },
                        Err(e) => format!("Failed calling {} -> {:?}", command, e),
                    }
                })
            }))
        }

        for versionstring in result.into_iter().map(|handle| handle.join()) {
            println!("{}", versionstring);
        }
    }

    match matches.subcommand() {
        (subcommand, Some(scmd)) => {
            debug!("Calling with subcommand: {}", subcommand);
            let subcommand_args : Vec<&str> = match scmd.values_of("") {
                Some(values) => values.collect(),
                None => Vec::new()
            };

            if !get_commands().contains(&String::from(subcommand)) {
                println!("No such command: 'imag-{}'", subcommand);
                println!("See 'imag --help' for available subcommands");
                exit(2);
            }

            debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args);

            match Command::new(format!("imag-{}", subcommand))
                .stdin(Stdio::inherit())
                .stdout(Stdio::inherit())
                .stderr(Stdio::inherit())
                .args(&subcommand_args[..])
                .spawn()
                .and_then(|mut handle| handle.wait())
            {
                Ok(exit_status) => {
                    if !exit_status.success() {
                        debug!("{} exited with non-zero exit code: {:?}", subcommand, exit_status);
                        println!("{} exited with non-zero exit code", subcommand);
                        exit(exit_status.code().unwrap_or(1));
                    }
                    debug!("Successful exit!");
                },

                Err(e) => {
                    debug!("Error calling the subcommand");
                    match e.kind() {
                        ErrorKind::NotFound => {
                            // With the check above, this absolutely should not happen.
                            // Keeping it to be safe
                            println!("No such command: 'imag-{}'", subcommand);
                            println!("See 'imag --help' for available subcommands");
                            exit(2);
                        },
                        ErrorKind::PermissionDenied => {
                            println!("No permission to execute: 'imag-{}'", subcommand);
                            exit(1);
                        },
                        _ => {
                            println!("Error spawning: {:?}", e);
                            exit(1);
                        }
                    }
                }
            }
        },
        // clap ensures we have valid input by exiting if not.
        // The above case is a catch-all for subcommands,
        // so nothing else needs to be expexted.
        _ => unreachable!(),
    }
}
<commit_msg>Add some comments<commit_after>extern crate crossbeam;
extern crate clap;
#[macro_use] extern crate version;
#[macro_use] extern crate log;
extern crate walkdir;

extern crate libimagrt;
extern crate libimagerror;

use std::env;
use std::process::exit;
use std::process::Command;
use std::process::Stdio;
use std::io::ErrorKind;

use walkdir::WalkDir;
use crossbeam::*;
use clap::{Arg, AppSettings, SubCommand};

use libimagrt::runtime::Runtime;
use libimagerror::trace::trace_error;

/// Returns the helptext, putting the Strings in cmds as possible
/// subcommands into it
fn help_text(cmds: Vec<String>) -> String {
    let text = format!(r#"

     _
    (_)_ __ ___   __ _  __ _
    | | '_ \` _ \/ _\`|/ _\`|
    | | | | | | | (_| | (_| |
    |_|_| |_| |_|\__,_|\__, |
                       |___/
    -------------------------

    Usage: imag [--version | --versions | -h | --help] <command> <args...>

    imag - the personal information management suite for the commandline

    imag is a PIM suite for the commandline. It consists of several commands,
    called "modules". Each module implements one PIM aspect and all of these
    modules can be used independently.

    Available commands:

    {imagbins}

    Call a command with 'imag <command> <args>'
    Each command can be called with "--help" to get the respective helptext.

    Please visit https://github.com/matthiasbeyer/imag to view the source code,
    follow the development of imag or maybe even contribute to imag.

    imag is free software. It is released under the terms of LGPLv2.1

    (c) 2016 Matthias Beyer and contributors"#, imagbins = cmds.into_iter()
        .map(|cmd| format!("\t{}\n", cmd))
        .fold(String::new(), |s, c| {
            let s = s + c.as_str();
            s
        }));
    text
}

/// Returns the list of imag-* executables found in $PATH
fn get_commands() -> Vec<String> {
    let path = env::var("PATH");
    if path.is_err() {
        println!("PATH error: {:?}", path);
        exit(1);
    }
    let pathelements = path.unwrap();
    let pathelements = pathelements.split(":");

    let joinhandles : Vec<ScopedJoinHandle<Vec<String>>> = pathelements
        .map(|elem| {
            crossbeam::scope(|scope| {
                scope.spawn(|| {
                    WalkDir::new(elem)
                        .max_depth(1)
                        .into_iter()
                        .filter(|path| {
                            match path {
                                &Ok(ref p) => p.file_name()
                                    .to_str()
                                    .map_or(false, |filename| filename.starts_with("imag-")),
                                &Err(_)   => false,
                            }
                        })
                        .filter_map(|x| x.ok())
                        .filter_map(|path| {
                           path.file_name()
                               .to_str()
                               .and_then(|s| s.splitn(2, "-").nth(1).map(String::from))
                        })
                        .collect()
                })
            })
        })
        .collect();

    let mut execs = vec![];
    for joinhandle in joinhandles.into_iter() {
        let mut v = joinhandle.join();
        execs.append(&mut v);
    }

    execs
}

fn main() {
    // Initialize the Runtime and build the CLI
    let appname  = "imag";
    let version  = &version!();
    let about    = "imag - the PIM suite for the commandline";
    let commands = get_commands();
    let helptext = help_text(commands.clone());
    let app      = Runtime::get_default_cli_builder(appname, version, about)
        .settings(&[AppSettings::AllowExternalSubcommands, AppSettings::ArgRequiredElseHelp])
        .arg(Arg::with_name("version")
             .long("version")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Get the version of imag"))
        .arg(Arg::with_name("versions")
             .long("versions")
             .takes_value(false)
             .required(false)
             .multiple(false)
             .help("Get the versions of the imag commands"))
        .subcommand(SubCommand::with_name("help").help("Show help"))
        .help(helptext.as_str());
    let rt = Runtime::new(app)
        .unwrap_or_else(|e| {
            println!("Runtime couldn't be setup. Exiting");
            trace_error(&e);
            exit(1);
        });
    let matches = rt.cli();

    debug!("matches: {:?}", matches);

    // Begin checking for arguments

    if matches.is_present("version") {
        debug!("Showing version");
        println!("imag {}", &version!()[..]);
        exit(0);
    }

    if matches.is_present("versions") {
        debug!("Showing versions");
        let mut result = vec![];
        for command in get_commands().iter() {
            result.push(crossbeam::scope(|scope| {
                scope.spawn(|| {
                    let v = Command::new(command).arg("--version").output();
                    match v {
                        Ok(v) => match String::from_utf8(v.stdout) {
                            Ok(s) => format!("{} -> {}", command, s),
                            Err(e) => format!("Failed calling {} -> {:?}", command, e),
                        },
                        Err(e) => format!("Failed calling {} -> {:?}", command, e),
                    }
                })
            }))
        }

        for versionstring in result.into_iter().map(|handle| handle.join()) {
            println!("{}", versionstring);
        }
    }

    // Matches any subcommand given
    match matches.subcommand() {
        (subcommand, Some(scmd)) => {
            // Get all given arguments and further subcommands to pass to
            // the imag-<> binary
            // Providing no arguments is OK, and is therefore ignored here
            let subcommand_args : Vec<&str> = match scmd.values_of("") {
                Some(values) => values.collect(),
                None => Vec::new()
            };

            // Typos happen, so check if the given subcommand is one found in $PATH
            if !commands.clone().contains(&String::from(subcommand)) {
                println!("No such command: 'imag-{}'", subcommand);
                println!("See 'imag --help' for available subcommands");
                exit(2);
            }

            debug!("Calling 'imag-{}' with args: {:?}", subcommand, subcommand_args);

            // Create a Command, and pass it the gathered arguments
            match Command::new(format!("imag-{}", subcommand))
                .stdin(Stdio::inherit())
                .stdout(Stdio::inherit())
                .stderr(Stdio::inherit())
                .args(&subcommand_args[..])
                .spawn()
                .and_then(|mut handle| handle.wait())
            {
                Ok(exit_status) => {
                    if !exit_status.success() {
                        debug!("{} exited with non-zero exit code: {:?}", subcommand, exit_status);
                        println!("{} exited with non-zero exit code", subcommand);
                        exit(exit_status.code().unwrap_or(1));
                    }
                    debug!("Successful exit!");
                },

                Err(e) => {
                    debug!("Error calling the subcommand");
                    match e.kind() {
                        ErrorKind::NotFound => {
                            // With the check above, this absolutely should not happen.
                            // Keeping it to be safe
                            println!("No such command: 'imag-{}'", subcommand);
                            println!("See 'imag --help' for available subcommands");
                            exit(2);
                        },
                        ErrorKind::PermissionDenied => {
                            println!("No permission to execute: 'imag-{}'", subcommand);
                            exit(1);
                        },
                        _ => {
                            println!("Error spawning: {:?}", e);
                            exit(1);
                        }
                    }
                }
            }
        },
        // Calling for example 'imag --versions' will lead here, as this option does not exit.
        // There's nothing to do in such a case
        _ => {},
    }
}
<|endoftext|>