<commit_before>use circular::Buffer;
use err_derive::Error;
use nom::{Err, Offset};
use std::env;
use std::fs::File;
use std::io::{self, Read};

use matroska::ebml::ebml_header;
use matroska::elements::{segment, segment_element, SegmentElement};
use matroska::serializer::ebml::EbmlSize;

#[derive(Debug, Error)]
pub enum InfoError {
    #[error(display = "expected file path")]
    NoPathReceived,
    #[error(display = "no more data to read or parse")]
    NoMoreData,
    #[error(display = "unable to parse header")]
    ParseHeader,
    #[error(display = "already got a SeekHead element")]
    SeekHeadElement,
    #[error(display = "already got an Info element")]
    InfoElement,
    #[error(display = "already got a Tracks element")]
    TracksElement,
    #[error(display = "unexpected element: {}", _0)]
    UnexpectedElement(String),
    #[error(display = "offset {:X?}: got unknown element: {:X?} {:#?}", _0, _1, _2)]
    UnknownElement(usize, u64, Option<u64>),
    #[error(display = "failed parsing: {}", _0)]
    Parse(String),
    #[error(display = "could not read the file: {}", _0)]
    Io(#[error(cause)] io::Error),
}

fn main() -> Result<(), InfoError> {
    pretty_env_logger::init();
    let mut args = env::args();
    let _ = args.next().expect("first arg is program path");
    let filename = args.next().ok_or(InfoError::NoPathReceived)?;

    run(&filename)
}

fn run(filename: &str) -> Result<(), InfoError> {
    let mut file = File::open(filename)?;

    let capacity = 5_242_880;
    let mut b = Buffer::with_capacity(capacity);

    // we write into the `&mut[u8]` returned by `space()`
    let sz = file.read(b.space())?;
    b.fill(sz);
    //eprintln!("write {:#?}", sz);

    let length = {
        let res = ebml_header(b.data());
        if let Ok((remaining, header)) = res {
            //eprintln!("parsed header: {:#?}", h);
            println!("+ EBML head");
            println!("|+ EBML version: {}", header.version);
            println!("|+ EBML read version: {}", header.read_version);
            println!("|+ EBML maximum ID length: {}", header.max_id_length);
            println!("|+ EBML maximum size length: {}", header.max_size_length);
            println!("|+ Document type: {}", header.doc_type);
            println!("|+ Document type version: {}", header.doc_type_version);
            println!(
                "|+ Document type read version: {}",
                header.doc_type_read_version
            );

            b.data().offset(remaining)
        } else {
            return Err(InfoError::ParseHeader);
        }
    };

    let mut _consumed = length;
    b.consume(length);

    let length = {
        let res = segment(b.data());
        if let Ok((remaining, segment)) = res {
            //eprintln!("parsed segment: {:#?}", h);
            println!("+ Segment, size {}", segment.1.unwrap_or(0));

            b.data().offset(remaining)
        } else {
            return Err(InfoError::ParseHeader);
        }
    };

    b.consume(length);

    // handle first elements
    let mut seek_head = None;
    let mut info = None;
    let mut tracks = None;

    loop {
        if seek_head.is_some() && info.is_some() && tracks.is_some() {
            break;
        }

        if b.available_space() == 0 {
            b.shift();
            if b.available_space() == 0 {
                println!("buffer is already full, cannot refill");
                break;
            }
        }

        // refill the buffer
        let sz = file.read(b.space())?;
        b.fill(sz);

        // if there's no more available data in the buffer after a write, that means we reached
        // the end of the file
        if b.available_data() == 0 {
            return Err(InfoError::NoMoreData);
        }

        let offset = {
            let (i, element) = match segment_element(b.data()) {
                Ok((i, o)) => (i, o),
                Err(Err::Error(e)) | Err(Err::Failure(e)) => {
                    return Err(InfoError::Parse(format!("{:?}", e)))
                }
                Err(Err::Incomplete(_i)) => continue,
            };

            match element {
                SegmentElement::SeekHead(s) => {
                    println!("|+ Seek head at {:#0x} size {}", 0x0, b.data().offset(i));
                    for seek in s.positions.iter() {
                        let _id: u64 = (u64::from(seek.id[0]) << 24)
                            | (u64::from(seek.id[1]) << 16)
                            | (u64::from(seek.id[2]) << 8)
                            | u64::from(seek.id[3]);

                        let element_size = seek.size(0x4DBB);
                        let id_size = seek.id.size(0x53AB);
                        let position_size = seek.position.size(0x53AC);

                        println!("| + Seek entry size {}", element_size);

                        print!("|  + Seek ID:");
                        for id in seek.id.iter() {
                            print!(" {:#0x}", id);
                        }

                        let name = match &seek.id[..] {
                            [0x11, 0x4D, 0x9B, 0x74] => " (KaxSeekHead)",
                            [0x12, 0x54, 0xC3, 0x67] => " (KaxTags)",
                            [0x15, 0x49, 0xA9, 0x66] => " (KaxInfo)",
                            [0x16, 0x54, 0xAE, 0x6B] => " (KaxTracks)",
                            [0x1C, 0x53, 0xBB, 0x6B] => " (KaxCues)",
                            [0x1F, 0x43, 0xB6, 0x75] => " (KaxCluster)",
                            _ => "",
                        };

                        println!("{} at {:#0x} size {}", name, 0x0, id_size);
                        println!(
                            "|  + Seek position: {} size {}",
                            seek.position, position_size
                        );
                    }

                    if seek_head.is_some() {
                        return Err(InfoError::SeekHeadElement);
                    } else {
                        seek_head = Some(s);
                    }
                }
                SegmentElement::Info(i) => {
                    println!("|+ Segment information");
                    println!("| + Timestamp scale: {}", i.timecode_scale);
                    println!("| + Multiplexing application: {}", i.muxing_app);
                    println!("| + Writing application: {}", i.writing_app);
                    println!(
                        "| + Segment UID: {:?}",
                        i.segment_uid.as_ref().unwrap_or(&Vec::new())
                    );
                    println!("| + Duration: {}s", i.duration.unwrap_or(0f64) / 1000f64);
                    if info.is_some() {
                        return Err(InfoError::InfoElement);
                    } else {
                        info = Some(i);
                    }
                }
                SegmentElement::Tracks(t) => {
                    //eprintln!("got tracks: {:#?}", t);
                    println!("|+ Segment tracks");
                    for tr in t.tracks.iter() {
                        println!("| + A track");
                        println!("|  + Track number: {}", tr.track_number);
                        println!("|  + Track UID: {}", tr.track_uid);
                        println!("|  + Track type: {}", tr.track_type);
                        println!("|  + Lacing flag: {}", tr.flag_lacing.unwrap_or(0));
                        println!("|  + Default flag: {}", tr.flag_default.unwrap_or(0));
                        println!(
                            "|  + Language: {}",
                            tr.language.as_ref().unwrap_or(&"".to_string())
                        );
                        println!("|  + Codec ID: {}", tr.codec_id);
                        println!(
                            "|  + Codec private: length {}",
                            tr.codec_private.as_ref().map(|v| v.len()).unwrap_or(0)
                        );

                        if let Some(ref v) = tr.video {
                            println!("|  + Video track");
                            println!("|    + Pixel width: {}", v.pixel_width);
                            println!("|    + Pixel height: {}", v.pixel_height);
                            if let Some(inter) = v.flag_interlaced {
                                println!("|    + Interlaced: {}", inter);
                            }
                            if let Some(width) = v.display_width {
                                println!("|    + Display width: {}", width);
                            }
                            if let Some(height) = v.display_height {
                                println!("|    + Display height: {}", height);
                            }
                            if let Some(unit) = v.display_unit {
                                println!("|    + Display unit: {}", unit);
                            }
                        }

                        if let Some(ref a) = tr.audio {
                            println!("|  + Audio track");
                            println!("|    + Sampling frequency: {}", a.sampling_frequency);
                            if let Some(frequency) = a.output_sampling_frequency {
                                println!("|    + Output sampling freqeuncy: {}", frequency);
                            }
                            println!("|    + Channels: {}", a.channels);
                            if let Some(ref channel_positions) = a.channel_positions {
                                println!("|    + Channel position: {:?}", channel_positions);
                            }
                            if let Some(bit_depth) = a.bit_depth {
                                println!("|    + Bit depth: {}", bit_depth);
                            }
                        }
                    }
                    if tracks.is_some() {
                        return Err(InfoError::TracksElement);
                    } else {
                        tracks = Some(t);
                    }
                }
                /*SegmentElement::Cluster(c) => {
                    println!("|+ Cluster");
                    eprintln!("got a cluster: {:#?}", c);
                },*/
                SegmentElement::Void(s) => {
                    println!("|+ EbmlVoid (size: {})", s);
                }
                el => return Err(InfoError::UnexpectedElement(format!("{:?}", el))),
            }

            b.data().offset(i)
        };
        _consumed += offset;
        //eprintln!("consumed {} bytes", length);
        b.consume(offset);
    }

    loop {
        if b.available_space() == 0 {
            b.shift();
            if b.available_space() == 0 {
                println!("buffer is already full,  cannot refill");
                break;
            }
        }

        // refill the buffer
        let sz = file.read(b.space())?;
        b.fill(sz);

        /*
        eprintln!(
            "refill: {} more bytes, available data: {} bytes, consumed: {} bytes",
            sz,
            b.available_data(),
            consumed
        );
        */

        // if there's no more available data in the buffer after a write, that means we reached
        // the end of the file
        if b.available_data() == 0 {
            //panic!("no more data to read or parse, stopping the reading loop");
            break;
        }

        let offset = {
            let (i, element) = match segment_element(b.data()) {
                Ok((i, o)) => (i, o),
                Err(Err::Error(e)) | Err(Err::Failure(e)) => {
                    return Err(InfoError::Parse(format!("{:?}", e)))
                }
                Err(Err::Incomplete(_)) => continue,
            };

            match element {
                SegmentElement::SeekHead(_)
                | SegmentElement::Info(_)
                | SegmentElement::Tracks(_) => {
                    return Err(InfoError::UnexpectedElement(
                        "seek head, info or tracks element".to_string(),
                    ));
                }
                SegmentElement::Cluster(c) => {
                    println!("|+ Cluster");
                    println!("|+   Timecode: {}", c.timecode);
                    println!("|+   Silent_tracks: {:?}", c.silent_tracks);
                    println!("|+   Position: {:?}", c.position);
                    println!("|+   Prev size: {:?}", c.prev_size);
                    println!("|+   Simple block: {} elements", c.simple_block.len());
                    println!("|+   Block group: {} elements", c.block_group.len());
                    println!(
                        "|+   Encrypted block: {:?} bytes",
                        c.encrypted_block.as_ref().map(|s| s.len())
                    );
                    //eprintln!("got a cluster: {:#?}", c);
                }
                SegmentElement::Void(s) => {
                    println!("|+ EbmlVoid (size: {})", s);
                }
                SegmentElement::Tags(_) => {
                    println!("|+ Tags");
                }
                SegmentElement::Cues(_) => {
                    println!("|+ Cues");
                }
                SegmentElement::Unknown(id, data) => {
                    return Err(InfoError::UnknownElement(_consumed, id, data))
                }
                el => return Err(InfoError::UnexpectedElement(format!("{:?}", el))),
            }

            b.data().offset(i)
        };
        _consumed += offset;
        //eprintln!("consumed {} bytes", length);
        b.consume(offset);
    }

    Ok(())
}
<commit_msg>tools: Remove dead code<commit_after>use circular::Buffer;
use err_derive::Error;
use nom::{Err, Offset};
use std::env;
use std::fs::File;
use std::io::{self, Read};

use matroska::ebml::ebml_header;
use matroska::elements::{segment, segment_element, SegmentElement};
use matroska::serializer::ebml::EbmlSize;

#[derive(Debug, Error)]
pub enum InfoError {
    #[error(display = "expected file path")]
    NoPathReceived,
    #[error(display = "no more data to read or parse")]
    NoMoreData,
    #[error(display = "unable to parse header")]
    ParseHeader,
    #[error(display = "already got a SeekHead element")]
    SeekHeadElement,
    #[error(display = "already got an Info element")]
    InfoElement,
    #[error(display = "already got a Tracks element")]
    TracksElement,
    #[error(display = "unexpected element: {}", _0)]
    UnexpectedElement(String),
    #[error(display = "offset {:X?}: got unknown element: {:X?} {:#?}", _0, _1, _2)]
    UnknownElement(usize, u64, Option<u64>),
    #[error(display = "failed parsing: {}", _0)]
    Parse(String),
    #[error(display = "could not read the file: {}", _0)]
    Io(#[error(cause)] io::Error),
}

fn main() -> Result<(), InfoError> {
    pretty_env_logger::init();
    let mut args = env::args();
    let _ = args.next().expect("first arg is program path");
    let filename = args.next().ok_or(InfoError::NoPathReceived)?;

    run(&filename)
}

fn run(filename: &str) -> Result<(), InfoError> {
    let mut file = File::open(filename)?;

    let capacity = 5_242_880;
    let mut b = Buffer::with_capacity(capacity);

    // we write into the `&mut[u8]` returned by `space()`
    let sz = file.read(b.space())?;
    b.fill(sz);

    let length = {
        let res = ebml_header(b.data());
        if let Ok((remaining, header)) = res {
            println!("+ EBML head");
            println!("|+ EBML version: {}", header.version);
            println!("|+ EBML read version: {}", header.read_version);
            println!("|+ EBML maximum ID length: {}", header.max_id_length);
            println!("|+ EBML maximum size length: {}", header.max_size_length);
            println!("|+ Document type: {}", header.doc_type);
            println!("|+ Document type version: {}", header.doc_type_version);
            println!(
                "|+ Document type read version: {}",
                header.doc_type_read_version
            );

            b.data().offset(remaining)
        } else {
            return Err(InfoError::ParseHeader);
        }
    };

    let mut _consumed = length;
    b.consume(length);

    let length = {
        let res = segment(b.data());
        if let Ok((remaining, segment)) = res {
            println!("+ Segment, size {}", segment.1.unwrap_or(0));

            b.data().offset(remaining)
        } else {
            return Err(InfoError::ParseHeader);
        }
    };

    b.consume(length);

    // handle first elements
    let mut seek_head = None;
    let mut info = None;
    let mut tracks = None;

    loop {
        if seek_head.is_some() && info.is_some() && tracks.is_some() {
            break;
        }

        if b.available_space() == 0 {
            b.shift();
            if b.available_space() == 0 {
                println!("buffer is already full, cannot refill");
                break;
            }
        }

        // refill the buffer
        let sz = file.read(b.space())?;
        b.fill(sz);

        // if there's no more available data in the buffer after a write, that means we reached
        // the end of the file
        if b.available_data() == 0 {
            return Err(InfoError::NoMoreData);
        }

        let offset = {
            let (i, element) = match segment_element(b.data()) {
                Ok((i, o)) => (i, o),
                Err(Err::Error(e)) | Err(Err::Failure(e)) => {
                    return Err(InfoError::Parse(format!("{:?}", e)))
                }
                Err(Err::Incomplete(_i)) => continue,
            };

            match element {
                SegmentElement::SeekHead(s) => {
                    println!("|+ Seek head at {:#0x} size {}", 0x0, b.data().offset(i));
                    for seek in s.positions.iter() {
                        let _id: u64 = (u64::from(seek.id[0]) << 24)
                            | (u64::from(seek.id[1]) << 16)
                            | (u64::from(seek.id[2]) << 8)
                            | u64::from(seek.id[3]);

                        let element_size = seek.size(0x4DBB);
                        let id_size = seek.id.size(0x53AB);
                        let position_size = seek.position.size(0x53AC);

                        println!("| + Seek entry size {}", element_size);

                        print!("|  + Seek ID:");
                        for id in seek.id.iter() {
                            print!(" {:#0x}", id);
                        }

                        let name = match &seek.id[..] {
                            [0x11, 0x4D, 0x9B, 0x74] => " (KaxSeekHead)",
                            [0x12, 0x54, 0xC3, 0x67] => " (KaxTags)",
                            [0x15, 0x49, 0xA9, 0x66] => " (KaxInfo)",
                            [0x16, 0x54, 0xAE, 0x6B] => " (KaxTracks)",
                            [0x1C, 0x53, 0xBB, 0x6B] => " (KaxCues)",
                            [0x1F, 0x43, 0xB6, 0x75] => " (KaxCluster)",
                            _ => "",
                        };

                        println!("{} at {:#0x} size {}", name, 0x0, id_size);
                        println!(
                            "|  + Seek position: {} size {}",
                            seek.position, position_size
                        );
                    }

                    if seek_head.is_some() {
                        return Err(InfoError::SeekHeadElement);
                    } else {
                        seek_head = Some(s);
                    }
                }
                SegmentElement::Info(i) => {
                    println!("|+ Segment information");
                    println!("| + Timestamp scale: {}", i.timecode_scale);
                    println!("| + Multiplexing application: {}", i.muxing_app);
                    println!("| + Writing application: {}", i.writing_app);
                    println!(
                        "| + Segment UID: {:?}",
                        i.segment_uid.as_ref().unwrap_or(&Vec::new())
                    );
                    println!("| + Duration: {}s", i.duration.unwrap_or(0f64) / 1000f64);
                    if info.is_some() {
                        return Err(InfoError::InfoElement);
                    } else {
                        info = Some(i);
                    }
                }
                SegmentElement::Tracks(t) => {
                    //eprintln!("got tracks: {:#?}", t);
                    println!("|+ Segment tracks");
                    for tr in t.tracks.iter() {
                        println!("| + A track");
                        println!("|  + Track number: {}", tr.track_number);
                        println!("|  + Track UID: {}", tr.track_uid);
                        println!("|  + Track type: {}", tr.track_type);
                        println!("|  + Lacing flag: {}", tr.flag_lacing.unwrap_or(0));
                        println!("|  + Default flag: {}", tr.flag_default.unwrap_or(0));
                        println!(
                            "|  + Language: {}",
                            tr.language.as_ref().unwrap_or(&"".to_string())
                        );
                        println!("|  + Codec ID: {}", tr.codec_id);
                        println!(
                            "|  + Codec private: length {}",
                            tr.codec_private.as_ref().map(|v| v.len()).unwrap_or(0)
                        );

                        if let Some(ref v) = tr.video {
                            println!("|  + Video track");
                            println!("|    + Pixel width: {}", v.pixel_width);
                            println!("|    + Pixel height: {}", v.pixel_height);
                            if let Some(inter) = v.flag_interlaced {
                                println!("|    + Interlaced: {}", inter);
                            }
                            if let Some(width) = v.display_width {
                                println!("|    + Display width: {}", width);
                            }
                            if let Some(height) = v.display_height {
                                println!("|    + Display height: {}", height);
                            }
                            if let Some(unit) = v.display_unit {
                                println!("|    + Display unit: {}", unit);
                            }
                        }

                        if let Some(ref a) = tr.audio {
                            println!("|  + Audio track");
                            println!("|    + Sampling frequency: {}", a.sampling_frequency);
                            if let Some(frequency) = a.output_sampling_frequency {
                                println!("|    + Output sampling freqeuncy: {}", frequency);
                            }
                            println!("|    + Channels: {}", a.channels);
                            if let Some(ref channel_positions) = a.channel_positions {
                                println!("|    + Channel position: {:?}", channel_positions);
                            }
                            if let Some(bit_depth) = a.bit_depth {
                                println!("|    + Bit depth: {}", bit_depth);
                            }
                        }
                    }
                    if tracks.is_some() {
                        return Err(InfoError::TracksElement);
                    } else {
                        tracks = Some(t);
                    }
                }
                SegmentElement::Void(s) => {
                    println!("|+ EbmlVoid (size: {})", s);
                }
                el => return Err(InfoError::UnexpectedElement(format!("{:?}", el))),
            }

            b.data().offset(i)
        };
        _consumed += offset;
        b.consume(offset);
    }

    loop {
        if b.available_space() == 0 {
            b.shift();
            if b.available_space() == 0 {
                println!("buffer is already full,  cannot refill");
                break;
            }
        }

        // refill the buffer
        let sz = file.read(b.space())?;
        b.fill(sz);

        // if there's no more available data in the buffer after a write, that means we reached
        // the end of the file
        if b.available_data() == 0 {
            //panic!("no more data to read or parse, stopping the reading loop");
            break;
        }

        let offset = {
            let (i, element) = match segment_element(b.data()) {
                Ok((i, o)) => (i, o),
                Err(Err::Error(e)) | Err(Err::Failure(e)) => {
                    return Err(InfoError::Parse(format!("{:?}", e)))
                }
                Err(Err::Incomplete(_)) => continue,
            };

            match element {
                SegmentElement::SeekHead(_)
                | SegmentElement::Info(_)
                | SegmentElement::Tracks(_) => {
                    return Err(InfoError::UnexpectedElement(
                        "seek head, info or tracks element".to_string(),
                    ));
                }
                SegmentElement::Cluster(c) => {
                    println!("|+ Cluster");
                    println!("|+   Timecode: {}", c.timecode);
                    println!("|+   Silent_tracks: {:?}", c.silent_tracks);
                    println!("|+   Position: {:?}", c.position);
                    println!("|+   Prev size: {:?}", c.prev_size);
                    println!("|+   Simple block: {} elements", c.simple_block.len());
                    println!("|+   Block group: {} elements", c.block_group.len());
                    println!(
                        "|+   Encrypted block: {:?} bytes",
                        c.encrypted_block.as_ref().map(|s| s.len())
                    );
                }
                SegmentElement::Void(s) => {
                    println!("|+ EbmlVoid (size: {})", s);
                }
                SegmentElement::Tags(_) => {
                    println!("|+ Tags");
                }
                SegmentElement::Cues(_) => {
                    println!("|+ Cues");
                }
                SegmentElement::Unknown(id, data) => {
                    return Err(InfoError::UnknownElement(_consumed, id, data))
                }
                el => return Err(InfoError::UnexpectedElement(format!("{:?}", el))),
            }

            b.data().offset(i)
        };
        _consumed += offset;
        b.consume(offset);
    }

    Ok(())
}
<|endoftext|>


<commit_before>extern crate iron;
extern crate router;
extern crate persistent;

#[macro_use]
mod utils;
mod search_api;
mod alias_api;
mod document_api;
mod index_api;
mod mapping_api;
mod bulk_api;

use std::sync::Arc;

use api::iron::prelude::*;
use api::iron::status;
use api::iron::typemap::Key;
use api::router::Router;

use system::System;
use VERSION;

fn view_home(_: &mut Request) -> IronResult<Response> {
    Ok(Response::with((status::Ok, format!("{{
  \"cluster_name\" : \"rusticsearch\",
  \"version\" : {{
    \"number\" : \"{}\",
  }}
}}", VERSION))))
}

fn get_router() -> Router {
    router!(get "/" => view_home,
            get "/:index/_count" => search_api::view_count,
            post "/:index/_count" => search_api::view_count,
            get "/:index/_search" => search_api::view_search,
            post "/:index/_search" => search_api::view_search,
            get "/_alias/:alias" => alias_api::view_get_global_alias,
            get "/:index/_alias" => alias_api::view_get_alias_list,
            get "/:index/_alias/:alias" => alias_api::view_get_alias,
            put "/:index/_alias/:alias" => alias_api::view_put_alias,
            get "/:index/:mapping/:doc" => document_api::view_get_doc,
            put "/:index/:mapping/:doc" => document_api::view_put_doc,
            delete "/:index/:mapping/:doc" => document_api::view_delete_doc,
            get "/:index" => index_api::view_get_index,
            put "/:index" => index_api::view_put_index,
            delete "/:index" => index_api::view_delete_index,
            post "/:index/_refresh" => index_api::view_post_refresh_index,
            put "/:index/_mapping/:mapping" => mapping_api::view_put_mapping,
            post "/_bulk" => bulk_api::view_post_bulk)
}

// The "Context" struct just wraps Arc<System> so we can put it into chain.link()
// Workaround for: https://github.com/iron/persistent/issues/55

struct Context {
    system: Arc<System>,
}

impl Context {
    fn new(system: Arc<System>) -> Context {
        Context {
            system: system,
        }
    }
}

impl Key for Context {
    type Value = Context;
}

pub fn api_main(system: Arc<System>) {
    let router = get_router();
    let mut chain = Chain::new(router);
    chain.link(persistent::Read::<Context>::both(Context::new(system.clone())));
    system.log.info("[api] listening", b!("scheme" => "http", "address" => "localhost", "port" => 9200));

    if let Err(error) = Iron::new(chain).http("localhost:9200") {
        system.log.critical("[api] unable to start api server", b!("error" => format!("{}", error)));
    }
}
<commit_msg>Use json_response in home view<commit_after>extern crate iron;
extern crate router;
extern crate persistent;

#[macro_use]
mod utils;
mod search_api;
mod alias_api;
mod document_api;
mod index_api;
mod mapping_api;
mod bulk_api;

use std::sync::Arc;

use api::iron::prelude::*;
use api::iron::status;
use api::iron::typemap::Key;
use api::router::Router;
use api::utils::json_response;

use system::System;
use VERSION;

fn view_home(_: &mut Request) -> IronResult<Response> {
    Ok(json_response(status::Ok, json!({
        "cluster_name": "rusticsearch",
        "version": {
            "number": VERSION
        }
    })))
}

fn get_router() -> Router {
    router!(get "/" => view_home,
            get "/:index/_count" => search_api::view_count,
            post "/:index/_count" => search_api::view_count,
            get "/:index/_search" => search_api::view_search,
            post "/:index/_search" => search_api::view_search,
            get "/_alias/:alias" => alias_api::view_get_global_alias,
            get "/:index/_alias" => alias_api::view_get_alias_list,
            get "/:index/_alias/:alias" => alias_api::view_get_alias,
            put "/:index/_alias/:alias" => alias_api::view_put_alias,
            get "/:index/:mapping/:doc" => document_api::view_get_doc,
            put "/:index/:mapping/:doc" => document_api::view_put_doc,
            delete "/:index/:mapping/:doc" => document_api::view_delete_doc,
            get "/:index" => index_api::view_get_index,
            put "/:index" => index_api::view_put_index,
            delete "/:index" => index_api::view_delete_index,
            post "/:index/_refresh" => index_api::view_post_refresh_index,
            put "/:index/_mapping/:mapping" => mapping_api::view_put_mapping,
            post "/_bulk" => bulk_api::view_post_bulk)
}

// The "Context" struct just wraps Arc<System> so we can put it into chain.link()
// Workaround for: https://github.com/iron/persistent/issues/55

struct Context {
    system: Arc<System>,
}

impl Context {
    fn new(system: Arc<System>) -> Context {
        Context {
            system: system,
        }
    }
}

impl Key for Context {
    type Value = Context;
}

pub fn api_main(system: Arc<System>) {
    let router = get_router();
    let mut chain = Chain::new(router);
    chain.link(persistent::Read::<Context>::both(Context::new(system.clone())));
    system.log.info("[api] listening", b!("scheme" => "http", "address" => "localhost", "port" => 9200));

    if let Err(error) = Iron::new(chain).http("localhost:9200") {
        system.log.critical("[api] unable to start api server", b!("error" => format!("{}", error)));
    }
}
<|endoftext|>


<commit_before>// Copyright (c) 2016-2019 Fabian Schuiki

//! An implementation of the visitor pattern for the HIR.
//!
//! This module defines the [`Visitor`] trait that allows the HIR tree graph to
//! be visited.

use super::{nodes::*, HirNode};
use crate::{common::NodeId, Context};

/// A visitor of the HIR.
pub trait Visitor<'a>: Sized {
    /// The type of context that this visitor uses.
    type Context: Context<'a>;

    /// Get the context to be used to resolve queries.
    fn context(&self) -> &Self::Context;

    fn visit_node_with_id(&mut self, node_id: NodeId, lvalue: bool) {
        match self.context().hir_of(node_id) {
            Ok(x) => self.visit_node(x, lvalue),
            Err(()) => (),
        }
    }

    fn visit_node(&mut self, node: HirNode<'a>, lvalue: bool) {
        match node {
            HirNode::Proc(x) => self.visit_proc(x),
            HirNode::Stmt(x) => self.visit_stmt(x),
            HirNode::Expr(x) => self.visit_expr(x, lvalue),
            _ => (),
        }
    }

    fn visit_proc(&mut self, prok: &'a Proc) {
        walk_proc(self, prok)
    }

    fn visit_stmt(&mut self, stmt: &'a Stmt) {
        walk_stmt(self, stmt)
    }

    fn visit_expr(&mut self, expr: &'a Expr, lvalue: bool) {
        walk_expr(self, expr, lvalue);
    }
}

/// Walk the contents of a procedure.
pub fn walk_proc<'a>(visitor: &mut impl Visitor<'a>, prok: &'a Proc) {
    visitor.visit_node_with_id(prok.stmt, false);
}

/// Walk the contents of a statement.
pub fn walk_stmt<'a>(visitor: &mut impl Visitor<'a>, stmt: &'a Stmt) {
    #[allow(unreachable_patterns)]
    match stmt.kind {
        StmtKind::Null => (),
        StmtKind::Block(ref stmts) => {
            for &id in stmts {
                visitor.visit_node_with_id(id, false);
            }
        }
        StmtKind::Assign { lhs, rhs, .. } => {
            visitor.visit_node_with_id(lhs, true);
            visitor.visit_node_with_id(rhs, false);
        }
        _ => (),
    }
}

/// Walk the contents of an expression.
pub fn walk_expr<'a>(_visitor: &mut impl Visitor<'a>, expr: &'a Expr, _lvalue: bool) {
    match expr.kind {
        _ => (),
    }
}
<commit_msg>svlog: impl timing ctrl and event expr visit<commit_after>// Copyright (c) 2016-2019 Fabian Schuiki

//! An implementation of the visitor pattern for the HIR.
//!
//! This module defines the [`Visitor`] trait that allows the HIR tree graph to
//! be visited.

use super::{nodes::*, HirNode};
use crate::{common::NodeId, Context};

/// A visitor of the HIR.
pub trait Visitor<'a>: Sized {
    /// The type of context that this visitor uses.
    type Context: Context<'a>;

    /// Get the context to be used to resolve queries.
    fn context(&self) -> &Self::Context;

    fn visit_node_with_id(&mut self, node_id: NodeId, lvalue: bool) {
        match self.context().hir_of(node_id) {
            Ok(x) => self.visit_node(x, lvalue),
            Err(()) => (),
        }
    }

    fn visit_node(&mut self, node: HirNode<'a>, lvalue: bool) {
        match node {
            HirNode::Proc(x) => self.visit_proc(x),
            HirNode::Stmt(x) => self.visit_stmt(x),
            HirNode::Expr(x) => self.visit_expr(x, lvalue),
            HirNode::EventExpr(x) => self.visit_event_expr(x),
            _ => (),
        }
    }

    fn visit_proc(&mut self, prok: &'a Proc) {
        walk_proc(self, prok)
    }

    fn visit_stmt(&mut self, stmt: &'a Stmt) {
        walk_stmt(self, stmt)
    }

    fn visit_expr(&mut self, expr: &'a Expr, lvalue: bool) {
        walk_expr(self, expr, lvalue);
    }

    fn visit_timing_control(&mut self, ctrl: &'a TimingControl) {
        walk_timing_control(self, ctrl);
    }

    fn visit_event_expr(&mut self, expr: &'a EventExpr) {
        walk_event_expr(self, expr);
    }

    fn visit_event(&mut self, event: &'a Event) {
        walk_event(self, event);
    }
}

/// Walk the contents of a procedure.
pub fn walk_proc<'a>(visitor: &mut impl Visitor<'a>, prok: &'a Proc) {
    visitor.visit_node_with_id(prok.stmt, false);
}

/// Walk the contents of a statement.
pub fn walk_stmt<'a>(visitor: &mut impl Visitor<'a>, stmt: &'a Stmt) {
    #[allow(unreachable_patterns)]
    match stmt.kind {
        StmtKind::Null => (),
        StmtKind::Block(ref stmts) => {
            for &id in stmts {
                visitor.visit_node_with_id(id, false);
            }
        }
        StmtKind::Assign { lhs, rhs, .. } => {
            visitor.visit_node_with_id(lhs, true);
            visitor.visit_node_with_id(rhs, false);
        }
        StmtKind::Timed { ref control, stmt } => {
            visitor.visit_timing_control(control);
            visitor.visit_node_with_id(stmt, false);
        }
        _ => (),
    }
}

/// Walk the contents of an expression.
pub fn walk_expr<'a>(_visitor: &mut impl Visitor<'a>, expr: &'a Expr, _lvalue: bool) {
    match expr.kind {
        _ => (),
    }
}

/// Walk the contents of a timing control block.
pub fn walk_timing_control<'a>(visitor: &mut impl Visitor<'a>, ctrl: &'a TimingControl) {
    match *ctrl {
        TimingControl::Delay(id) => visitor.visit_node_with_id(id, false),
        TimingControl::ImplicitEvent => (),
        TimingControl::ExplicitEvent(id) => visitor.visit_node_with_id(id, false),
    }
}

/// Walk the contents of an event expression.
pub fn walk_event_expr<'a>(visitor: &mut impl Visitor<'a>, expr: &'a EventExpr) {
    for event in &expr.events {
        visitor.visit_event(event);
    }
}

/// Walk the contents of an event.
pub fn walk_event<'a>(visitor: &mut impl Visitor<'a>, event: &'a Event) {
    visitor.visit_node_with_id(event.expr, false);
    for &iff in &event.iff {
        visitor.visit_node_with_id(iff, false);
    }
}
<|endoftext|>


<commit_before>use crates_index_diff::Index;
use git_testtools::tempfile::TempDir;
use std::path::PathBuf;

mod changes_between_commits;

const NUM_CHANGES_SINCE_EVER: usize = 3516;

#[test]
fn peek_changes() -> crate::Result {
    let mut index = index_ro()?;
    index.branch_name = "main";
    assert!(
        index.last_seen_reference().is_err(),
        "marker ref doesn't exist"
    );
    let (changes, last_seen_revision) = index.peek_changes()?;
    assert_eq!(
        changes.len(),
        NUM_CHANGES_SINCE_EVER,
        "all changes since the beginning of history"
    );

    let origin_main = index
        .repository()
        .find_reference("refs/remotes/origin/main")?;
    assert_eq!(
        last_seen_revision,
        origin_main.id(),
        "last seen reference should the latest state from the clone"
    );
    assert!(
        index.last_seen_reference().is_err(),
        "the last-seen reference has not been created"
    );
    Ok(())
}

#[test]
fn clone_if_needed() {
    let tmp = TempDir::new().unwrap();
    Index::from_path_or_cloned_with_options(tmp.path(), clone_options())
        .expect("successful clone to be created");
    Index::from_path_or_cloned_with_options(tmp.path(), clone_options())
        .expect("second instance re-uses existing clone");
}

#[test]
fn quick_changes_since_last_fetch() -> crate::Result {
    let (index, _tmp) = index_rw()?;
    assert!(index.last_seen_reference().is_err(), "no marker exists");
    let num_changes_since_first_commit = index.fetch_changes()?.len();
    assert_eq!(
        num_changes_since_first_commit, NUM_CHANGES_SINCE_EVER,
        "all changes since ever"
    );
    let mut marker = index
        .last_seen_reference()
        .expect("must be created/update now");
    let remote_main = index
        .repository()
        .find_reference("refs/remotes/origin/main")?;
    assert_eq!(
        marker.target(),
        remote_main.target(),
        "we are updated to the most recent known version of the remote"
    );

    // reset to previous one
    marker
        .set_target_id(
            index
                .repository()
                .rev_parse(format!("{}~2", index.seen_ref_name).as_str())?
                .single()
                .unwrap(),
            "resetting to previous commit",
        )
        .expect("reset success");
    let num_seen_after_reset = index.fetch_changes()?.len();
    assert_eq!(
        index.last_seen_reference()?.target(),
        remote_main.target(),
        "seen branch was updated again"
    );
    assert_eq!(
        num_seen_after_reset, 1,
        "normalization has no changes, but the commit before has one"
    );

    assert_eq!(
        index.fetch_changes()?.len(),
        0,
        "nothing if there was no change"
    );
    Ok(())
}

fn index_ro() -> crate::Result<Index> {
    let dir = fixture_dir()?;
    Ok(Index::from_path_or_cloned(dir.join("clone"))?)
}

fn index_rw() -> crate::Result<(Index, TempDir)> {
    let tmp = TempDir::new().unwrap();
    let mut index = Index::from_path_or_cloned_with_options(tmp.path(), clone_options())?;
    index.branch_name = "main";
    Ok((index, tmp))
}

fn fixture_dir() -> crate::Result<PathBuf> {
    Ok(git_testtools::scripted_fixture_repo_read_only_with_args(
        "make-index-from-parts.sh",
        std::env::current_dir()
            .ok()
            .map(|p| p.to_str().unwrap().to_owned()),
    )?)
}

fn clone_options() -> crates_index_diff::index::CloneOptions<'static> {
    crates_index_diff::index::CloneOptions {
        repository_url: fixture_dir().unwrap().join("base").display().to_string(),
        fetch_options: None,
    }
}
<commit_msg>thanks clippy<commit_after>use crates_index_diff::Index;
use git_testtools::tempfile::TempDir;
use std::path::PathBuf;

mod changes_between_commits;

const NUM_CHANGES_SINCE_EVER: usize = 3516;

#[test]
fn peek_changes() -> crate::Result {
    let mut index = index_ro()?;
    index.branch_name = "main";
    assert!(
        index.last_seen_reference().is_err(),
        "marker ref doesn't exist"
    );
    let (changes, last_seen_revision) = index.peek_changes()?;
    assert_eq!(
        changes.len(),
        NUM_CHANGES_SINCE_EVER,
        "all changes since the beginning of history"
    );

    let origin_main = index
        .repository()
        .find_reference("refs/remotes/origin/main")?;
    assert_eq!(
        last_seen_revision,
        origin_main.id(),
        "last seen reference should the latest state from the clone"
    );
    assert!(
        index.last_seen_reference().is_err(),
        "the last-seen reference has not been created"
    );
    Ok(())
}

#[test]
fn clone_if_needed() {
    let tmp = TempDir::new().unwrap();
    Index::from_path_or_cloned_with_options(tmp.path(), clone_options())
        .expect("successful clone to be created");
    Index::from_path_or_cloned_with_options(tmp.path(), clone_options())
        .expect("second instance re-uses existing clone");
}

#[test]
fn quick_changes_since_last_fetch() -> crate::Result {
    let (index, _tmp) = index_rw()?;
    assert!(index.last_seen_reference().is_err(), "no marker exists");
    let num_changes_since_first_commit = index.fetch_changes()?.len();
    assert_eq!(
        num_changes_since_first_commit, NUM_CHANGES_SINCE_EVER,
        "all changes since ever"
    );
    let mut marker = index
        .last_seen_reference()
        .expect("must be created/update now");
    let remote_main = index
        .repository()
        .find_reference("refs/remotes/origin/main")?;
    assert_eq!(
        marker.target(),
        remote_main.target(),
        "we are updated to the most recent known version of the remote"
    );

    // reset to previous one
    marker
        .set_target_id(
            index
                .repository()
                .rev_parse(format!("{}~2", index.seen_ref_name).as_str())?
                .single()
                .unwrap(),
            "resetting to previous commit",
        )
        .expect("reset success");
    let num_seen_after_reset = index.fetch_changes()?.len();
    assert_eq!(
        index.last_seen_reference()?.target(),
        remote_main.target(),
        "seen branch was updated again"
    );
    assert_eq!(
        num_seen_after_reset, 1,
        "normalization has no changes, but the commit before has one"
    );

    assert_eq!(
        index.fetch_changes()?.len(),
        0,
        "nothing if there was no change"
    );
    Ok(())
}

fn index_ro() -> crate::Result<Index> {
    let dir = fixture_dir()?;
    Ok(Index::from_path_or_cloned(dir.join("clone"))?)
}

fn index_rw() -> crate::Result<(Index, TempDir)> {
    let tmp = TempDir::new().unwrap();
    let mut index = Index::from_path_or_cloned_with_options(tmp.path(), clone_options())?;
    index.branch_name = "main";
    Ok((index, tmp))
}

fn fixture_dir() -> crate::Result<PathBuf> {
    git_testtools::scripted_fixture_repo_read_only_with_args(
        "make-index-from-parts.sh",
        std::env::current_dir()
            .ok()
            .map(|p| p.to_str().unwrap().to_owned()),
    )
}

fn clone_options() -> crates_index_diff::index::CloneOptions<'static> {
    crates_index_diff::index::CloneOptions {
        repository_url: fixture_dir().unwrap().join("base").display().to_string(),
        fetch_options: None,
    }
}
<|endoftext|>


<commit_before>use amq_protocol::frame::{GenError, Offset, gen_frame, parse_frame};
use log::{error, trace};
use mio::{Evented, Events, Poll, PollOpt, Ready, Registration, SetReadiness, Token};
use parking_lot::Mutex;

use std::{
  io::{self, Read, Write},
  sync::{
    Arc,
    atomic::{AtomicBool, Ordering},
  },
  thread::{self, Builder as ThreadBuilder, JoinHandle},
  time::{Duration, Instant},
};

use crate::{
  buffer::Buffer,
  connection::Connection,
  connection_status::ConnectionState,
  error::{Error, ErrorKind},
};

const SOCKET:   Token = Token(0);
const DATA:     Token = Token(1);
const CONTINUE: Token = Token(2);

pub struct IoLoop<T> {
  inner: Arc<Mutex<Inner<T>>>,
}

impl<T: Evented + Read + Write + Send + 'static> IoLoop<T> {
  pub fn new(connection: Connection, socket: T) -> Result<Self, Error> {
    let inner = Arc::new(Mutex::new(Inner::new(connection, socket)?));
    Ok(Self { inner })
  }

  pub fn run(&self) -> Result<(), Error> {
    let inner  = self.inner.clone();
    let handle = ThreadBuilder::new().name("io_loop".to_owned()).spawn(move || {
      let mut events = Events::with_capacity(1024);
      loop {
        inner.lock().run(&mut events)?;
      }
    }).map_err(ErrorKind::IOError)?;
    self.inner.lock().handle = Some(handle);
    Ok(())
  }
}

#[derive(PartialEq)]
enum Status {
  Initial,
  Setup,
}

struct Inner<T> {
  connection:     Connection,
  socket:         T,
  status:         Status,
  poll:           Poll,
  registration:   Registration,
  set_readiness:  SetReadiness,
  handle:         Option<JoinHandle<Result<(), Error>>>,
  hb_handle:      Option<JoinHandle<()>>,
  capacity:       usize,
  receive_buffer: Buffer,
  send_buffer:    Buffer,
  can_write:      bool,
  can_read:       bool,
  has_data:       bool,
  send_heartbeat: Arc<AtomicBool>,
}

impl<T> Drop for Inner<T> {
  fn drop(&mut self) {
    if let Some(handle) = self.handle.take() {
      handle.join().expect("io loop failed").expect("io loop failed");
    }
    if let Some(hb_handle) = self.hb_handle.take() {
      hb_handle.join().expect("heartbeat loop failed");
    }
  }
}

impl<T: Evented + Read + Write + Send + 'static> Inner<T> {
  fn new(connection: Connection, socket: T) -> Result<Self, Error> {
    let capacity = std::cmp::max(8192, connection.configuration.frame_max() as usize);
    let (registration, set_readiness) = Registration::new2();
    let inner = Self {
      connection,
      socket,
      status:         Status::Initial,
      poll:           Poll::new().map_err(ErrorKind::IOError)?,
      registration,
      set_readiness,
      handle:         None,
      hb_handle:      None,
      capacity,
      receive_buffer: Buffer::with_capacity(capacity),
      send_buffer:    Buffer::with_capacity(capacity),
      can_write:      false,
      can_read:       false,
      has_data:       false,
      send_heartbeat: Arc::new(AtomicBool::new(false)),
    };
    inner.poll.register(&inner.socket, SOCKET, Ready::readable() | Ready::writable(), PollOpt::edge()).map_err(ErrorKind::IOError)?;
    inner.poll.register(&inner.connection, DATA, Ready::readable(), PollOpt::edge()).map_err(ErrorKind::IOError)?;
    inner.poll.register(&inner.registration, CONTINUE, Ready::readable(), PollOpt::edge()).map_err(ErrorKind::IOError)?;
    Ok(inner)
  }

  pub fn start_heartbeat(&mut self, interval: Duration) -> Result<(), Error> {
    let send_hartbeat = self.send_heartbeat.clone();
    let hb_handle = ThreadBuilder::new().name("heartbeat".to_owned()).spawn(move || {
      loop {
        let start         = Instant::now();
        let mut remaining = interval;

        loop {
          thread::park_timeout(remaining);
          let elapsed = start.elapsed();
          if elapsed >= remaining {
            break
          }
          remaining -= interval - elapsed;
        }

        send_hartbeat.store(true, Ordering::Relaxed);
      }
    }).map_err(ErrorKind::IOError)?;
    self.hb_handle = Some(hb_handle);
    Ok(())
  }

  fn heartbeat(&mut self) -> Result<(), Error> {
    self.connection.send_heartbeat()?;
    self.send_heartbeat.store(false, Ordering::Relaxed);
    Ok(())
  }

  fn ensure_setup(&mut self) -> Result<(), Error> {
    if self.status != Status::Setup && self.connection.status.connected() {
      let frame_max = self.connection.configuration.frame_max() as usize;
      self.capacity = std::cmp::max(self.capacity, frame_max);
      self.receive_buffer.grow(256 * self.capacity);
      self.send_buffer.grow(256 * self.capacity);
      let heartbeat = self.connection.configuration.heartbeat();
      if heartbeat != 0 {
        self.start_heartbeat(Duration::from_secs(heartbeat as u64))?;
      }
      self.status = Status::Setup;
    }
    Ok(())
  }

  fn wants_to_write(&self) -> bool {
    self.can_write && self.has_data
  }

  fn wants_to_read(&self) -> bool {
    self.can_read
  }

  fn do_run(&mut self) -> Result<(), Error> {
    loop {
      if self.send_heartbeat.load(Ordering::Relaxed) {
        self.heartbeat()?;
      }
      if self.wants_to_write() && !self.connection.status.blocked() {
        if let Err(e) = self.write_to_stream() {
          match e.kind() {
            ErrorKind::NoNewMessage => self.has_data = false,
            ErrorKind::IOError(e) if e.kind() == io::ErrorKind::WouldBlock => self.can_write = false,
            ErrorKind::SendBufferTooSmall => { /* We already shifted the buffer and we already limit the size of the frames, so retry */ },
            _ => {
              error!("error writing: {:?}", e);
              self.connection.set_error()?;
              return Err(e);
            }
          }
        }
        self.send_buffer.shift_unless_available(self.capacity);
      }
      if self.wants_to_read() {
        if let Err(e) = self.read_from_stream() {
          match e.kind() {
            ErrorKind::IOError(e) if e.kind() == io::ErrorKind::WouldBlock => self.can_read = false,
            _ => {
              error!("error reading: {:?}", e);
              self.connection.set_error()?;
              return Err(e);
            }
          }
        }
        self.receive_buffer.shift_unless_available(self.capacity);
      }
      if self.can_parse() {
        self.parse()?;
      }
      if !(self.can_read || !self.can_write) {
        if self.wants_to_read() || self.wants_to_write() || self.can_parse() {
          self.set_readiness.set_readiness(Ready::readable()).map_err(ErrorKind::IOError)?;
        }
        break;
      }
    }
    Ok(())
  }

  fn run(&mut self, events: &mut Events) -> Result<(), Error> {
    self.ensure_setup()?;
    self.poll.poll(events, None).map_err(ErrorKind::IOError)?;
    for event in events.iter() {
      match event.token() {
        SOCKET    => {
          if event.readiness().is_readable() {
            self.can_read = true;
          }
          if event.readiness().is_writable() {
            self.can_write = true;
          }
        },
        DATA      => self.has_data = true,
        _         => {},
      }
    }
    self.do_run()
  }

  fn can_parse(&self) -> bool {
    self.receive_buffer.available_data() > 0
  }

  fn write_to_stream(&mut self) -> Result<(), Error> {
    self.serialize()?;

    self.socket.write(&self.send_buffer.data()).map(|sz| {
      trace!("wrote {} bytes", sz);
      self.send_buffer.consume(sz);
    }).map_err(|e| ErrorKind::IOError(e).into())
  }

  fn read_from_stream(&mut self) -> Result<(), Error> {
    let state = self.connection.status.state();
    if state == ConnectionState::Initial || state == ConnectionState::Closed || state == ConnectionState::Error {
      self.connection.set_error()?;
      Err(ErrorKind::InvalidConnectionState(state).into())
    } else {
      self.socket.read(&mut self.receive_buffer.space()).map(|sz| {
        trace!("read {} bytes", sz);
        self.receive_buffer.fill(sz);
      }).map_err(|e| ErrorKind::IOError(e).into())
    }
  }

  fn serialize(&mut self) -> Result<(), Error> {
    if let Some((send_id, next_msg)) = self.connection.next_frame() {
      trace!("will write to buffer: {:?}", next_msg);
      match gen_frame(self.send_buffer.space(), &next_msg).map(|tup| tup.0) {
        Ok(sz) => {
          self.send_buffer.fill(sz);
          self.connection.mark_sent(send_id);
          Ok(())
        },
        Err(e) => {
          match e {
            GenError::BufferTooSmall(_) => {
              // Requeue msg
              self.connection.requeue_frame(send_id, next_msg)?;
              self.send_buffer.shift();
              Err(ErrorKind::SendBufferTooSmall.into())
            },
            GenError::InvalidOffset | GenError::CustomError(_) | GenError::NotYetImplemented => {
              error!("error generating frame: {:?}", e);
              self.connection.set_error()?;
              Err(ErrorKind::SerialisationError(e).into())
            }
          }
        }
      }
    } else {
      Err(ErrorKind::NoNewMessage.into())
    }
  }

  fn parse(&mut self) -> Result<(), Error> {
    match parse_frame(self.receive_buffer.data()) {
      Ok((i, f)) => {

        let consumed = self.receive_buffer.data().offset(i);
        self.receive_buffer.consume(consumed);

        if let Err(e) = self.connection.handle_frame(f) {
          self.connection.set_error()?;
          Err(e)
        } else {
          Ok(())
        }
      },
      Err(e) => {
        if e.is_incomplete() {
          self.receive_buffer.shift();
          Ok(())
        } else {
          error!("parse error: {:?}", e);
          self.connection.set_error()?;
          Err(ErrorKind::ParsingError(format!("{:?}", e)).into())
        }
      }
    }
  }
}
<commit_msg>async: fix io_loop continue condition<commit_after>use amq_protocol::frame::{GenError, Offset, gen_frame, parse_frame};
use log::{error, trace};
use mio::{Evented, Events, Poll, PollOpt, Ready, Registration, SetReadiness, Token};
use parking_lot::Mutex;

use std::{
  io::{self, Read, Write},
  sync::{
    Arc,
    atomic::{AtomicBool, Ordering},
  },
  thread::{self, Builder as ThreadBuilder, JoinHandle},
  time::{Duration, Instant},
};

use crate::{
  buffer::Buffer,
  connection::Connection,
  connection_status::ConnectionState,
  error::{Error, ErrorKind},
};

const SOCKET:   Token = Token(0);
const DATA:     Token = Token(1);
const CONTINUE: Token = Token(2);

pub struct IoLoop<T> {
  inner: Arc<Mutex<Inner<T>>>,
}

impl<T: Evented + Read + Write + Send + 'static> IoLoop<T> {
  pub fn new(connection: Connection, socket: T) -> Result<Self, Error> {
    let inner = Arc::new(Mutex::new(Inner::new(connection, socket)?));
    Ok(Self { inner })
  }

  pub fn run(&self) -> Result<(), Error> {
    let inner  = self.inner.clone();
    let handle = ThreadBuilder::new().name("io_loop".to_owned()).spawn(move || {
      let mut events = Events::with_capacity(1024);
      loop {
        inner.lock().run(&mut events)?;
      }
    }).map_err(ErrorKind::IOError)?;
    self.inner.lock().handle = Some(handle);
    Ok(())
  }
}

#[derive(PartialEq)]
enum Status {
  Initial,
  Setup,
}

struct Inner<T> {
  connection:     Connection,
  socket:         T,
  status:         Status,
  poll:           Poll,
  registration:   Registration,
  set_readiness:  SetReadiness,
  handle:         Option<JoinHandle<Result<(), Error>>>,
  hb_handle:      Option<JoinHandle<()>>,
  capacity:       usize,
  receive_buffer: Buffer,
  send_buffer:    Buffer,
  can_write:      bool,
  can_read:       bool,
  has_data:       bool,
  send_heartbeat: Arc<AtomicBool>,
}

impl<T> Drop for Inner<T> {
  fn drop(&mut self) {
    if let Some(handle) = self.handle.take() {
      handle.join().expect("io loop failed").expect("io loop failed");
    }
    if let Some(hb_handle) = self.hb_handle.take() {
      hb_handle.join().expect("heartbeat loop failed");
    }
  }
}

impl<T: Evented + Read + Write + Send + 'static> Inner<T> {
  fn new(connection: Connection, socket: T) -> Result<Self, Error> {
    let capacity = std::cmp::max(8192, connection.configuration.frame_max() as usize);
    let (registration, set_readiness) = Registration::new2();
    let inner = Self {
      connection,
      socket,
      status:         Status::Initial,
      poll:           Poll::new().map_err(ErrorKind::IOError)?,
      registration,
      set_readiness,
      handle:         None,
      hb_handle:      None,
      capacity,
      receive_buffer: Buffer::with_capacity(capacity),
      send_buffer:    Buffer::with_capacity(capacity),
      can_write:      false,
      can_read:       false,
      has_data:       false,
      send_heartbeat: Arc::new(AtomicBool::new(false)),
    };
    inner.poll.register(&inner.socket, SOCKET, Ready::readable() | Ready::writable(), PollOpt::edge()).map_err(ErrorKind::IOError)?;
    inner.poll.register(&inner.connection, DATA, Ready::readable(), PollOpt::edge()).map_err(ErrorKind::IOError)?;
    inner.poll.register(&inner.registration, CONTINUE, Ready::readable(), PollOpt::edge()).map_err(ErrorKind::IOError)?;
    Ok(inner)
  }

  pub fn start_heartbeat(&mut self, interval: Duration) -> Result<(), Error> {
    let send_hartbeat = self.send_heartbeat.clone();
    let hb_handle = ThreadBuilder::new().name("heartbeat".to_owned()).spawn(move || {
      loop {
        let start         = Instant::now();
        let mut remaining = interval;

        loop {
          thread::park_timeout(remaining);
          let elapsed = start.elapsed();
          if elapsed >= remaining {
            break
          }
          remaining -= interval - elapsed;
        }

        send_hartbeat.store(true, Ordering::Relaxed);
      }
    }).map_err(ErrorKind::IOError)?;
    self.hb_handle = Some(hb_handle);
    Ok(())
  }

  fn heartbeat(&mut self) -> Result<(), Error> {
    self.connection.send_heartbeat()?;
    self.send_heartbeat.store(false, Ordering::Relaxed);
    Ok(())
  }

  fn ensure_setup(&mut self) -> Result<(), Error> {
    if self.status != Status::Setup && self.connection.status.connected() {
      let frame_max = self.connection.configuration.frame_max() as usize;
      self.capacity = std::cmp::max(self.capacity, frame_max);
      self.receive_buffer.grow(256 * self.capacity);
      self.send_buffer.grow(256 * self.capacity);
      let heartbeat = self.connection.configuration.heartbeat();
      if heartbeat != 0 {
        self.start_heartbeat(Duration::from_secs(heartbeat as u64))?;
      }
      self.status = Status::Setup;
    }
    Ok(())
  }

  fn wants_to_write(&self) -> bool {
    self.can_write && self.has_data
  }

  fn wants_to_read(&self) -> bool {
    self.can_read
  }

  fn do_run(&mut self) -> Result<(), Error> {
    loop {
      if self.send_heartbeat.load(Ordering::Relaxed) {
        self.heartbeat()?;
      }
      if self.wants_to_write() && !self.connection.status.blocked() {
        if let Err(e) = self.write_to_stream() {
          match e.kind() {
            ErrorKind::NoNewMessage => self.has_data = false,
            ErrorKind::IOError(e) if e.kind() == io::ErrorKind::WouldBlock => self.can_write = false,
            ErrorKind::SendBufferTooSmall => { /* We already shifted the buffer and we already limit the size of the frames, so retry */ },
            _ => {
              error!("error writing: {:?}", e);
              self.connection.set_error()?;
              return Err(e);
            }
          }
        }
        self.send_buffer.shift_unless_available(self.capacity);
      }
      if self.wants_to_read() {
        if let Err(e) = self.read_from_stream() {
          match e.kind() {
            ErrorKind::IOError(e) if e.kind() == io::ErrorKind::WouldBlock => self.can_read = false,
            _ => {
              error!("error reading: {:?}", e);
              self.connection.set_error()?;
              return Err(e);
            }
          }
        }
        self.receive_buffer.shift_unless_available(self.capacity);
      }
      if self.can_parse() {
        self.parse()?;
      }
      if !self.can_read || !self.can_write {
        if self.wants_to_read() || self.can_parse() || self.has_data {
          self.set_readiness.set_readiness(Ready::readable()).map_err(ErrorKind::IOError)?;
        }
        break;
      }
    }
    Ok(())
  }

  fn run(&mut self, events: &mut Events) -> Result<(), Error> {
    self.ensure_setup()?;
    self.poll.poll(events, None).map_err(ErrorKind::IOError)?;
    for event in events.iter() {
      match event.token() {
        SOCKET    => {
          if event.readiness().is_readable() {
            self.can_read = true;
          }
          if event.readiness().is_writable() {
            self.can_write = true;
          }
        },
        DATA      => self.has_data = true,
        _         => {},
      }
    }
    self.do_run()
  }

  fn can_parse(&self) -> bool {
    self.receive_buffer.available_data() > 0
  }

  fn write_to_stream(&mut self) -> Result<(), Error> {
    self.serialize()?;

    self.socket.write(&self.send_buffer.data()).map(|sz| {
      trace!("wrote {} bytes", sz);
      self.send_buffer.consume(sz);
    }).map_err(|e| ErrorKind::IOError(e).into())
  }

  fn read_from_stream(&mut self) -> Result<(), Error> {
    let state = self.connection.status.state();
    if state == ConnectionState::Initial || state == ConnectionState::Closed || state == ConnectionState::Error {
      self.connection.set_error()?;
      Err(ErrorKind::InvalidConnectionState(state).into())
    } else {
      self.socket.read(&mut self.receive_buffer.space()).map(|sz| {
        trace!("read {} bytes", sz);
        self.receive_buffer.fill(sz);
      }).map_err(|e| ErrorKind::IOError(e).into())
    }
  }

  fn serialize(&mut self) -> Result<(), Error> {
    if let Some((send_id, next_msg)) = self.connection.next_frame() {
      trace!("will write to buffer: {:?}", next_msg);
      match gen_frame(self.send_buffer.space(), &next_msg).map(|tup| tup.0) {
        Ok(sz) => {
          self.send_buffer.fill(sz);
          self.connection.mark_sent(send_id);
          Ok(())
        },
        Err(e) => {
          match e {
            GenError::BufferTooSmall(_) => {
              // Requeue msg
              self.connection.requeue_frame(send_id, next_msg)?;
              self.send_buffer.shift();
              Err(ErrorKind::SendBufferTooSmall.into())
            },
            GenError::InvalidOffset | GenError::CustomError(_) | GenError::NotYetImplemented => {
              error!("error generating frame: {:?}", e);
              self.connection.set_error()?;
              Err(ErrorKind::SerialisationError(e).into())
            }
          }
        }
      }
    } else {
      Err(ErrorKind::NoNewMessage.into())
    }
  }

  fn parse(&mut self) -> Result<(), Error> {
    match parse_frame(self.receive_buffer.data()) {
      Ok((i, f)) => {

        let consumed = self.receive_buffer.data().offset(i);
        self.receive_buffer.consume(consumed);

        if let Err(e) = self.connection.handle_frame(f) {
          self.connection.set_error()?;
          Err(e)
        } else {
          Ok(())
        }
      },
      Err(e) => {
        if e.is_incomplete() {
          self.receive_buffer.shift();
          Ok(())
        } else {
          error!("parse error: {:?}", e);
          self.connection.set_error()?;
          Err(ErrorKind::ParsingError(format!("{:?}", e)).into())
        }
      }
    }
  }
}
<|endoftext|>


<commit_before>#![no_main]
use libfuzzer_sys::fuzz_target;

use minidump::{MinidumpContext, MinidumpContextValidity, MinidumpMemory};
use minidump::{MinidumpModule, MinidumpModuleList};
use minidump_processor::walk_stack;
use minidump_processor::{string_symbol_supplier, CallStack, Symbolizer};
use std::collections::HashMap;
use test_assembler::Section;

struct TestFixture {
    pub raw: minidump::MinidumpRawContext,
    pub modules: MinidumpModuleList,
    pub symbols: HashMap<String, String>,
}

impl TestFixture {
    pub fn new(raw: minidump::MinidumpRawContext) -> TestFixture {
        TestFixture {
            raw,
            // Give the two modules reasonable standard locations and names
            // for tests to play with.
            modules: MinidumpModuleList::from_modules(vec![
                MinidumpModule::new(0x40000000, 0x10000, "module1"),
                MinidumpModule::new(0x50000000, 0x10000, "module2"),
            ]),
            symbols: HashMap::new(),
        }
    }

    pub async fn walk_stack(self, stack: Section) -> Option<CallStack> {
        let context = MinidumpContext {
            raw: self.raw,
            valid: MinidumpContextValidity::All,
        };

        let base = stack.start().value().unwrap();
        let size = stack.size();
        let stack = stack.get_contents().unwrap();
        let stack_memory = MinidumpMemory {
            desc: Default::default(),
            base_address: base,
            size,
            bytes: &stack,
        };

        let symbolizer = Symbolizer::new(string_symbol_supplier(self.symbols.clone()));

        Some(
            walk_stack(
                &Some(&context),
                Some(&stack_memory),
                &self.modules,
                &symbolizer,
            )
            .await,
        )
    }
}

fuzz_target!(|data: (&[u8], minidump::MinidumpRawContext)| {
    let f = TestFixture::new(data.1);
    let mut stack = Section::new();
    stack.start().set_const(0x80000000);
    stack = stack.append_bytes(data.0);
    minidump_processor_fuzz::fuzzing_block_on(f.walk_stack(stack));
});
<commit_msg>try to fix fuzz target<commit_after>#![no_main]
use libfuzzer_sys::fuzz_target;

use minidump::{MinidumpContext, MinidumpContextValidity, MinidumpMemory};
use minidump::{MinidumpModule, MinidumpModuleList};
use minidump::system_info::{Cpu, Os};
use minidump_processor::walk_stack;
use minidump_processor::{string_symbol_supplier, CallStack, Symbolizer, SystemInfo};
use std::collections::HashMap;
use test_assembler::Section;

struct TestFixture {
    pub raw: minidump::MinidumpRawContext,
    pub modules: MinidumpModuleList,
    pub symbols: HashMap<String, String>,
}

impl TestFixture {
    pub fn new(raw: minidump::MinidumpRawContext) -> TestFixture {
        TestFixture {
            raw,
            // Give the two modules reasonable standard locations and names
            // for tests to play with.
            modules: MinidumpModuleList::from_modules(vec![
                MinidumpModule::new(0x40000000, 0x10000, "module1"),
                MinidumpModule::new(0x50000000, 0x10000, "module2"),
            ]),
            symbols: HashMap::new(),
        }
    }

    pub async fn walk_stack(self, stack: Section) -> Option<CallStack> {
        let context = MinidumpContext {
            raw: self.raw,
            valid: MinidumpContextValidity::All,
        };

        let base = stack.start().value().unwrap();
        let size = stack.size();
        let stack = stack.get_contents().unwrap();
        let stack_memory = MinidumpMemory {
            desc: Default::default(),
            base_address: base,
            size,
            bytes: &stack,
        };
        let system_info = SystemInfo {
            os: Os::Windows,
            os_version: None,
            os_build: None,
            cpu: Cpu::X86_64,
            cpu_info: None,
            cpu_microcode_version: None,
            cpu_count: 1,
        };

        let symbolizer = Symbolizer::new(string_symbol_supplier(self.symbols.clone()));

        Some(
            walk_stack(
                &Some(&context),
                Some(&stack_memory),
                &self.modules,
                &system_info,
                &symbolizer,
            )
            .await,
        )
    }
}

fuzz_target!(|data: (&[u8], minidump::MinidumpRawContext)| {
    let f = TestFixture::new(data.1);
    let mut stack = Section::new();
    stack.start().set_const(0x80000000);
    stack = stack.append_bytes(data.0);
    minidump_processor_fuzz::fuzzing_block_on(f.walk_stack(stack));
});
<|endoftext|>


<commit_before>/*
 * Cymbalum, Molecular Simulation in Rust
 * Copyright (C) 2015 Guillaume Fraux
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/
*/
#![allow(non_snake_case)]
//! Testing physical properties of a Lennard-Jones gaz of Helium.
extern crate cymbalum;
use self::cymbalum::*;

use std::sync::{Once, ONCE_INIT};
static START: Once = ONCE_INIT;

use std::path::Path;

fn setup<T: Integrator + 'static>(integrator: T) -> (Simulation, Universe) {
    let data_dir = Path::new(file!()).parent().unwrap();
    let configuration = data_dir.join("data").join("Helium.xyz");
    let mut universe = Universe::from_file(configuration.to_str().unwrap()).unwrap();
    universe.set_cell(UnitCell::cubic(10.0));
    universe.add_pair_interaction("He", "He",
        LennardJones{
            sigma: units::from(2.0, "A").unwrap(),
            epsilon: units::from(0.2, "kJ/mol").unwrap()
        }
    );

    let mut velocities = BoltzmanVelocities::new(units::from(300.0, "K").unwrap());
    velocities.init(&mut universe);

    let simulation = Simulation::new(
        MolecularDynamics::from_integrator(integrator)
    );
    return (simulation, universe);
}

#[test]
fn constant_energy_velocity_verlet() {
    START.call_once(|| {Logger::stdout();});
    let (mut simulation, mut universe) = setup(
        VelocityVerlet::new(units::from(1.0, "fs").unwrap())
    );

    let E_initial = universe.total_energy();
    simulation.run(&mut universe, 1000);
    let E_final = universe.total_energy();

    assert!(f64::abs(E_initial - E_final) < 1e-5);
}

#[test]
fn constant_energy_verlet() {
    START.call_once(|| {Logger::stdout();});
    let (mut simulation, mut universe) = setup(
        Verlet::new(units::from(1.0, "fs").unwrap())
    );
    let E_initial = universe.total_energy();
    simulation.run(&mut universe, 1000);
    let E_final = universe.total_energy();
    assert!(f64::abs(E_initial - E_final) < 1e-4);
}

#[test]
fn constant_energy_leap_frog() {
    START.call_once(|| {Logger::stdout();});
    let (mut simulation, mut universe) = setup(
        LeapFrog::new(units::from(1.0, "fs").unwrap())
    );
    let E_initial = universe.total_energy();
    simulation.run(&mut universe, 1000);
    let E_final = universe.total_energy();
    assert!(f64::abs(E_initial - E_final) < 1e-5);
}

#[test]
fn perfect_gaz() {
    START.call_once(|| {Logger::stdout();});
    let (mut simulation, mut universe) = setup(
        VelocityVerlet::new(units::from(1.0, "fs").unwrap())
    );

    // dilating the universe!
    for particle in universe.iter_mut() {
        let pos = particle.position().clone();
        particle.set_position(10.0 * pos);
    }
    universe.set_cell(UnitCell::cubic(100.0));

    simulation.run(&mut universe, 1000);
    let P = universe.pressure();
    let V = universe.volume();
    let T = universe.temperature();
    let N = universe.size() as f64;

    assert!(f64::abs(P * V - N * constants::K_BOLTZMANN * T) < 1e-3);
}
<commit_msg>Add test for the Berendsen barostat<commit_after>/*
 * Cymbalum, Molecular Simulation in Rust
 * Copyright (C) 2015 Guillaume Fraux
 *
 * This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/
*/
#![allow(non_snake_case)]
//! Testing physical properties of a Lennard-Jones gaz of Helium.
extern crate cymbalum;
use self::cymbalum::*;

use std::sync::{Once, ONCE_INIT};
static START: Once = ONCE_INIT;

use std::path::Path;

fn get_universe() -> Universe {
    let data_dir = Path::new(file!()).parent().unwrap();
    let configuration = data_dir.join("data").join("Helium.xyz");
    let mut universe = Universe::from_file(configuration.to_str().unwrap()).unwrap();
    universe.set_cell(UnitCell::cubic(10.0));
    universe.add_pair_interaction("He", "He",
        LennardJones{
            sigma: units::from(2.0, "A").unwrap(),
            epsilon: units::from(0.2, "kJ/mol").unwrap()
        }
    );

    let mut velocities = BoltzmanVelocities::new(units::from(300.0, "K").unwrap());
    velocities.init(&mut universe);
    return universe;
}

#[test]
fn constant_energy_velocity_verlet() {
    START.call_once(|| {Logger::stdout();});
    let mut universe = get_universe();
    let mut simulation = Simulation::new(
        MolecularDynamics::from_integrator(
            VelocityVerlet::new(units::from(1.0, "fs").unwrap())
        )
    );

    let E_initial = universe.total_energy();
    simulation.run(&mut universe, 1000);
    let E_final = universe.total_energy();

    assert!(f64::abs(E_initial - E_final) < 1e-5);
}

#[test]
fn constant_energy_verlet() {
    START.call_once(|| {Logger::stdout();});
    let mut universe = get_universe();
    let mut simulation = Simulation::new(
        MolecularDynamics::from_integrator(
            Verlet::new(units::from(1.0, "fs").unwrap())
        )
    );
    let E_initial = universe.total_energy();
    simulation.run(&mut universe, 1000);
    let E_final = universe.total_energy();
    assert!(f64::abs(E_initial - E_final) < 1e-4);
}

#[test]
fn constant_energy_leap_frog() {
    START.call_once(|| {Logger::stdout();});
    let mut universe = get_universe();
    let mut simulation = Simulation::new(
        MolecularDynamics::from_integrator(
            LeapFrog::new(units::from(1.0, "fs").unwrap())
        )
    );
    let E_initial = universe.total_energy();
    simulation.run(&mut universe, 1000);
    let E_final = universe.total_energy();
    assert!(f64::abs(E_initial - E_final) < 1e-5);
}

#[test]
fn perfect_gaz() {
    START.call_once(|| {Logger::stdout();});
    let mut universe = get_universe();
    let mut simulation = Simulation::new(
        MolecularDynamics::from_integrator(
            VelocityVerlet::new(units::from(1.0, "fs").unwrap())
        )
    );

    // dilating the universe!
    for particle in universe.iter_mut() {
        let pos = particle.position().clone();
        particle.set_position(10.0 * pos);
    }
    universe.set_cell(UnitCell::cubic(100.0));

    simulation.run(&mut universe, 1000);
    let P = universe.pressure();
    let V = universe.volume();
    let T = universe.temperature();
    let N = universe.size() as f64;

    assert!(f64::abs(P * V - N * constants::K_BOLTZMANN * T) < 1e-3);
}

#[test]
fn berendsen_barostat() {
    START.call_once(|| {Logger::stdout();});
    let mut universe = get_universe();
    let mut md = MolecularDynamics::from_integrator(
        BerendsenBarostat::with_timestep(
            units::from(1.0, "fs").unwrap(),
            units::from(5000.0, "bar").unwrap(),
            100.0
        )
    );
    md.add_control(BerendsenThermostat::new(units::from(300.0, "K").unwrap(), 10.0));
    let mut simulation = Simulation::new(md);

    simulation.run(&mut universe, 5000);
    let P = universe.pressure();
    let T = universe.temperature();

    assert!(f64::abs(P - units::from(5000.0, "bar").unwrap())/P < 1e-2);
    assert!(f64::abs(T - units::from(300.0, "K").unwrap()) < 1.0);
}
<|endoftext|>


<commit_before>#![cfg(any(feature = "rustc-serialize", feature = "serde"))]
#[cfg(feature = "rustc-serialize")]
extern crate rustc_serialize as serialize;
extern crate ndarray;

#[cfg(feature = "serde")]
extern crate serde;

#[cfg(feature = "rustc-serialize")]
use serialize::json;

use ndarray::{arr0, arr1, arr2, Array, Ix, S, Si};

#[cfg(feature = "serde")]
#[test]
fn test_serde()
{
    let mut out = std::io::stdout();
    {
        let a = arr0::<f32>(2.72);
        println!("{:?}", a);
        let v = serde::json::to_value(&a);
        serde::json::to_writer(&mut out, &a);
        /*
        let serial = serde::json::encode(&a).unwrap();
        println!("Encode {:?} => {:?}", a, serial);
        */
        //let res = json::decode::<Array<f32, _>>(&serial);
        //println!("{:?}", res);
        //assert_eq!(a, res.unwrap());
    }

    {
        let a = arr2(&[[2.7, 1., 2.],
                       [ 1., 0., 1.]]);
        println!("{:?}", a);
        serde::json::to_writer(&mut out, &a);
        /*
        let serial = serde::json::encode(&a).unwrap();
        println!("{:?}", serial);
        let res = json::decode::<Array<f32, _>>(&serial);
        println!("{:?}", res);
        assert_eq!(a, res.unwrap());
        */
    }
}

#[cfg(feature = "rustc-serialize")]
#[test]
fn serial_many_dim()
{
    {
        let a = arr0::<f32>(2.72);
        let serial = json::encode(&a).unwrap();
        println!("Encode {:?} => {:?}", a, serial);
        let res = json::decode::<Array<f32, _>>(&serial);
        println!("{:?}", res);
        assert_eq!(a, res.unwrap());
    }

    {
        let a = arr1::<f32>(&[2.72, 1., 2.]);
        println!("{:?}", a);
        let serial = json::encode(&a).unwrap();
        println!("{:?}", serial);
        let res = json::decode::<Array<f32, _>>(&serial);
        println!("{:?}", res);
        assert_eq!(a, res.unwrap());
    }

    {
        let a = arr2(&[[3., 1., 2.2], [3.1, 4., 7.]]);
        println!("{:?}", a);
        let serial = json::encode(&a).unwrap();
        println!("{:?}", serial);
        let res = json::decode::<Array<f32, _>>(&serial);
        println!("{:?}", res);
        assert_eq!(a, res.unwrap());
        let text = r##"{"v":1,"dim":[2,3],"data":[3,1,2.2,3.1,4,7]}"##;
        let b = json::decode::<Array<f32, (Ix, Ix)>>(text);
        assert_eq!(a, b.unwrap());
    }

    {
        // Test a sliced array.
        let mut a = Array::range(0., 32.0_f32).reshape((2, 2, 2, 4));
        a.islice(&[Si(0, None, -1), S, S, Si(0, Some(2), 1)]);
        println!("{:?}", a);
        let serial = json::encode(&a).unwrap();
        println!("{:?}", serial);
        let res = json::decode::<Array<f32, _>>(&serial);
        println!("{:?}", res);
        assert_eq!(a, res.unwrap());
    }
}

#[cfg(feature = "rustc-serialize")]
#[test]
fn serial_wrong_count()
{
    // one element too few
    let text = r##"{"v":1,"dim":[2,3],"data":[3,1,2.2,3.1,4]}"##;
    let arr = json::decode::<Array<f32, (Ix, Ix)>>(text);
    println!("{:?}", arr);
    assert!(arr.is_err());

    // future version
    let text = r##"{"v":200,"dim":[2,3],"data":[3,1,2.2,3.1,4,7]}"##;
    let arr = json::decode::<Array<f32, (Ix, Ix)>>(text);
    println!("{:?}", arr);
    assert!(arr.is_err());
}
<commit_msg>Fix serialization test<commit_after>#![cfg(any(feature = "rustc-serialize", feature = "serde"))]
#[cfg(feature = "rustc-serialize")]
extern crate rustc_serialize as serialize;
extern crate ndarray;

#[cfg(feature = "serde")]
extern crate serde;

#[cfg(feature = "rustc-serialize")]
use serialize::json;

use ndarray::{arr0, arr1, arr2, Array, Ix, S, Si};

#[cfg(feature = "serde")]
#[test]
fn test_serde()
{
    let mut out = std::io::stdout();
    {
        let a = arr0::<f32>(2.72);
        println!("{:?}", a);
        let v = serde::json::to_value(&a);
        serde::json::to_writer(&mut out, &a);
        /*
        let serial = serde::json::encode(&a).unwrap();
        println!("Encode {:?} => {:?}", a, serial);
        */
        //let res = json::decode::<Array<f32, _>>(&serial);
        //println!("{:?}", res);
        //assert_eq!(a, res.unwrap());
    }

    {
        let a = arr2(&[[2.7, 1., 2.],
                       [ 1., 0., 1.]]);
        println!("{:?}", a);
        serde::json::to_writer(&mut out, &a);
        /*
        let serial = serde::json::encode(&a).unwrap();
        println!("{:?}", serial);
        let res = json::decode::<Array<f32, _>>(&serial);
        println!("{:?}", res);
        assert_eq!(a, res.unwrap());
        */
    }
}

#[cfg(feature = "rustc-serialize")]
#[test]
fn serial_many_dim()
{
    {
        let a = arr0::<f32>(2.72);
        let serial = json::encode(&a).unwrap();
        println!("Encode {:?} => {:?}", a, serial);
        let res = json::decode::<Array<f32, _>>(&serial);
        println!("{:?}", res);
        assert_eq!(a, res.unwrap());
    }

    {
        let a = arr1::<f32>(&[2.72, 1., 2.]);
        println!("{:?}", a);
        let serial = json::encode(&a).unwrap();
        println!("{:?}", serial);
        let res = json::decode::<Array<f32, _>>(&serial);
        println!("{:?}", res);
        assert_eq!(a, res.unwrap());
    }

    {
        let a = arr2(&[[3., 1., 2.2], [3.1, 4., 7.]]);
        println!("{:?}", a);
        let serial = json::encode(&a).unwrap();
        println!("{:?}", serial);
        let res = json::decode::<Array<f32, _>>(&serial);
        println!("{:?}", res);
        assert_eq!(a, res.unwrap());
        let text = r##"{"v":1,"dim":[2,3],"data":[3,1,2.2,3.1,4,7]}"##;
        let b = json::decode::<Array<f32, (Ix, Ix)>>(text);
        assert_eq!(a, b.unwrap());
    }

    {
        // Test a sliced array.
        let mut a = Array::linspace(0., 31., 32).reshape((2, 2, 2, 4));
        a.islice(&[Si(0, None, -1), S, S, Si(0, Some(2), 1)]);
        println!("{:?}", a);
        let serial = json::encode(&a).unwrap();
        println!("{:?}", serial);
        let res = json::decode::<Array<f32, _>>(&serial);
        println!("{:?}", res);
        assert_eq!(a, res.unwrap());
    }
}

#[cfg(feature = "rustc-serialize")]
#[test]
fn serial_wrong_count()
{
    // one element too few
    let text = r##"{"v":1,"dim":[2,3],"data":[3,1,2.2,3.1,4]}"##;
    let arr = json::decode::<Array<f32, (Ix, Ix)>>(text);
    println!("{:?}", arr);
    assert!(arr.is_err());

    // future version
    let text = r##"{"v":200,"dim":[2,3],"data":[3,1,2.2,3.1,4,7]}"##;
    let arr = json::decode::<Array<f32, (Ix, Ix)>>(text);
    println!("{:?}", arr);
    assert!(arr.is_err());
}
<|endoftext|>


<commit_before>//! Crate documentation builder
//!
//! This module is extremely similar to cargo install operation, except it's building
//! documentation of a crate and not installing anything.

use std::path::{Path, PathBuf};
use std::env;
use std::sync::Arc;

use cargo::core::{SourceId, Dependency, Registry, Source, Package, Workspace};
use cargo::util::{CargoResult, Config, human, Filesystem};
use cargo::sources::SourceConfigMap;
use cargo::ops::{self, Packages, DefaultExecutor};

use Metadata;

/// Builds documentation of a crate and version.
///
/// Crate will be built into current working directory/crate-version.
///
/// It will build latest version, if no version is given.
// idea is to make cargo to download
// and build a crate and its documentation
// instead of doing it manually like in the previous version of cratesfyi
pub fn build_doc(name: &str, vers: Option<&str>, target: Option<&str>) -> CargoResult<Package> {
    let config = try!(Config::default());
    let source_id = try!(SourceId::crates_io(&config));

    let source_map = try!(SourceConfigMap::new(&config));
    let mut source = try!(source_map.load(&source_id));

    // update crates.io-index registry
    try!(source.update());

    let dep = try!(Dependency::parse_no_deprecated(name, vers, &source_id));
    let deps = try!(source.query(&dep));
    let pkg = try!(deps.iter().map(|p| p.package_id()).max()
                   // FIXME: This is probably not a rusty way to handle options and results
                   //        or maybe it is who knows...
                   .map(|pkgid| source.download(pkgid))
                   .unwrap_or(Err(human("PKG download error"))));

    let current_dir = try!(env::current_dir());
    let target_dir = PathBuf::from(current_dir)
        .join(format!("{}-{}", pkg.manifest().name(), pkg.manifest().version()));

    let metadata = Metadata::from_package(&pkg);

    let opts = ops::CompileOptions {
        config: &config,
        jobs: None,
        target: target,
        features: &metadata.features.unwrap_or(Vec::new()),
        all_features: metadata.all_features,
        no_default_features: metadata.no_default_features,
        spec: Packages::Packages(&[]),
        mode: ops::CompileMode::Doc { deps: false },
        release: false,
        message_format: ops::MessageFormat::Human,
        filter: ops::CompileFilter::new(true, &[], &[], &[], &[]),
        target_rustc_args: metadata.rustc_args.as_ref().map(Vec::as_slice),
        target_rustdoc_args: metadata.rustdoc_args.as_ref().map(Vec::as_slice),
    };

    let ws = try!(Workspace::ephemeral(pkg, &config, Some(Filesystem::new(target_dir))));
    try!(ops::compile_ws(&ws, Some(source), &opts, Arc::new(DefaultExecutor)));

    Ok(try!(ws.current()).clone())
}

/// Downloads a crate and returns Cargo Package.
pub fn get_package(name: &str, vers: Option<&str>) -> CargoResult<Package> {
    debug!("Getting package with cargo");
    let config = try!(Config::default());
    let source_id = try!(SourceId::crates_io(&config));

    let source_map = try!(SourceConfigMap::new(&config));
    let mut source = try!(source_map.load(&source_id));

    let dep = try!(Dependency::parse_no_deprecated(name, vers, &source_id));
    let deps = try!(source.query(&dep));
    let pkg = try!(deps.iter().map(|p| p.package_id()).max()
                   // FIXME: This is probably not a rusty way to handle options and results
                   //        or maybe it is who knows...
                   .map(|pkgid| source.download(pkgid))
                   .unwrap_or(Err(human("PKG download error"))));

    Ok(pkg)
}

/// Updates central crates-io.index repository
pub fn update_sources() -> CargoResult<()> {
    let config = try!(Config::default());
    let source_id = try!(SourceId::crates_io(&config));

    let source_map = try!(SourceConfigMap::new(&config));
    let mut source = try!(source_map.load(&source_id));

    source.update()
}

/// Gets source path of a downloaded package.
pub fn source_path(pkg: &Package) -> Option<&Path> {
    // parent of the manifest file is where source codes are stored
    pkg.manifest_path().parent()
}

#[cfg(test)]
mod test {
    use std::path::Path;
    use std::fs::remove_dir_all;
    use super::*;

    #[test]
    fn test_build_doc() {
        let doc = build_doc("rand", None, None);
        assert!(doc.is_ok());

        let doc = doc.unwrap();
        remove_dir_all(format!("{}-{}", doc.manifest().name(), doc.manifest().version())).unwrap();

        let doc = build_doc("SOMECRATEWICHWILLBENVEREXISTS", None, None);
        assert!(doc.is_err());
    }

    #[test]
    fn test_get_package() {
        let pkg = get_package("rand", None);
        assert!(pkg.is_ok());

        let pkg = pkg.unwrap();

        let manifest = pkg.manifest();
        assert_eq!(manifest.name(), "rand");
    }

    #[test]
    fn test_source_path() {
        let pkg = get_package("rand", None).unwrap();
        let source_path = source_path(&pkg).unwrap();
        assert!(source_path.is_dir());

        let cargo_toml_path = Path::new(source_path).join("Cargo.toml");
        assert!(cargo_toml_path.exists());
        assert!(cargo_toml_path.is_file());

        let src_path = Path::new(source_path).join("src");
        assert!(src_path.exists());
        assert!(src_path.is_dir());
    }
}
<commit_msg>Ignore rustc_args<commit_after>//! Crate documentation builder
//!
//! This module is extremely similar to cargo install operation, except it's building
//! documentation of a crate and not installing anything.

use std::path::{Path, PathBuf};
use std::env;
use std::sync::Arc;

use cargo::core::{SourceId, Dependency, Registry, Source, Package, Workspace};
use cargo::util::{CargoResult, Config, human, Filesystem};
use cargo::sources::SourceConfigMap;
use cargo::ops::{self, Packages, DefaultExecutor};

use Metadata;

/// Builds documentation of a crate and version.
///
/// Crate will be built into current working directory/crate-version.
///
/// It will build latest version, if no version is given.
// idea is to make cargo to download
// and build a crate and its documentation
// instead of doing it manually like in the previous version of cratesfyi
pub fn build_doc(name: &str, vers: Option<&str>, target: Option<&str>) -> CargoResult<Package> {
    let config = try!(Config::default());
    let source_id = try!(SourceId::crates_io(&config));

    let source_map = try!(SourceConfigMap::new(&config));
    let mut source = try!(source_map.load(&source_id));

    // update crates.io-index registry
    try!(source.update());

    let dep = try!(Dependency::parse_no_deprecated(name, vers, &source_id));
    let deps = try!(source.query(&dep));
    let pkg = try!(deps.iter().map(|p| p.package_id()).max()
                   // FIXME: This is probably not a rusty way to handle options and results
                   //        or maybe it is who knows...
                   .map(|pkgid| source.download(pkgid))
                   .unwrap_or(Err(human("PKG download error"))));

    let current_dir = try!(env::current_dir());
    let target_dir = PathBuf::from(current_dir)
        .join(format!("{}-{}", pkg.manifest().name(), pkg.manifest().version()));

    let metadata = Metadata::from_package(&pkg);

    let opts = ops::CompileOptions {
        config: &config,
        jobs: None,
        target: target,
        features: &metadata.features.unwrap_or(Vec::new()),
        all_features: metadata.all_features,
        no_default_features: metadata.no_default_features,
        spec: Packages::Packages(&[]),
        mode: ops::CompileMode::Doc { deps: false },
        release: false,
        message_format: ops::MessageFormat::Human,
        filter: ops::CompileFilter::new(true, &[], &[], &[], &[]),
        // FIXME: cargo is ignoring target_rustdoc_args if rustc_args set.
        //        I believe this is expected behavior when building docs but I am not sure.
        //        This needs to be investigated.
        target_rustc_args: None,
        target_rustdoc_args: metadata.rustdoc_args.as_ref().map(Vec::as_slice),
    };

    let ws = try!(Workspace::ephemeral(pkg, &config, Some(Filesystem::new(target_dir))));
    try!(ops::compile_ws(&ws, Some(source), &opts, Arc::new(DefaultExecutor)));

    Ok(try!(ws.current()).clone())
}

/// Downloads a crate and returns Cargo Package.
pub fn get_package(name: &str, vers: Option<&str>) -> CargoResult<Package> {
    debug!("Getting package with cargo");
    let config = try!(Config::default());
    let source_id = try!(SourceId::crates_io(&config));

    let source_map = try!(SourceConfigMap::new(&config));
    let mut source = try!(source_map.load(&source_id));

    let dep = try!(Dependency::parse_no_deprecated(name, vers, &source_id));
    let deps = try!(source.query(&dep));
    let pkg = try!(deps.iter().map(|p| p.package_id()).max()
                   // FIXME: This is probably not a rusty way to handle options and results
                   //        or maybe it is who knows...
                   .map(|pkgid| source.download(pkgid))
                   .unwrap_or(Err(human("PKG download error"))));

    Ok(pkg)
}

/// Updates central crates-io.index repository
pub fn update_sources() -> CargoResult<()> {
    let config = try!(Config::default());
    let source_id = try!(SourceId::crates_io(&config));

    let source_map = try!(SourceConfigMap::new(&config));
    let mut source = try!(source_map.load(&source_id));

    source.update()
}

/// Gets source path of a downloaded package.
pub fn source_path(pkg: &Package) -> Option<&Path> {
    // parent of the manifest file is where source codes are stored
    pkg.manifest_path().parent()
}

#[cfg(test)]
mod test {
    use std::path::Path;
    use std::fs::remove_dir_all;
    use super::*;

    #[test]
    fn test_build_doc() {
        let doc = build_doc("rand", None, None);
        assert!(doc.is_ok());

        let doc = doc.unwrap();
        remove_dir_all(format!("{}-{}", doc.manifest().name(), doc.manifest().version())).unwrap();

        let doc = build_doc("SOMECRATEWICHWILLBENVEREXISTS", None, None);
        assert!(doc.is_err());
    }

    #[test]
    fn test_get_package() {
        let pkg = get_package("rand", None);
        assert!(pkg.is_ok());

        let pkg = pkg.unwrap();

        let manifest = pkg.manifest();
        assert_eq!(manifest.name(), "rand");
    }

    #[test]
    fn test_source_path() {
        let pkg = get_package("rand", None).unwrap();
        let source_path = source_path(&pkg).unwrap();
        assert!(source_path.is_dir());

        let cargo_toml_path = Path::new(source_path).join("Cargo.toml");
        assert!(cargo_toml_path.exists());
        assert!(cargo_toml_path.is_file());

        let src_path = Path::new(source_path).join("src");
        assert!(src_path.exists());
        assert!(src_path.is_dir());
    }
}
<|endoftext|>


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

//! A task that sniffs data
use std::comm::{channel, Receiver, Sender, Disconnected};
use std::task::TaskBuilder;
use resource_task::{TargetedLoadResponse};

pub type SnifferTask = Sender<TargetedLoadResponse>;

pub fn new_sniffer_task() -> SnifferTask {
    let(sen, rec) = channel();
    let builder = TaskBuilder::new().named("SnifferManager");
    builder.spawn(proc() {
        SnifferManager::new(rec).start();
    });
    sen
}

struct SnifferManager {
    data_receiver: Receiver<TargetedLoadResponse>,
}

impl SnifferManager {
    fn new(data_receiver: Receiver <TargetedLoadResponse>) -> SnifferManager {
        SnifferManager {
            data_receiver: data_receiver,
        }
    }
}

impl SnifferManager {
    fn start(self) {
        loop {
            match self.data_receiver.try_recv() {
                Ok(snif_data) => {
                    let result = snif_data.consumer.send_opt(snif_data.load_response);
                    if result.is_err() {
                        break;
                    }
                }
                Err(Disconnected) => break,
                Err(_) => (),
            }
        }
    }
}
<commit_msg>Don't abort the sniffer task whenever an error occurs. Also, switch to blocking recv_opt vs. non-blocking try_recv.<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

//! A task that sniffs data
use std::comm::{channel, Receiver, Sender};
use std::task::TaskBuilder;
use resource_task::{TargetedLoadResponse};

pub type SnifferTask = Sender<TargetedLoadResponse>;

pub fn new_sniffer_task() -> SnifferTask {
    let(sen, rec) = channel();
    let builder = TaskBuilder::new().named("SnifferManager");
    builder.spawn(proc() {
        SnifferManager::new(rec).start();
    });
    sen
}

struct SnifferManager {
    data_receiver: Receiver<TargetedLoadResponse>,
}

impl SnifferManager {
    fn new(data_receiver: Receiver <TargetedLoadResponse>) -> SnifferManager {
        SnifferManager {
            data_receiver: data_receiver,
        }
    }
}

impl SnifferManager {
    fn start(self) {
        loop {
            match self.data_receiver.recv_opt() {
                Ok(snif_data) => {
                    let _ = snif_data.consumer.send_opt(snif_data.load_response);
                }
                Err(_) => break,
            }
        }
    }
}
<|endoftext|>