<commit_before>#![allow(
    clippy::decimal_literal_representation,
    clippy::unreadable_literal,
    clippy::shadow_unrelated
)]

use indoc::indoc;
use serde_derive::{Deserialize, Serialize};
use serde_yaml::Value;
use std::collections::BTreeMap;
use std::f64;
use std::fmt::Debug;

fn test_serde<T>(thing: &T, yaml: &str)
where
    T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug,
{
    let serialized = serde_yaml::to_string(&thing).unwrap();
    assert_eq!(yaml, serialized);

    let value = serde_yaml::to_value(&thing).unwrap();
    let serialized = serde_yaml::to_string(&value).unwrap();
    assert_eq!(yaml, serialized);

    let deserialized: T = serde_yaml::from_str(yaml).unwrap();
    assert_eq!(*thing, deserialized);

    let value: Value = serde_yaml::from_str(yaml).unwrap();
    let deserialized: T = serde_yaml::from_value(value).unwrap();
    assert_eq!(*thing, deserialized);

    serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
}

#[test]
fn test_default() {
    assert_eq!(Value::default(), Value::Null);
}

#[test]
fn test_int() {
    let thing = 256;
    let yaml = indoc! {"
        ---
        256
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_int_max_u64() {
    let thing = ::std::u64::MAX;
    let yaml = indoc! {"
        ---
        18446744073709551615
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_int_min_i64() {
    let thing = ::std::i64::MIN;
    let yaml = indoc! {"
        ---
        -9223372036854775808
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_int_max_i64() {
    let thing = ::std::i64::MAX;
    let yaml = indoc! {"
        ---
        9223372036854775807
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_i128_small() {
    let thing: i128 = -256;
    let yaml = indoc! {"
        ---
        -256
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_u128_small() {
    let thing: u128 = 256;
    let yaml = indoc! {"
        ---
        256
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_float() {
    let thing = 25.6;
    let yaml = indoc! {"
        ---
        25.6
    "};
    test_serde(&thing, yaml);

    let thing = 25.;
    let yaml = indoc! {"
        ---
        25.0
    "};
    test_serde(&thing, yaml);

    let thing = f64::INFINITY;
    let yaml = indoc! {"
        ---
        .inf
    "};
    test_serde(&thing, yaml);

    let thing = f64::NEG_INFINITY;
    let yaml = indoc! {"
        ---
        -.inf
    "};
    test_serde(&thing, yaml);

    let float: f64 = serde_yaml::from_str(indoc! {"
        ---
        .nan
    "})
    .unwrap();
    assert!(float.is_nan());
}

#[test]
fn test_float32() {
    let thing: f32 = 25.6;
    let yaml = indoc! {"
        ---
        25.6
    "};
    test_serde(&thing, yaml);

    let thing = f32::INFINITY;
    let yaml = indoc! {"
        ---
        .inf
    "};
    test_serde(&thing, yaml);

    let thing = f32::NEG_INFINITY;
    let yaml = indoc! {"
        ---
        -.inf
    "};
    test_serde(&thing, yaml);

    let single_float: f32 = serde_yaml::from_str(indoc! {"
        ---
        .nan
    "})
    .unwrap();
    assert!(single_float.is_nan());

}

#[test]
fn test_vec() {
    let thing = vec![1, 2, 3];
    let yaml = indoc! {"
        ---
        - 1
        - 2
        - 3
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_map() {
    let mut thing = BTreeMap::new();
    thing.insert(String::from("x"), 1);
    thing.insert(String::from("y"), 2);
    let yaml = indoc! {"
        ---
        x: 1
        y: 2
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_basic_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Basic {
        x: isize,
        y: String,
        z: bool,
    }
    let thing = Basic {
        x: -4,
        y: String::from("hi\tquoted"),
        z: true,
    };
    let yaml = indoc! {r#"
        ---
        x: -4
        y: "hi\tquoted"
        z: true
    "#};
    test_serde(&thing, yaml);
}

#[test]
fn test_nested_vec() {
    let thing = vec![vec![1, 2, 3], vec![4, 5, 6]];
    let yaml = indoc! {"
        ---
        - - 1
          - 2
          - 3
        - - 4
          - 5
          - 6
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_nested_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Outer {
        inner: Inner,
    }
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Inner {
        v: u16,
    }
    let thing = Outer {
        inner: Inner { v: 512 },
    };
    let yaml = indoc! {"
        ---
        inner:
          v: 512
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_option() {
    let thing = vec![Some(1), None, Some(3)];
    let yaml = indoc! {"
        ---
        - 1
        - ~
        - 3
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_unit() {
    let thing = vec![(), ()];
    let yaml = indoc! {"
        ---
        - ~
        - ~
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_unit_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        First,
        Second,
    }
    let thing = Variant::First;
    let yaml = indoc! {"
        ---
        First
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_newtype_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct OriginalType {
        v: u16,
    }
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct NewType(OriginalType);
    let thing = NewType(OriginalType { v: 1 });
    let yaml = indoc! {"
        ---
        v: 1
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_newtype_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Size(usize),
    }
    let thing = Variant::Size(127);
    let yaml = indoc! {"
        ---
        Size: 127
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_tuple_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Rgb(u8, u8, u8),
    }
    let thing = Variant::Rgb(32, 64, 96);
    let yaml = indoc! {"
        ---
        Rgb:
          - 32
          - 64
          - 96
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_struct_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Color { r: u8, g: u8, b: u8 },
    }
    let thing = Variant::Color {
        r: 32,
        g: 64,
        b: 96,
    };
    let yaml = indoc! {"
        ---
        Color:
          r: 32
          g: 64
          b: 96
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_value() {
    use serde_yaml::{Mapping, Number};

    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    pub struct GenericInstructions {
        #[serde(rename = "type")]
        pub typ: String,
        pub config: Value,
    }
    let thing = GenericInstructions {
        typ: "primary".to_string(),
        config: Value::Sequence(vec![
            Value::Null,
            Value::Bool(true),
            Value::Number(Number::from(65535)),
            Value::Number(Number::from(0.54321)),
            Value::String("s".into()),
            Value::Mapping(Mapping::new()),
        ]),
    };
    let yaml = indoc! {"
        ---
        type: primary
        config:
          - ~
          - true
          - 65535
          - 0.54321
          - s
          - {}
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_mapping() {
    use serde_yaml::Mapping;
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Data {
        pub substructure: Mapping,
    }

    let mut thing = Data {
        substructure: Mapping::new(),
    };
    thing.substructure.insert(
        Value::String("a".to_owned()),
        Value::String("foo".to_owned()),
    );
    thing.substructure.insert(
        Value::String("b".to_owned()),
        Value::String("bar".to_owned()),
    );

    let yaml = indoc! {"
        ---
        substructure:
          a: foo
          b: bar
    "};

    test_serde(&thing, yaml);
}
<commit_msg>Add test for unit_struct<commit_after>#![allow(
    clippy::decimal_literal_representation,
    clippy::unreadable_literal,
    clippy::shadow_unrelated
)]

use indoc::indoc;
use serde_derive::{Deserialize, Serialize};
use serde_yaml::Value;
use std::collections::BTreeMap;
use std::f64;
use std::fmt::Debug;

fn test_serde<T>(thing: &T, yaml: &str)
where
    T: serde::Serialize + serde::de::DeserializeOwned + PartialEq + Debug,
{
    let serialized = serde_yaml::to_string(&thing).unwrap();
    assert_eq!(yaml, serialized);

    let value = serde_yaml::to_value(&thing).unwrap();
    let serialized = serde_yaml::to_string(&value).unwrap();
    assert_eq!(yaml, serialized);

    let deserialized: T = serde_yaml::from_str(yaml).unwrap();
    assert_eq!(*thing, deserialized);

    let value: Value = serde_yaml::from_str(yaml).unwrap();
    let deserialized: T = serde_yaml::from_value(value).unwrap();
    assert_eq!(*thing, deserialized);

    serde_yaml::from_str::<serde::de::IgnoredAny>(yaml).unwrap();
}

#[test]
fn test_default() {
    assert_eq!(Value::default(), Value::Null);
}

#[test]
fn test_int() {
    let thing = 256;
    let yaml = indoc! {"
        ---
        256
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_int_max_u64() {
    let thing = ::std::u64::MAX;
    let yaml = indoc! {"
        ---
        18446744073709551615
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_int_min_i64() {
    let thing = ::std::i64::MIN;
    let yaml = indoc! {"
        ---
        -9223372036854775808
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_int_max_i64() {
    let thing = ::std::i64::MAX;
    let yaml = indoc! {"
        ---
        9223372036854775807
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_i128_small() {
    let thing: i128 = -256;
    let yaml = indoc! {"
        ---
        -256
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_u128_small() {
    let thing: u128 = 256;
    let yaml = indoc! {"
        ---
        256
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_float() {
    let thing = 25.6;
    let yaml = indoc! {"
        ---
        25.6
    "};
    test_serde(&thing, yaml);

    let thing = 25.;
    let yaml = indoc! {"
        ---
        25.0
    "};
    test_serde(&thing, yaml);

    let thing = f64::INFINITY;
    let yaml = indoc! {"
        ---
        .inf
    "};
    test_serde(&thing, yaml);

    let thing = f64::NEG_INFINITY;
    let yaml = indoc! {"
        ---
        -.inf
    "};
    test_serde(&thing, yaml);

    let float: f64 = serde_yaml::from_str(indoc! {"
        ---
        .nan
    "})
    .unwrap();
    assert!(float.is_nan());
}

#[test]
fn test_float32() {
    let thing: f32 = 25.6;
    let yaml = indoc! {"
        ---
        25.6
    "};
    test_serde(&thing, yaml);

    let thing = f32::INFINITY;
    let yaml = indoc! {"
        ---
        .inf
    "};
    test_serde(&thing, yaml);

    let thing = f32::NEG_INFINITY;
    let yaml = indoc! {"
        ---
        -.inf
    "};
    test_serde(&thing, yaml);

    let single_float: f32 = serde_yaml::from_str(indoc! {"
        ---
        .nan
    "})
    .unwrap();
    assert!(single_float.is_nan());
}

#[test]
fn test_vec() {
    let thing = vec![1, 2, 3];
    let yaml = indoc! {"
        ---
        - 1
        - 2
        - 3
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_map() {
    let mut thing = BTreeMap::new();
    thing.insert(String::from("x"), 1);
    thing.insert(String::from("y"), 2);
    let yaml = indoc! {"
        ---
        x: 1
        y: 2
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_basic_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Basic {
        x: isize,
        y: String,
        z: bool,
    }
    let thing = Basic {
        x: -4,
        y: String::from("hi\tquoted"),
        z: true,
    };
    let yaml = indoc! {r#"
        ---
        x: -4
        y: "hi\tquoted"
        z: true
    "#};
    test_serde(&thing, yaml);
}

#[test]
fn test_nested_vec() {
    let thing = vec![vec![1, 2, 3], vec![4, 5, 6]];
    let yaml = indoc! {"
        ---
        - - 1
          - 2
          - 3
        - - 4
          - 5
          - 6
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_nested_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Outer {
        inner: Inner,
    }
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Inner {
        v: u16,
    }
    let thing = Outer {
        inner: Inner { v: 512 },
    };
    let yaml = indoc! {"
        ---
        inner:
          v: 512
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_option() {
    let thing = vec![Some(1), None, Some(3)];
    let yaml = indoc! {"
        ---
        - 1
        - ~
        - 3
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_unit() {
    let thing = vec![(), ()];
    let yaml = indoc! {"
        ---
        - ~
        - ~
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_unit_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Foo;
    let thing = Foo;
    let yaml = indoc! {"
        ---
        ~
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_unit_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        First,
        Second,
    }
    let thing = Variant::First;
    let yaml = indoc! {"
        ---
        First
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_newtype_struct() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct OriginalType {
        v: u16,
    }
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct NewType(OriginalType);
    let thing = NewType(OriginalType { v: 1 });
    let yaml = indoc! {"
        ---
        v: 1
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_newtype_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Size(usize),
    }
    let thing = Variant::Size(127);
    let yaml = indoc! {"
        ---
        Size: 127
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_tuple_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Rgb(u8, u8, u8),
    }
    let thing = Variant::Rgb(32, 64, 96);
    let yaml = indoc! {"
        ---
        Rgb:
          - 32
          - 64
          - 96
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_struct_variant() {
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    enum Variant {
        Color { r: u8, g: u8, b: u8 },
    }
    let thing = Variant::Color {
        r: 32,
        g: 64,
        b: 96,
    };
    let yaml = indoc! {"
        ---
        Color:
          r: 32
          g: 64
          b: 96
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_value() {
    use serde_yaml::{Mapping, Number};

    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    pub struct GenericInstructions {
        #[serde(rename = "type")]
        pub typ: String,
        pub config: Value,
    }
    let thing = GenericInstructions {
        typ: "primary".to_string(),
        config: Value::Sequence(vec![
            Value::Null,
            Value::Bool(true),
            Value::Number(Number::from(65535)),
            Value::Number(Number::from(0.54321)),
            Value::String("s".into()),
            Value::Mapping(Mapping::new()),
        ]),
    };
    let yaml = indoc! {"
        ---
        type: primary
        config:
          - ~
          - true
          - 65535
          - 0.54321
          - s
          - {}
    "};
    test_serde(&thing, yaml);
}

#[test]
fn test_mapping() {
    use serde_yaml::Mapping;
    #[derive(Serialize, Deserialize, PartialEq, Debug)]
    struct Data {
        pub substructure: Mapping,
    }

    let mut thing = Data {
        substructure: Mapping::new(),
    };
    thing.substructure.insert(
        Value::String("a".to_owned()),
        Value::String("foo".to_owned()),
    );
    thing.substructure.insert(
        Value::String("b".to_owned()),
        Value::String("bar".to_owned()),
    );

    let yaml = indoc! {"
        ---
        substructure:
          a: foo
          b: bar
    "};

    test_serde(&thing, yaml);
}
<|endoftext|>


<commit_before>use std::io::{BufferedWriter, IoResult, TcpStream};
use data::Message;

pub struct Connection(pub TcpStream);

pub fn connect(host: &str, port: u16) -> IoResult<Connection> {
    let socket = try!(TcpStream::connect(host, port));
    Ok(Connection(socket))
}

fn send_internal(conn: &Connection, msg: &str) -> IoResult<()> {
    let &Connection(ref tcp) = conn;
    let mut writer = BufferedWriter::new(tcp.clone());
    writer.write_str(msg)
}

pub fn send(conn: &Connection, msg: Message) -> IoResult<()> {
    let arg_string = msg.args.init().connect(" ").append(" :").append(*msg.args.last().unwrap());
    send_internal(conn, msg.command.to_string().append(" ").append(arg_string.as_slice()).append("\r\n").as_slice())
}
<commit_msg>Removed usage of deprecated append(...) method.<commit_after>use std::io::{BufferedWriter, IoResult, TcpStream};
use data::Message;

pub struct Connection(pub TcpStream);

pub fn connect(host: &str, port: u16) -> IoResult<Connection> {
    let socket = try!(TcpStream::connect(host, port));
    Ok(Connection(socket))
}

fn send_internal(conn: &Connection, msg: &str) -> IoResult<()> {
    let &Connection(ref tcp) = conn;
    let mut writer = BufferedWriter::new(tcp.clone());
    writer.write_str(msg)
}

pub fn send(conn: &Connection, msg: Message) -> IoResult<()> {
    let mut send = msg.command.to_string();
    send.push_str(" ");
    send.push_str(msg.args.init().connect(" ").as_slice());
    send.push_str(" :");
    send.push_str(*msg.args.last().unwrap());
    send.push_str("\r\n");
    send_internal(conn, send.as_slice())
}
<|endoftext|>


<commit_before>/// Creator of the earth.

use common::communicate::{ServerToClient, TerrainBlockSend};
use common::lod::{LODIndex, OwnerId};
use common::process_events::process_receiver;
use common::stopwatch::TimerSet;
use common::block_position::BlockPosition;
use common::terrain_block::{BLOCK_WIDTH, TEXTURE_WIDTH};
use opencl_context::CL;
use server::Server;
use std::old_io::timer;
use std::ops::DerefMut;
use std::sync::mpsc::Receiver;
use std::time::duration::Duration;
use terrain::terrain_game_loader::TerrainGameLoader;
use terrain::texture_generator::TerrainTextureGenerator;

#[derive(Debug, Clone)]
pub enum LoadReason {
  Local(OwnerId),
  ForClient,
}

#[derive(Debug, Clone)]
pub enum ServerToGaia {
  Load(BlockPosition, LODIndex, LoadReason),
  Quit,
}

// TODO: Consider adding terrain loads to a thread pool instead of having one monolithic separate thread.
pub fn gaia_thread(
  ups_from_server: &Receiver<ServerToGaia>,
  server: &Server,
) {
  let timers = TimerSet::new();
  let timers = &timers;

  let cl = unsafe {
    CL::new()
  };
  let cl = &cl;

  let texture_generators = [
    TerrainTextureGenerator::new(&cl, TEXTURE_WIDTH[0], BLOCK_WIDTH as u32),
    TerrainTextureGenerator::new(&cl, TEXTURE_WIDTH[1], BLOCK_WIDTH as u32),
    TerrainTextureGenerator::new(&cl, TEXTURE_WIDTH[2], BLOCK_WIDTH as u32),
    TerrainTextureGenerator::new(&cl, TEXTURE_WIDTH[3], BLOCK_WIDTH as u32),
  ];

  loop {
    let quit =
      !process_receiver(
        ups_from_server,
        |update| {
          match update {
            ServerToGaia::Quit => {
              return false;
            },
            ServerToGaia::Load(position, lod, load_reason) => {
              timers.time("terrain.load", || {
                // TODO: Just lock `terrain` for the check and then the move,
                // not while we're generating the block.
                let mut terrain_game_loader = server.terrain_game_loader.lock().unwrap();
                let terrain_game_loader = terrain_game_loader.deref_mut();
                let lod_map = &mut terrain_game_loader.lod_map;
                let in_progress_terrain = &mut terrain_game_loader.in_progress_terrain;
                terrain_game_loader.terrain.load(
                  timers,
                  cl,
                  &texture_generators[lod.0 as usize],
                  &server.id_allocator,
                  &position,
                  lod,
                  |block| {
                    match load_reason {
                      LoadReason::Local(owner) => {
                        // TODO: Check that this block isn't stale; i.e. should still be loaded.
                        TerrainGameLoader::insert_block(
                          timers,
                          block,
                          &position,
                          lod,
                          owner,
                          &server.physics,
                          lod_map,
                          in_progress_terrain,
                        );
                      },
                      LoadReason::ForClient => {
                        server.to_client.lock().unwrap().as_mut().unwrap().send(
                          ServerToClient::AddBlock(TerrainBlockSend {
                            position: position,
                            block: block.clone(),
                            lod: lod,
                          })
                        );
                      },
                    }
                  },
                );
              });
            },
          };

          true
        }
      );
    if quit {
      break;
    }

    timer::sleep(Duration::milliseconds(1));
  }

  timers.print();
}
<commit_msg>Remove unused file.<commit_after><|endoftext|>


<commit_before>
#[macro_export]
macro_rules! router {
    ($($method:ident $path:expr => |$req:ident, $res:ident| $b:block)+) => (
        {
            use nickel::HttpRouter;
            let mut router = nickel::Router::new();

            $( router.$method($path, middleware!(|$req, $res| $b)); )+

            router
        }
    )
}

#[macro_export]
macro_rules! middleware {
    (@$f:ident) => {
        $f as for<'a> fn(&mut Request, Response<'a>) -> MiddlewareResult<'a>
    };
    (|$req:ident, $res:ident| $($b:tt)+) => {{
        use nickel::{MiddlewareResult,ResponseFinalizer, Response, Request};

        #[inline(always)]
        fn restrict<'a, R: ResponseFinalizer>(r: R, res: Response<'a>)
                -> MiddlewareResult<'a> {
            r.respond(res)
        }

        #[allow(unused_variables)]
        fn f<'a>($req: &mut Request, $res: Response<'a>)
                -> MiddlewareResult<'a> {
            restrict(as_block!({$($b)+}), $res)
        }

        // issue #20178
        f as for<'a> fn(&mut Request, Response<'a>) -> MiddlewareResult<'a>
    }};
    (|$req:ident| $($b:tt)+) => { middleware!(|$req, res| $($b)+) };
    ($($b:tt)+) => { middleware!(|req, res| $($b)+) };
}

#[macro_export] macro_rules! as_block { ($b:block) => ( $b ) }
<commit_msg>fix(rustup): remove warnings from trivial_casts for fn pointers<commit_after>
#[macro_export]
macro_rules! router {
    ($($method:ident $path:expr => |$req:ident, $res:ident| $b:block)+) => (
        {
            use nickel::HttpRouter;
            let mut router = nickel::Router::new();

            $( router.$method($path, middleware!(|$req, $res| $b)); )+

            router
        }
    )
}

#[macro_export]
macro_rules! middleware {
    (@$f:ident) => {{
        // issue #20178 with a lame interaction from #23630. *grumble*
        let f : for<'a> fn(&mut Request, Response<'a>) -> MiddlewareResult<'a> = $f;
        f
    }};
    (|$req:ident, $res:ident| $($b:tt)+) => {{
        use nickel::{MiddlewareResult,ResponseFinalizer, Response, Request};

        #[inline(always)]
        fn restrict<'a, R: ResponseFinalizer>(r: R, res: Response<'a>)
                -> MiddlewareResult<'a> {
            r.respond(res)
        }

        #[allow(unused_variables)]
        fn f<'a>($req: &mut Request, $res: Response<'a>)
                -> MiddlewareResult<'a> {
            restrict(as_block!({$($b)+}), $res)
        }

        middleware!(@f)
    }};
    (|$req:ident| $($b:tt)+) => { middleware!(|$req, res| $($b)+) };
    ($($b:tt)+) => { middleware!(|req, res| $($b)+) };
}

#[macro_export] macro_rules! as_block { ($b:block) => ( $b ) }
<|endoftext|>


<commit_before>extern crate trust_dns;
extern crate trust_dns_proto;
extern crate trust_dns_server;

use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;

use trust_dns::rr::*;
use trust_dns::rr::dnssec::*;
use trust_dns::serialize::txt::*;
use trust_dns_proto::rr::rdata::tlsa::*;
use trust_dns_server::authority::*;

#[test]
fn test_string() {
    let lexer = Lexer::new(
        "@   IN  SOA     venera      action\\.domains (
                               \
                            20     ; SERIAL
                               7200   ; REFRESH
                               \
                            600    ; RETRY
                               3600000; EXPIRE
                               \
                            60)    ; MINIMUM

      NS      a.isi.edu.
      NS      venera
      \
                            NS      vaxa
      MX      10      venera
      MX      20      vaxa

\
                            a       A       26.3.0.103
        TXT     I am a txt record
        \
                            TXT     I am another txt record
        TXT     \"I am a different\" \
                            \"txt record\"
        TXT     key=val
aaaa    AAAA    \
                            4321:0:1:2:3:4:567:89ab
alias   CNAME   a
103.0.3.26.IN-ADDR.ARPA.   \
                            PTR a
b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.\
                            4.IP6.ARPA. PTR aaaa

_ldap._tcp.service SRV 1 2 3 short

short 70 A      \
                            26.3.0.104
venera  A       10.1.0.52
      A       128.9.0.32

nocerts       CAA 0 issue \";\"
certs         CAA 0 issuewild \"example.net\"

_443._tcp.www.example.com. IN TLSA (
      0 0 1 d2abde240d7cd3ee6b4b28c54df034b9
            7983a1d16e8a410e4561cb106618e971 )
",
    );

    let records = Parser::new().parse(lexer, Some(Name::from_labels(vec!["isi", "edu"])));
    if records.is_err() {
        panic!("failed to parse: {:?}", records.err())
    }

    let (origin, records) = records.unwrap();
    let authority = Authority::new(origin, records, ZoneType::Master, false, false);

    // not validating everything, just one of each...

    // SOA
    let soa_record = authority.soa().unwrap().first().cloned().unwrap();
    assert_eq!(RecordType::SOA, soa_record.rr_type());
    assert_eq!(&Name::from_labels(vec!["isi", "edu"]), soa_record.name()); // i.e. the origin or domain
    assert_eq!(3600000, soa_record.ttl());
    assert_eq!(DNSClass::IN, soa_record.dns_class());
    if let RData::SOA(ref soa) = *soa_record.rdata() {
        // this should all be lowercased
        assert_eq!(
            &Name::from_labels(vec!["venera", "isi", "edu"]),
            soa.mname()
        );
        assert_eq!(
            &Name::from_labels(vec!["action.domains", "isi", "edu"]),
            soa.rname()
        );
        assert_eq!(20, soa.serial());
        assert_eq!(7200, soa.refresh());
        assert_eq!(600, soa.retry());
        assert_eq!(3600000, soa.expire());
        assert_eq!(60, soa.minimum());
    } else {
        panic!("Not an SOA record!!!") // valid panic, test code
    }

    // NS
    let mut ns_records: Vec<&Record> = authority
        .lookup(
            &Name::from_labels(vec!["isi", "edu"]),
            RecordType::NS,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap();
    let mut compare = vec![
        // this is cool, zip up the expected results... works as long as the order is good.
        Name::from_labels(vec!["a", "isi", "edu"]),
        Name::from_labels(vec!["venera", "isi", "edu"]),
        Name::from_labels(vec!["vaxa", "isi", "edu"]),
    ];

    compare.sort();
    ns_records.sort();
    let compare = ns_records.iter().zip(compare);

    for (record, ref name) in compare {
        assert_eq!(&Name::from_labels(vec!["isi", "edu"]), record.name());
        assert_eq!(60, record.ttl()); // TODO: should this be minimum or expire?
        assert_eq!(DNSClass::IN, record.dns_class());
        assert_eq!(RecordType::NS, record.rr_type());
        if let RData::NS(ref nsdname) = *record.rdata() {
            assert_eq!(name, nsdname);
        } else {
            panic!("Not an NS record!!!") // valid panic, test code
        }
    }

    // MX
    let mut mx_records: Vec<&Record> = authority
        .lookup(
            &Name::from_labels(vec!["isi", "edu"]),
            RecordType::MX,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap();
    let mut compare = vec![
        (10, Name::from_labels(vec!["venera", "isi", "edu"])),
        (20, Name::from_labels(vec!["vaxa", "isi", "edu"])),
    ];

    compare.sort();
    mx_records.sort();
    let compare = mx_records.iter().zip(compare);

    for (record, (num, ref name)) in compare {
        assert_eq!(&Name::from_labels(vec!["isi", "edu"]), record.name());
        assert_eq!(60, record.ttl()); // TODO: should this be minimum or expire?
        assert_eq!(DNSClass::IN, record.dns_class());
        assert_eq!(RecordType::MX, record.rr_type());
        if let RData::MX(ref rdata) = *record.rdata() {
            assert_eq!(num, rdata.preference());
            assert_eq!(name, rdata.exchange());
        } else {
            panic!("Not an NS record!!!") // valid panic, test code
        }
    }

    // A
    let a_record: &Record = authority
        .lookup(
            &Name::from_labels(vec!["a", "isi", "edu"]),
            RecordType::A,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .unwrap();
    assert_eq!(&Name::from_labels(vec!["a", "isi", "edu"]), a_record.name());
    assert_eq!(60, a_record.ttl()); // TODO: should this be minimum or expire?
    assert_eq!(DNSClass::IN, a_record.dns_class());
    assert_eq!(RecordType::A, a_record.rr_type());
    if let RData::A(ref address) = *a_record.rdata() {
        assert_eq!(&Ipv4Addr::new(26u8, 3u8, 0u8, 103u8), address);
    } else {
        panic!("Not an A record!!!") // valid panic, test code
    }

    // AAAA
    let aaaa_record: &Record = authority
        .lookup(
            &Name::from_labels(vec!["aaaa", "isi", "edu"]),
            RecordType::AAAA,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .unwrap();
    assert_eq!(
        &Name::from_labels(vec!["aaaa", "isi", "edu"]),
        aaaa_record.name()
    );
    if let RData::AAAA(ref address) = *aaaa_record.rdata() {
        assert_eq!(
            &Ipv6Addr::from_str("4321:0:1:2:3:4:567:89ab").unwrap(),
            address
        );
    } else {
        panic!("Not a AAAA record!!!") // valid panic, test code
    }

    // SHORT
    let short_record: &Record = authority
        .lookup(
            &Name::from_labels(vec!["short", "isi", "edu"]),
            RecordType::A,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .unwrap();
    assert_eq!(
        &Name::from_labels(vec!["short", "isi", "edu"]),
        short_record.name()
    );
    assert_eq!(70, short_record.ttl());
    if let RData::A(ref address) = *short_record.rdata() {
        assert_eq!(&Ipv4Addr::new(26u8, 3u8, 0u8, 104u8), address);
    } else {
        panic!("Not an A record!!!") // valid panic, test code
    }

    // TXT
    let mut txt_records: Vec<&Record> = authority
        .lookup(
            &Name::from_labels(vec!["a", "isi", "edu"]),
            RecordType::TXT,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap();
    let compare = vec![
        vec![
            "I".to_string(),
            "am".to_string(),
            "a".to_string(),
            "txt".to_string(),
            "record".to_string(),
        ],
        vec![
            "I".to_string(),
            "am".to_string(),
            "another".to_string(),
            "txt".to_string(),
            "record".to_string(),
        ],
        vec!["key=val".to_string()],
        vec!["I am a different".to_string(), "txt record".to_string()],
    ];

    txt_records.sort();

    println!("compare: {:#?}", compare);
    println!("txt_records: {:#?}", txt_records);

    let compare = txt_records.iter().zip(compare);

    for (record, ref vector) in compare {
        if let RData::TXT(ref rdata) = *record.rdata() {
            assert_eq!(vector as &[String], rdata.txt_data());
        } else {
            panic!("Not a TXT record!!!") // valid panic, test code
        }
    }

    // PTR
    let ptr_record: &Record = authority
        .lookup(
            &Name::from_labels(vec!["103", "0", "3", "26", "in-addr", "arpa"]),
            RecordType::PTR,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .unwrap();
    if let RData::PTR(ref ptrdname) = *ptr_record.rdata() {
        assert_eq!(&Name::from_labels(vec!["a", "isi", "edu"]), ptrdname);
    } else {
        panic!("Not a PTR record!!!") // valid panic, test code
    }

    // SRV
    let srv_record: &Record = authority
        .lookup(
            &Name::from_labels(vec!["_ldap", "_tcp", "service", "isi", "edu"]),
            RecordType::SRV,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .unwrap();
    if let RData::SRV(ref rdata) = *srv_record.rdata() {
        assert_eq!(rdata.priority(), 1);
        assert_eq!(rdata.weight(), 2);
        assert_eq!(rdata.port(), 3);
        assert_eq!(
            rdata.target(),
            &Name::from_labels(vec!["short", "isi", "edu"])
        );
    } else {
        panic!("Not an SRV record!!!") // valid panic, test code
    }

    // CAA
    let caa_record: &Record = authority
        .lookup(
            &Name::parse("nocerts.isi.edu.", None).unwrap(),
            RecordType::CAA,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .expect("nocerts not found");
    if let RData::CAA(ref rdata) = *caa_record.rdata() {
        assert!(!rdata.issuer_critical());
        assert!(rdata.tag().is_issue());
        assert!(rdata.value().is_issuer());
    } else {
        assert!(false);
    }

    // TLSA
    let tlsa_record: &Record = authority
        .lookup(
            &Name::parse("_443._tcp.www.example.com.", None).unwrap(),
            RecordType::TLSA,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .expect("tlsa record not found");

    if let RData::TLSA(ref rdata) = *tlsa_record.rdata() {
        assert_eq!(*rdata.cert_usage(), CertUsage::CA);
        assert_eq!(*rdata.selector(), Selector::Full);
        assert_eq!(*rdata.matching(), Matching::Sha256);
        assert_eq!(
            rdata.cert_data(),
            &[
                210,
                171,
                222,
                36,
                13,
                124,
                211,
                238,
                107,
                75,
                40,
                197,
                77,
                240,
                52,
                185,
                121,
                131,
                161,
                209,
                110,
                138,
                65,
                14,
                69,
                97,
                203,
                16,
                102,
                24,
                233,
                113
            ]
        );
    } else {
        assert!(false);
    }
}
<commit_msg>Add underscores for long literals<commit_after>extern crate trust_dns;
extern crate trust_dns_proto;
extern crate trust_dns_server;

use std::net::{Ipv4Addr, Ipv6Addr};
use std::str::FromStr;

use trust_dns::rr::*;
use trust_dns::rr::dnssec::*;
use trust_dns::serialize::txt::*;
use trust_dns_proto::rr::rdata::tlsa::*;
use trust_dns_server::authority::*;

#[test]
fn test_string() {
    let lexer = Lexer::new(
        "@   IN  SOA     venera      action\\.domains (
                               \
                            20     ; SERIAL
                               7200   ; REFRESH
                               \
                            600    ; RETRY
                               3600000; EXPIRE
                               \
                            60)    ; MINIMUM

      NS      a.isi.edu.
      NS      venera
      \
                            NS      vaxa
      MX      10      venera
      MX      20      vaxa

\
                            a       A       26.3.0.103
        TXT     I am a txt record
        \
                            TXT     I am another txt record
        TXT     \"I am a different\" \
                            \"txt record\"
        TXT     key=val
aaaa    AAAA    \
                            4321:0:1:2:3:4:567:89ab
alias   CNAME   a
103.0.3.26.IN-ADDR.ARPA.   \
                            PTR a
b.a.9.8.7.6.5.0.4.0.0.0.3.0.0.0.2.0.0.0.1.0.0.0.0.0.0.0.1.2.3.\
                            4.IP6.ARPA. PTR aaaa

_ldap._tcp.service SRV 1 2 3 short

short 70 A      \
                            26.3.0.104
venera  A       10.1.0.52
      A       128.9.0.32

nocerts       CAA 0 issue \";\"
certs         CAA 0 issuewild \"example.net\"

_443._tcp.www.example.com. IN TLSA (
      0 0 1 d2abde240d7cd3ee6b4b28c54df034b9
            7983a1d16e8a410e4561cb106618e971 )
",
    );

    let records = Parser::new().parse(lexer, Some(Name::from_labels(vec!["isi", "edu"])));
    if records.is_err() {
        panic!("failed to parse: {:?}", records.err())
    }

    let (origin, records) = records.unwrap();
    let authority = Authority::new(origin, records, ZoneType::Master, false, false);

    // not validating everything, just one of each...

    // SOA
    let soa_record = authority.soa().unwrap().first().cloned().unwrap();
    assert_eq!(RecordType::SOA, soa_record.rr_type());
    assert_eq!(&Name::from_labels(vec!["isi", "edu"]), soa_record.name()); // i.e. the origin or domain
    assert_eq!(3_600_000, soa_record.ttl());
    assert_eq!(DNSClass::IN, soa_record.dns_class());
    if let RData::SOA(ref soa) = *soa_record.rdata() {
        // this should all be lowercased
        assert_eq!(
            &Name::from_labels(vec!["venera", "isi", "edu"]),
            soa.mname()
        );
        assert_eq!(
            &Name::from_labels(vec!["action.domains", "isi", "edu"]),
            soa.rname()
        );
        assert_eq!(20, soa.serial());
        assert_eq!(7200, soa.refresh());
        assert_eq!(600, soa.retry());
        assert_eq!(3_600_000, soa.expire());
        assert_eq!(60, soa.minimum());
    } else {
        panic!("Not an SOA record!!!") // valid panic, test code
    }

    // NS
    let mut ns_records: Vec<&Record> = authority
        .lookup(
            &Name::from_labels(vec!["isi", "edu"]),
            RecordType::NS,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap();
    let mut compare = vec![
        // this is cool, zip up the expected results... works as long as the order is good.
        Name::from_labels(vec!["a", "isi", "edu"]),
        Name::from_labels(vec!["venera", "isi", "edu"]),
        Name::from_labels(vec!["vaxa", "isi", "edu"]),
    ];

    compare.sort();
    ns_records.sort();
    let compare = ns_records.iter().zip(compare);

    for (record, ref name) in compare {
        assert_eq!(&Name::from_labels(vec!["isi", "edu"]), record.name());
        assert_eq!(60, record.ttl()); // TODO: should this be minimum or expire?
        assert_eq!(DNSClass::IN, record.dns_class());
        assert_eq!(RecordType::NS, record.rr_type());
        if let RData::NS(ref nsdname) = *record.rdata() {
            assert_eq!(name, nsdname);
        } else {
            panic!("Not an NS record!!!") // valid panic, test code
        }
    }

    // MX
    let mut mx_records: Vec<&Record> = authority
        .lookup(
            &Name::from_labels(vec!["isi", "edu"]),
            RecordType::MX,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap();
    let mut compare = vec![
        (10, Name::from_labels(vec!["venera", "isi", "edu"])),
        (20, Name::from_labels(vec!["vaxa", "isi", "edu"])),
    ];

    compare.sort();
    mx_records.sort();
    let compare = mx_records.iter().zip(compare);

    for (record, (num, ref name)) in compare {
        assert_eq!(&Name::from_labels(vec!["isi", "edu"]), record.name());
        assert_eq!(60, record.ttl()); // TODO: should this be minimum or expire?
        assert_eq!(DNSClass::IN, record.dns_class());
        assert_eq!(RecordType::MX, record.rr_type());
        if let RData::MX(ref rdata) = *record.rdata() {
            assert_eq!(num, rdata.preference());
            assert_eq!(name, rdata.exchange());
        } else {
            panic!("Not an NS record!!!") // valid panic, test code
        }
    }

    // A
    let a_record: &Record = authority
        .lookup(
            &Name::from_labels(vec!["a", "isi", "edu"]),
            RecordType::A,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .unwrap();
    assert_eq!(&Name::from_labels(vec!["a", "isi", "edu"]), a_record.name());
    assert_eq!(60, a_record.ttl()); // TODO: should this be minimum or expire?
    assert_eq!(DNSClass::IN, a_record.dns_class());
    assert_eq!(RecordType::A, a_record.rr_type());
    if let RData::A(ref address) = *a_record.rdata() {
        assert_eq!(&Ipv4Addr::new(26u8, 3u8, 0u8, 103u8), address);
    } else {
        panic!("Not an A record!!!") // valid panic, test code
    }

    // AAAA
    let aaaa_record: &Record = authority
        .lookup(
            &Name::from_labels(vec!["aaaa", "isi", "edu"]),
            RecordType::AAAA,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .unwrap();
    assert_eq!(
        &Name::from_labels(vec!["aaaa", "isi", "edu"]),
        aaaa_record.name()
    );
    if let RData::AAAA(ref address) = *aaaa_record.rdata() {
        assert_eq!(
            &Ipv6Addr::from_str("4321:0:1:2:3:4:567:89ab").unwrap(),
            address
        );
    } else {
        panic!("Not a AAAA record!!!") // valid panic, test code
    }

    // SHORT
    let short_record: &Record = authority
        .lookup(
            &Name::from_labels(vec!["short", "isi", "edu"]),
            RecordType::A,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .unwrap();
    assert_eq!(
        &Name::from_labels(vec!["short", "isi", "edu"]),
        short_record.name()
    );
    assert_eq!(70, short_record.ttl());
    if let RData::A(ref address) = *short_record.rdata() {
        assert_eq!(&Ipv4Addr::new(26u8, 3u8, 0u8, 104u8), address);
    } else {
        panic!("Not an A record!!!") // valid panic, test code
    }

    // TXT
    let mut txt_records: Vec<&Record> = authority
        .lookup(
            &Name::from_labels(vec!["a", "isi", "edu"]),
            RecordType::TXT,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap();
    let compare = vec![
        vec![
            "I".to_string(),
            "am".to_string(),
            "a".to_string(),
            "txt".to_string(),
            "record".to_string(),
        ],
        vec![
            "I".to_string(),
            "am".to_string(),
            "another".to_string(),
            "txt".to_string(),
            "record".to_string(),
        ],
        vec!["key=val".to_string()],
        vec!["I am a different".to_string(), "txt record".to_string()],
    ];

    txt_records.sort();

    println!("compare: {:#?}", compare);
    println!("txt_records: {:#?}", txt_records);

    let compare = txt_records.iter().zip(compare);

    for (record, ref vector) in compare {
        if let RData::TXT(ref rdata) = *record.rdata() {
            assert_eq!(vector as &[String], rdata.txt_data());
        } else {
            panic!("Not a TXT record!!!") // valid panic, test code
        }
    }

    // PTR
    let ptr_record: &Record = authority
        .lookup(
            &Name::from_labels(vec!["103", "0", "3", "26", "in-addr", "arpa"]),
            RecordType::PTR,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .unwrap();
    if let RData::PTR(ref ptrdname) = *ptr_record.rdata() {
        assert_eq!(&Name::from_labels(vec!["a", "isi", "edu"]), ptrdname);
    } else {
        panic!("Not a PTR record!!!") // valid panic, test code
    }

    // SRV
    let srv_record: &Record = authority
        .lookup(
            &Name::from_labels(vec!["_ldap", "_tcp", "service", "isi", "edu"]),
            RecordType::SRV,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .unwrap();
    if let RData::SRV(ref rdata) = *srv_record.rdata() {
        assert_eq!(rdata.priority(), 1);
        assert_eq!(rdata.weight(), 2);
        assert_eq!(rdata.port(), 3);
        assert_eq!(
            rdata.target(),
            &Name::from_labels(vec!["short", "isi", "edu"])
        );
    } else {
        panic!("Not an SRV record!!!") // valid panic, test code
    }

    // CAA
    let caa_record: &Record = authority
        .lookup(
            &Name::parse("nocerts.isi.edu.", None).unwrap(),
            RecordType::CAA,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .expect("nocerts not found");
    if let RData::CAA(ref rdata) = *caa_record.rdata() {
        assert!(!rdata.issuer_critical());
        assert!(rdata.tag().is_issue());
        assert!(rdata.value().is_issuer());
    } else {
        assert!(false);
    }

    // TLSA
    let tlsa_record: &Record = authority
        .lookup(
            &Name::parse("_443._tcp.www.example.com.", None).unwrap(),
            RecordType::TLSA,
            false,
            SupportedAlgorithms::new(),
        )
        .unwrap()
        .first()
        .cloned()
        .expect("tlsa record not found");

    if let RData::TLSA(ref rdata) = *tlsa_record.rdata() {
        assert_eq!(*rdata.cert_usage(), CertUsage::CA);
        assert_eq!(*rdata.selector(), Selector::Full);
        assert_eq!(*rdata.matching(), Matching::Sha256);
        assert_eq!(
            rdata.cert_data(),
            &[
                210,
                171,
                222,
                36,
                13,
                124,
                211,
                238,
                107,
                75,
                40,
                197,
                77,
                240,
                52,
                185,
                121,
                131,
                161,
                209,
                110,
                138,
                65,
                14,
                69,
                97,
                203,
                16,
                102,
                24,
                233,
                113
            ]
        );
    } else {
        assert!(false);
    }
}
<|endoftext|>


<commit_before>/*!
This module contains the underlying data generation and shrinking mechanism. The main type is the `InfoPool`, which represents a pool of random bytes that can be observed via the `InfoTap` object (obtained via `InfoPool#tap`).

*/
use std::fmt;
use hex_slice::AsHex;
use rand::{random, Rng, Rand};

/// A pool of data that we can draw upon to generate other types of data.
#[derive(Clone, Default, PartialEq)]
pub struct InfoPool {
    data: Vec<u8>,
}

/// A handle to an info Pool that we can draw bytes from.
#[derive(Clone, Default)]
pub struct InfoTap<'a> {
    data: &'a [u8],
    off: usize,
}

impl fmt::Debug for InfoPool {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("InfoPool")
            .field("data", &format_args!("{:x}", self.data.as_hex()))
            .finish()
    }
}

/// The reasons why drawing data from a pool can fail.
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum DataError {
    /// Not enough data to generate a value
    PoolExhausted,
    /// One of our combinators said that we should not test this value.
    SkipItem,
}

/// A convenience alias for generators that use the pool.
pub type Maybe<T> = Result<T, DataError>;

impl InfoPool {
    pub fn of_vec(data: Vec<u8>) -> Self {
        InfoPool { data: data }
    }
    pub fn random_of_size(size: usize) -> Self {
        Self::of_vec((0..size).map(|_| random()).collect::<Vec<u8>>())
    }

    pub fn from_random_of_size<R: Rng>(rng: &mut R, size: usize) -> Self {
        Self::of_vec(
            (0..size)
                .map(|_| (u64::rand(rng) >> 56) as u8)
                .collect::<Vec<u8>>(),
        )
    }

    pub fn buffer(&self) -> &[u8] {
        &*self.data
    }

    pub fn tap(&self) -> InfoTap {
        InfoTap {
            data: &*self.data,
            off: 0,
        }
    }
}

impl<'a> InfoTap<'a> {
    pub fn next_byte(&mut self) -> Maybe<u8> {
        let res = self.data.get(self.off).cloned();
        self.off += 1;
        res.ok_or(DataError::PoolExhausted)
    }
}

impl<'a> Iterator for InfoTap<'a> {
    type Item = u8;
    fn next(&mut self) -> Option<u8> {
        self.next_byte().ok()
    }
}

fn minimize_via_removal<F: Fn(InfoTap) -> bool>(
    p: &InfoPool,
    candidate: &mut InfoPool,
    pred: &F,
) -> Option<InfoPool> {
    // First shrink tactic: item removal
    trace!("minimizing by removal: {:?}", p);
    let max_pow = 0usize.count_zeros();
    let pow = max_pow - p.data.len().leading_zeros();
    for granularity in 0..pow {
        let width = p.data.len() >> granularity;
        for chunk in 0..(1 << granularity) {
            let start = chunk * width;
            let end = start + width;
            candidate.data.clear();
            candidate.data.extend(&p.data[0..start]);
            candidate.data.extend(&p.data[end..]);

            let test = pred(candidate.tap());
            trace!(
                "removed {},{}: {:?}; test result {}",
                start,
                end,
                candidate,
                test
            );
            if test {
                if let Some(res) = minimize(&candidate, pred) {
                    trace!("Returning shrunk: {:?}", res);
                    return Some(res);
                } else {
                    trace!("Returning original: {:?}", candidate);
                    return Some(candidate.clone());
                }
            }
        }
    }
    None
}

fn minimize_via_scalar_shrink<F: Fn(InfoTap) -> bool>(
    p: &InfoPool,
    candidate: &mut InfoPool,
    pred: &F,
) -> Option<InfoPool> {
    // Second shrink tactic: make values smaller
    trace!("minimizing by scalar shrink: {:?}", p);
    for i in 0..p.data.len() {
        candidate.clone_from(&p);

        for bitoff in 0..8 {
            candidate.data[i] = p.data[i] - (p.data[i] >> bitoff);
            trace!(
                "shrunk item -(bitoff:{}) {} {}->{}: {:?}",
                bitoff,
                i,
                p.data[i],
                candidate.data[i],
                candidate
            );

            if candidate.buffer() == p.buffer() {
                trace!("No change");
                continue;
            }

            let test = pred(candidate.tap());
            trace!("test result {}", test);
            if test {
                if let Some(res) = minimize(&candidate, pred) {
                    trace!("Returning shrunk: {:?}", res);
                    return Some(res);
                } else {
                    trace!("Returning original: {:?}", candidate);
                    return Some(candidate.clone());
                }
            }
        }
    }

    None
}

pub fn minimize<F: Fn(InfoTap) -> bool>(p: &InfoPool, pred: &F) -> Option<InfoPool> {
    let mut candidate = p.clone();
    if let Some(res) = minimize_via_removal(p, &mut candidate, pred) {
        return Some(res);
    }

    if let Some(res) = minimize_via_scalar_shrink(p, &mut candidate, pred) {
        return Some(res);
    }

    trace!("Nothing smaller found than {:?}", p);
    None
}

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

    #[test]
    fn should_take_each_item_in_pool() {
        let p = InfoPool::of_vec(vec![0, 1, 2, 3]);
        let mut t = p.tap();
        assert_eq!(t.next_byte(), Ok(0));
        assert_eq!(t.next_byte(), Ok(1));
        assert_eq!(t.next_byte(), Ok(2));
        assert_eq!(t.next_byte(), Ok(3));
        assert_eq!(t.next_byte(), Err(DataError::PoolExhausted));
    }

    #[test]
    fn should_generate_random_data_of_size() {
        let size = 100;
        let p = InfoPool::random_of_size(size);
        let mut t = p.tap();
        for _ in 0..size {
            assert!(t.next_byte().is_ok());
        }
        assert!(t.next_byte().is_err());
    }

    #[test]
    fn should_allow_restarting_read() {
        let p = InfoPool::random_of_size(4);
        let mut t = p.tap();
        let mut v0 = Vec::new();
        while let Ok(val) = t.next_byte() {
            v0.push(val)
        }

        let mut t = p.tap();
        let mut v1 = Vec::new();
        while let Ok(val) = t.next_byte() {
            v1.push(val)
        }

        assert_eq!(v0, v1)
    }

    #[test]
    fn should_allow_borrowing_buffer() {
        let p = InfoPool::of_vec(vec![1]);
        assert_eq!(p.buffer(), &[1]);
    }

    #[test]
    fn tap_can_act_as_iterator() {
        let buf = vec![4, 3, 2, 1];
        let p = InfoPool::of_vec(buf.clone());
        let _: &Iterator<Item = u8> = &p.tap();

        assert_eq!(p.tap().collect::<Vec<_>>(), buf)
    }
    #[test]
    fn minimiser_should_minimise_to_empty() {
        let p = InfoPool::of_vec(vec![1]);
        let min = minimize(&p, &|_| true);

        assert_eq!(min.as_ref().map(|p| p.buffer()), Some([].as_ref()))
    }

    #[test]
    fn minimiser_should_minimise_to_minimum_given_size() {
        let p = InfoPool::of_vec(vec![0; 4]);
        let min = minimize(&p, &|t| t.count() > 1).expect("some smaller pool");

        assert_eq!(min.buffer(), &[0, 0])
    }

    #[test]
    fn minimiser_should_minimise_scalar_values() {
        let p = InfoPool::of_vec(vec![255; 3]);
        let min = minimize(&p, &|mut t| t.any(|v| v >= 3)).expect("some smaller pool");

        assert_eq!(min.buffer(), &[3])
    }
    #[test]
    fn minimiser_should_minimise_scalar_values_to_zero() {
        let p = InfoPool::of_vec(vec![255; 3]);
        let min = minimize(&p, &|mut t| t.any(|_| true)).expect("some smaller pool");

        assert_eq!(min.buffer(), &[0])
    }

    #[test]
    fn minimiser_should_minimise_scalar_values_by_search() {
        let p = InfoPool::of_vec(vec![255; 3]);
        let min = minimize(&p, &|mut t| t.any(|v| v >= 13)).expect("some smaller pool");

        assert_eq!(min.buffer(), &[13])
    }
    #[test]
    fn minimiser_should_minimise_scalar_values_accounting_for_overflow() {
        let p = InfoPool::of_vec(vec![255; 3]);
        let min = minimize(&p, &|mut t| t.any(|v| v >= 251)).expect("some smaller pool");

        assert_eq!(min.buffer(), &[251])
    }
}
<commit_msg>Document data module.<commit_after>//! This module contains the underlying data generation and shrinking
//! mechanism. The main type is the `InfoPool`, which represents a pool of
//! random bytes that can be observed via the `InfoTap` object (obtained via
//! `InfoPool#tap`).
//!
//! Also manages the shrinking process (see [`minimize`](fn.minimize.html)).

use std::fmt;
use hex_slice::AsHex;
use rand::{random, Rng, Rand};

/// A pool of data that we can draw upon to generate other types of data.
#[derive(Clone, Default, PartialEq)]
pub struct InfoPool {
    data: Vec<u8>,
}

/// A handle to an info Pool that we can draw bytes from.
#[derive(Clone, Default)]
pub struct InfoTap<'a> {
    data: &'a [u8],
    off: usize,
}

impl fmt::Debug for InfoPool {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        fmt.debug_struct("InfoPool")
            .field("data", &format_args!("{:x}", self.data.as_hex()))
            .finish()
    }
}

/// The reasons why drawing data from a pool can fail.
#[derive(Debug, Clone, Eq, PartialEq)]
pub enum DataError {
    /// Not enough data to generate a value
    PoolExhausted,
    /// One of our combinators said that we should not test this value.
    SkipItem,
}

/// A convenience alias for generators that use the pool.
pub type Maybe<T> = Result<T, DataError>;

impl InfoPool {
    /// Create an `InfoPool` with a given vector of bytes. (Mostly used for
    /// testing).
    pub fn of_vec(data: Vec<u8>) -> Self {
        InfoPool { data: data }
    }
    /// Create an `InfoPool` with a `size` length vector of random bytes.
    /// (Mostly used for testing).
    pub fn random_of_size(size: usize) -> Self {
        Self::of_vec((0..size).map(|_| random()).collect::<Vec<u8>>())
    }

    /// Create an `InfoPool` with a `size` length vector of random bytes
    /// using the generator `rng`. (Mostly used for testing).
    pub fn from_random_of_size<R: Rng>(rng: &mut R, size: usize) -> Self {
        Self::of_vec(
            (0..size)
                .map(|_| (u64::rand(rng) >> 56) as u8)
                .collect::<Vec<u8>>(),
        )
    }

    /// Allows access to the underlying buffer.
    pub fn buffer(&self) -> &[u8] {
        &*self.data
    }

    /// Creates a tap that allows drawing information from this pool.
    pub fn tap(&self) -> InfoTap {
        InfoTap {
            data: &*self.data,
            off: 0,
        }
    }
}

impl<'a> InfoTap<'a> {
    /// Consumes the next byte from this tap. Returns `Ok(x)` if successful,
    /// or `Err(DataError::PoolExhausted)` if we have reached the end.
    pub fn next_byte(&mut self) -> Maybe<u8> {
        let res = self.data.get(self.off).cloned();
        self.off += 1;
        res.ok_or(DataError::PoolExhausted)
    }
}

impl<'a> Iterator for InfoTap<'a> {
    type Item = u8;
    fn next(&mut self) -> Option<u8> {
        self.next_byte().ok()
    }
}

fn minimize_via_removal<F: Fn(InfoTap) -> bool>(
    p: &InfoPool,
    candidate: &mut InfoPool,
    pred: &F,
) -> Option<InfoPool> {
    // First shrink tactic: item removal
    trace!("minimizing by removal: {:?}", p);
    let max_pow = 0usize.count_zeros();
    let pow = max_pow - p.data.len().leading_zeros();
    for granularity in 0..pow {
        let width = p.data.len() >> granularity;
        for chunk in 0..(1 << granularity) {
            let start = chunk * width;
            let end = start + width;
            candidate.data.clear();
            candidate.data.extend(&p.data[0..start]);
            candidate.data.extend(&p.data[end..]);

            let test = pred(candidate.tap());
            trace!(
                "removed {},{}: {:?}; test result {}",
                start,
                end,
                candidate,
                test
            );
            if test {
                if let Some(res) = minimize(&candidate, pred) {
                    trace!("Returning shrunk: {:?}", res);
                    return Some(res);
                } else {
                    trace!("Returning original: {:?}", candidate);
                    return Some(candidate.clone());
                }
            }
        }
    }
    None
}

fn minimize_via_scalar_shrink<F: Fn(InfoTap) -> bool>(
    p: &InfoPool,
    candidate: &mut InfoPool,
    pred: &F,
) -> Option<InfoPool> {
    // Second shrink tactic: make values smaller
    trace!("minimizing by scalar shrink: {:?}", p);
    for i in 0..p.data.len() {
        candidate.clone_from(&p);

        for bitoff in 0..8 {
            candidate.data[i] = p.data[i] - (p.data[i] >> bitoff);
            trace!(
                "shrunk item -(bitoff:{}) {} {}->{}: {:?}",
                bitoff,
                i,
                p.data[i],
                candidate.data[i],
                candidate
            );

            if candidate.buffer() == p.buffer() {
                trace!("No change");
                continue;
            }

            let test = pred(candidate.tap());
            trace!("test result {}", test);
            if test {
                if let Some(res) = minimize(&candidate, pred) {
                    trace!("Returning shrunk: {:?}", res);
                    return Some(res);
                } else {
                    trace!("Returning original: {:?}", candidate);
                    return Some(candidate.clone());
                }
            }
        }
    }

    None
}

/// Try to find the smallest pool `p` such that the predicate `pred` returns
/// true. Given that our [generators](../generators/index.html) tend to
/// generate smaller outputs from smaller inputs, by minimizing the source
/// pool we can find the smallest value that provokes a failure.
///
/// If we do not find any smaller pool that satisifies `pred`; we return
/// `None`.
///
/// Currently, we have two heuristics for shrinking: removing slices, and
/// reducing individual values.
///
/// Removing slices tries to remove as much of the pool as it can whilst still
/// having the predicate hold. At present, we do this by removing each half
/// and testing, then each quarter, eighths, and so on. Eventually, we plan to
/// track the regions of data that each generator draws from, and use that to
/// optimise the shrinking process.
///
/// Reducing individual values basically goes through each position in the
/// pool, and then tries reducing it to zero, then half, thn three quarters,
/// seven eighths, and so on.
pub fn minimize<F: Fn(InfoTap) -> bool>(p: &InfoPool, pred: &F) -> Option<InfoPool> {
    let mut candidate = p.clone();
    if let Some(res) = minimize_via_removal(p, &mut candidate, pred) {
        return Some(res);
    }

    if let Some(res) = minimize_via_scalar_shrink(p, &mut candidate, pred) {
        return Some(res);
    }

    trace!("Nothing smaller found than {:?}", p);
    None
}

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

    #[test]
    fn should_take_each_item_in_pool() {
        let p = InfoPool::of_vec(vec![0, 1, 2, 3]);
        let mut t = p.tap();
        assert_eq!(t.next_byte(), Ok(0));
        assert_eq!(t.next_byte(), Ok(1));
        assert_eq!(t.next_byte(), Ok(2));
        assert_eq!(t.next_byte(), Ok(3));
        assert_eq!(t.next_byte(), Err(DataError::PoolExhausted));
    }

    #[test]
    fn should_generate_random_data_of_size() {
        let size = 100;
        let p = InfoPool::random_of_size(size);
        let mut t = p.tap();
        for _ in 0..size {
            assert!(t.next_byte().is_ok());
        }
        assert!(t.next_byte().is_err());
    }

    #[test]
    fn should_allow_restarting_read() {
        let p = InfoPool::random_of_size(4);
        let mut t = p.tap();
        let mut v0 = Vec::new();
        while let Ok(val) = t.next_byte() {
            v0.push(val)
        }

        let mut t = p.tap();
        let mut v1 = Vec::new();
        while let Ok(val) = t.next_byte() {
            v1.push(val)
        }

        assert_eq!(v0, v1)
    }

    #[test]
    fn should_allow_borrowing_buffer() {
        let p = InfoPool::of_vec(vec![1]);
        assert_eq!(p.buffer(), &[1]);
    }

    #[test]
    fn tap_can_act_as_iterator() {
        let buf = vec![4, 3, 2, 1];
        let p = InfoPool::of_vec(buf.clone());
        let _: &Iterator<Item = u8> = &p.tap();

        assert_eq!(p.tap().collect::<Vec<_>>(), buf)
    }
    #[test]
    fn minimiser_should_minimise_to_empty() {
        let p = InfoPool::of_vec(vec![1]);
        let min = minimize(&p, &|_| true);

        assert_eq!(min.as_ref().map(|p| p.buffer()), Some([].as_ref()))
    }

    #[test]
    fn minimiser_should_minimise_to_minimum_given_size() {
        let p = InfoPool::of_vec(vec![0; 4]);
        let min = minimize(&p, &|t| t.count() > 1).expect("some smaller pool");

        assert_eq!(min.buffer(), &[0, 0])
    }

    #[test]
    fn minimiser_should_minimise_scalar_values() {
        let p = InfoPool::of_vec(vec![255; 3]);
        let min = minimize(&p, &|mut t| t.any(|v| v >= 3)).expect("some smaller pool");

        assert_eq!(min.buffer(), &[3])
    }
    #[test]
    fn minimiser_should_minimise_scalar_values_to_zero() {
        let p = InfoPool::of_vec(vec![255; 3]);
        let min = minimize(&p, &|mut t| t.any(|_| true)).expect("some smaller pool");

        assert_eq!(min.buffer(), &[0])
    }

    #[test]
    fn minimiser_should_minimise_scalar_values_by_search() {
        let p = InfoPool::of_vec(vec![255; 3]);
        let min = minimize(&p, &|mut t| t.any(|v| v >= 13)).expect("some smaller pool");

        assert_eq!(min.buffer(), &[13])
    }
    #[test]
    fn minimiser_should_minimise_scalar_values_accounting_for_overflow() {
        let p = InfoPool::of_vec(vec![255; 3]);
        let min = minimize(&p, &|mut t| t.any(|v| v >= 251)).expect("some smaller pool");

        assert_eq!(min.buffer(), &[251])
    }
}
<|endoftext|>


<commit_before>extern crate tinyrsh;

use std::collections::HashMap;
use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};
use std::io;
use std::os::unix::io::{RawFd, AsRawFd};
use tinyrsh::select::FdSet;
use tinyrsh::child::PersistentChild;
use tinyrsh::fdstore::{FdStore, OnceAction, OnceAccept};

fn greet_client(mut stream: &TcpStream) {
    let remote = stream.peer_addr().unwrap();
    println!("connected: {}", remote);

    match stream.write(b"hello\n") {
        Err(e) => println!("{}", e),
        Ok(n) => println!("wrote {} bytes", n),
    };
}

fn read_child<T: Read>(readt: &mut T) {
    let mut buf = [0; 10];
    let n = readt.read(&mut buf).expect("read_child");
    println!("({} bytes) `{}'", n, String::from_utf8_lossy(&buf[..n]));
}

fn forward_to_remotes<T: Read, S>(child_out: &mut T, clients: &HashMap<S, TcpStream>) -> bool
    where S : std::cmp::Eq, S : std::hash::Hash
{
    let mut buf = [0; 10];
    let n = child_out.read(&mut buf).expect("read_child");
    let child_eof = (n == 0);
    if clients.is_empty() {
        println!("Warning: child output but no remote connected");
        println!("{:?} ({} bytes) `{}'", buf, n, String::from_utf8_lossy(&buf[..n]));
    }
    for mut remote in clients.values(){
        //println!("forwarding to {}", remote.peer_addr().unwrap());
        let written = remote.write(&buf[..n]).expect("remote write");
        assert_eq!(n, written);
    }
    child_eof
}

fn copy_to<T: Read, U: Write>(from: &mut T, to: &mut U) -> bool {
    let mut buf = [0; 10];
    let n = from.read(&mut buf).expect("copy_to read");
    //println!("copy_to read {:?} ({} bytes) `{}'", buf, n, String::from_utf8_lossy(&buf[..n]));
    let written = to.write(&buf[..n]).expect("copy_to write");
    to.flush();
    assert_eq!(n, written);

    n != 0
}

fn main() {
    println!("Hello, world!");

    let mut child = PersistentChild::new("../py-ptysh/ptysh.py");

    // TODO linebuffered? how is child output buffered at all?

    let listener = TcpListener::bind("127.0.0.1:6699").unwrap();

    let mut fdstore = FdStore::new(listener);

    for fd in [child.child.stdout.as_ref().unwrap().as_raw_fd(), child.child.stderr.as_ref().unwrap().as_raw_fd()].iter() {
        println!("inserting child fd {}", fd);
        fdstore.all_fdset.insert(*fd);
    };

   println!("select-looping");
   loop {
       //let readfds = fdstore.all_fdset.readfds_select();
       //for fd in readfds {
       let srvacceptfun = | allfd: &FdStore, a: OnceAccept | -> io::Result<TcpStream> {
              println!("Accepting new connection");
              match a.do_accept() {
                  Err(e) => { println!("couldn't get client: {:?}", e);
                              Err(e)
                  }
                  Ok((mut stream, addr)) => {
                      println!("new client: {:?}", addr);
                      greet_client(&mut stream);
                      Ok(stream)
                  }
              }
            };
       let active_vec = fdstore.select(&srvacceptfun);
       for active in active_vec {
       match active {
          OnceAction::Other(fd) => {
          if child.is_stdout(fd) {
              println!("child fd {} (stdout) got active", fd);
              let child_eof = forward_to_remotes(child.stdout_as_mut(), &fdstore.clients);
              if child_eof {
                  println!("!!!!!!! child exited. pipe will break now");
                  //println!("exit code: {}", child.wait().expect("child unexpected state"));
                  //ahh, ownership!
              }
              assert!(!child_eof, "child exited, unhandled!");
          } else if child.is_stderr(fd) {
              println!("child fd {} (stderr) got active", fd);
              read_child(child.stderr_as_mut());
          } else {
              assert!(fdstore.clients.contains_key(&fd));
              let cont = {
                  //let ref stream = clients[&i];
                  let stream: &mut TcpStream = fdstore.clients.get_mut(&fd).unwrap();
                  //read_client(stream)
                  copy_to(stream, child.stdin_as_mut())
              };
              if !cont {
                  fdstore.del_client(fd);
              };
          }
          }//Other
    } //match
    } //for
    } //loop
}
<commit_msg>tuned<commit_after>extern crate tinyrsh;

use std::collections::HashMap;
use std::net::{TcpListener, TcpStream};
use std::io::{Read, Write};
use std::io;
use std::os::unix::io::{RawFd, AsRawFd};
use tinyrsh::select::FdSet;
use tinyrsh::child::PersistentChild;
use tinyrsh::fdstore::{FdStore, OnceAction, OnceAccept};

fn greet_client(fdstore: &FdStore, mut stream: &TcpStream) {
   assert_eq!(stream.write(b"hello\n").expect("greet client failed"), 6);
   stream.write(b"Your fellow peers:");
   let mut v = vec![];
   for other in fdstore.clients.keys() {
       v.push(format!("fd {}", other));
   }
   stream.write(v.join(", ").as_bytes());
   stream.write(b"\n");
}

fn read_child<T: Read>(readt: &mut T) {
    let mut buf = [0; 10];
    let n = readt.read(&mut buf).expect("read_child");
    println!("({} bytes) `{}'", n, String::from_utf8_lossy(&buf[..n]));
}

fn forward_to_remotes<T: Read, S>(child_out: &mut T, clients: &HashMap<S, TcpStream>) -> bool
    where S : std::cmp::Eq, S : std::hash::Hash
{
    let mut buf = [0; 10];
    let n = child_out.read(&mut buf).expect("read_child");
    let child_eof = (n == 0);
    if clients.is_empty() {
        println!("Warning: child output but no remote connected");
        println!("{:?} ({} bytes) `{}'", buf, n, String::from_utf8_lossy(&buf[..n]));
    }
    for mut remote in clients.values(){
        //println!("forwarding to {}", remote.peer_addr().unwrap());
        let written = remote.write(&buf[..n]).expect("remote write");
        assert_eq!(n, written);
    }
    child_eof
}

fn copy_to<T: Read, U: Write>(from: &mut T, to: &mut U) -> bool {
    let mut buf = [0; 10];
    let n = from.read(&mut buf).expect("copy_to read");
    //println!("copy_to read {:?} ({} bytes) `{}'", buf, n, String::from_utf8_lossy(&buf[..n]));
    let written = to.write(&buf[..n]).expect("copy_to write");
    to.flush();
    assert_eq!(n, written);

    n != 0
}

fn main() {
    println!("Hello, world!");

    let mut child = PersistentChild::new("../py-ptysh/ptysh.py");

    // TODO linebuffered? how is child output buffered at all?

    let listener = TcpListener::bind("127.0.0.1:6699").unwrap();

    let mut fdstore = FdStore::new(listener);

    for fd in [child.child.stdout.as_ref().unwrap().as_raw_fd(), child.child.stderr.as_ref().unwrap().as_raw_fd()].iter() {
        println!("inserting child fd {}", fd);
        fdstore.all_fdset.insert(*fd);
    };

   println!("select-looping");
   loop {
       //let readfds = fdstore.all_fdset.readfds_select();
       //for fd in readfds {
       let srvacceptfun = | allfd: &FdStore, a: OnceAccept | -> io::Result<TcpStream> {
              println!("Accepting new connection");
              a.do_accept().map( | (mut stream, addr) | {
                      println!("new client: {:?}", addr);
                      greet_client(allfd, &mut stream);
                      stream
              })
           };
       let active_vec = fdstore.select(&srvacceptfun);
       for active in active_vec {
       match active {
          OnceAction::Other(fd) => {
          if child.is_stdout(fd) {
              println!("child fd {} (stdout) got active", fd);
              let child_eof = forward_to_remotes(child.stdout_as_mut(), &fdstore.clients);
              if child_eof {
                  println!("!!!!!!! child exited. pipe will break now");
                  //println!("exit code: {}", child.wait().expect("child unexpected state"));
                  //ahh, ownership!
              }
              assert!(!child_eof, "child exited, unhandled!");
          } else if child.is_stderr(fd) {
              println!("child fd {} (stderr) got active", fd);
              read_child(child.stderr_as_mut());
          } else {
              assert!(fdstore.clients.contains_key(&fd));
              let cont = {
                  //let ref stream = clients[&i];
                  let stream: &mut TcpStream = fdstore.clients.get_mut(&fd).unwrap();
                  //read_client(stream)
                  copy_to(stream, child.stdin_as_mut())
              };
              if !cont {
                  fdstore.del_client(fd);
              };
          }
          }//Other
    } //match
    } //for
    } //loop
}
<|endoftext|>


<commit_before>use luminance::{Dim2, Flat, RGBA32F, Texture};

/// Time.
pub type Time = f32;

/// A clip is an object that implements a visual sequence.
pub struct Clip<'a> {
  act: Box<Fn(Time) -> &'a Texture<Flat, Dim2, RGBA32F> + 'a>
}

impl<'a> Clip<'a> {
  pub fn new<F>(act: F) -> Self where F: 'a + Fn(Time) -> &'a Texture<Flat, Dim2, RGBA32F> {
    Clip {
      act: Box::new(act)
    }
  }
}

/// A cut is an object that slices a `Clip` at an *input time* and *output time*. It is instantiated
/// in a `Track` at a given *instance time*.
#[derive(Clone)]
pub struct Cut<'a> {
  pub in_time: Time,
  pub out_time: Time,
  pub inst_time: Time,
  pub clip: &'a Clip<'a>
}

impl<'a> Cut<'a> {
  pub fn new(in_time: Time, out_time: Time, inst_time: Time, clip: &'a Clip<'a>) -> Self {
    Cut {
      in_time: in_time,
      out_time: out_time,
      inst_time: inst_time,
      clip: clip
    }
  }
}

/// A track gathers `Cut`s and its purpose is to be used inside a `Timeline`.
#[derive(Clone)]
pub struct Track<'a> {
  cuts: Vec<Cut<'a>>
}

impl<'a> Track<'a> {
  pub fn new() -> Self {
    Track {
      cuts: Vec::new()
    }
  }

  pub fn add_cut(&mut self, cut: Cut<'a>) {
    self.cuts.push(cut);
  }
}

impl<'a, 'b> From<&'b [Cut<'a>]> for Track<'a> {
  fn from(cuts: &'b [Cut<'a>]) -> Self {
    Track {
      cuts: cuts.to_vec()
    }
  }
}

/// A timeline gathers tracks used to build up the visual aspect of the demo.
#[derive(Clone)]
pub struct Timeline<'a> {
  tracks: Vec<Track<'a>>,
  crosses: Vec<TrackCross<'a>>
}

impl<'a> Timeline<'a> {
  pub fn new() -> Self {
    Timeline {
      tracks: Vec::new(),
      crosses: Vec::new()
    }
  }

  pub fn add_track(&mut self, track: Track<'a>) {
    self.tracks.push(track);
  }
}

impl<'a, 'b> From<&'b [Track<'a>]> for Timeline<'a> {
  fn from(tracks: &'b [Track<'a>]) -> Self {
    Timeline {
      tracks: tracks.to_vec(),
      crosses: Vec::new()
    }
  }
}

/// An optimized structure used to put spanning regions over cuts of several tracks in a timeline in
/// order to know which cuts of which tracks are active at any time in O(1). A track cross
/// represents such a single region, and a list of ascending-ordered track cross can be used to
/// render the demo in an optimized way.
#[derive(Clone)]
struct TrackCross<'a> {
  /// Time at which the track cross begins.
  in_time: Time,
  /// Time at which the track cross ends.
  out_time: Time,
  /// List of cuts that are active at the given time.
  cuts: Vec<&'a Cut<'a>>
}
<commit_msg>CrossList added.<commit_after>use luminance::{Dim2, Flat, RGBA32F, Texture};

/// Time.
pub type Time = f32;

/// A clip is an object that implements a visual sequence.
pub struct Clip<'a> {
  act: Box<Fn(Time) -> &'a Texture<Flat, Dim2, RGBA32F> + 'a>
}

impl<'a> Clip<'a> {
  pub fn new<F>(act: F) -> Self where F: 'a + Fn(Time) -> &'a Texture<Flat, Dim2, RGBA32F> {
    Clip {
      act: Box::new(act)
    }
  }
}

/// A cut is an object that slices a `Clip` at an *input time* and *output time*. It is instantiated
/// in a `Track` at a given *instance time*.
#[derive(Clone)]
pub struct Cut<'a> {
  pub in_time: Time,
  pub out_time: Time,
  pub inst_time: Time,
  pub clip: &'a Clip<'a>
}

impl<'a> Cut<'a> {
  pub fn new(in_time: Time, out_time: Time, inst_time: Time, clip: &'a Clip<'a>) -> Self {
    Cut {
      in_time: in_time,
      out_time: out_time,
      inst_time: inst_time,
      clip: clip
    }
  }
}

/// A track gathers `Cut`s and its purpose is to be used inside a `Timeline`.
#[derive(Clone)]
pub struct Track<'a> {
  cuts: Vec<Cut<'a>>
}

impl<'a> Track<'a> {
  pub fn new() -> Self {
    Track {
      cuts: Vec::new()
    }
  }

  pub fn add_cut(&mut self, cut: Cut<'a>) {
    self.cuts.push(cut);
  }
}

impl<'a, 'b> From<&'b [Cut<'a>]> for Track<'a> {
  fn from(cuts: &'b [Cut<'a>]) -> Self {
    Track {
      cuts: cuts.to_vec()
    }
  }
}

/// A timeline gathers tracks used to build up the visual aspect of the demo.
#[derive(Clone)]
pub struct Timeline<'a> {
  tracks: Vec<Track<'a>>,
  cross_list: CrossList<'a>
}

impl<'a> Timeline<'a> {
  pub fn new() -> Self {
    Timeline {
      tracks: Vec::new(),
      cross_list: CrossList::new()
    }
  }

  pub fn add_track(&mut self, track: Track<'a>) {
    self.tracks.push(track);
  }
}

impl<'a, 'b> From<&'b [Track<'a>]> for Timeline<'a> {
  fn from(tracks: &'b [Track<'a>]) -> Self {
    Timeline {
      tracks: tracks.to_vec(),
      cross_list: CrossList::new()
    }
  }
}

/// An optimized structure used to put spanning regions over cuts of several tracks in a timeline in
/// order to know which cuts of which tracks are active at any time in O(1). A track cross
/// represents such a single region, and a list of ascending-ordered track cross can be used to
/// render the demo in an optimized way.
#[derive(Clone)]
struct TrackCross<'a> {
  /// Time at which the track cross begins.
  in_time: Time,
  /// Duration.
  out_time: Time,
  /// List of cuts that are active at the given time.
  cuts: Vec<&'a Cut<'a>>
}

impl<'a> TrackCross<'a> {
  pub fn new(in_time: Time, out_time: Time, cuts: &'a [&'a Cut<'a>]) -> Self {
    TrackCross {
      in_time: in_time,
      out_time: out_time,
      cuts: cuts.to_vec()
    }
  }

  // TODO
  /// Perform a cross track cut act.
  pub fn cross_act(&self, t: Time) -> &'a Texture<Flat, Dim2, RGBA32F> {
    if self.cuts.len() != 1 {
      unimplemented!();
    }

    // convert t into the clip’s time space
    let cut = self.cuts[0];
    let clip_t = t - cut.inst_time;

    (cut.clip.act)(clip_t)
  }
}

/// A list of cut cross optimized for forward playing.
#[derive(Clone)]
struct CrossList<'a> {
  track_cross: Vec<TrackCross<'a>>,
  current: usize
}

impl<'a> CrossList<'a> {
  fn new() -> Self {
    CrossList {
      track_cross: Vec::new(),
      current: 0
    }
  }
}
<|endoftext|>


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

use parse::{self, Token, ParseError};
use value::{Value, Func, Args, FromLisp, ToLisp};
use env::Env;

pub type FuncResult = Result<Value, FuncError>;

#[derive(Debug)]
pub enum FuncError {
    InvalidArguments,
    InvalidType,
    UndeclaredSymbol(String),
    AttemptToCallNonFunction,
    IoError(io::Error),

    ParsingErr(ParseError),
}

pub struct Lisp {
    scopes: Vec<Env>,
}

impl Lisp {
    pub fn new() -> Lisp {
        Lisp {
            scopes: vec![Env::std_lib()],
        }
    }

    pub fn eval<T: FromLisp>(&mut self, code: &str) -> Result<T, FuncError> {
        let result = try!(self.eval_raw(code));

        return T::from_lisp(result);
    }

    pub fn eval_raw(&mut self, code: &str) -> FuncResult {
        let mut token = match parse::tokenize_str(code) {
            Ok(tok) => tok,
            Err(err) => return Err(FuncError::ParsingErr(err)),
        };

        self.eval_token(token)
    }

    pub fn eval_token(&mut self, token: Token) -> FuncResult {
        match token {
            Token::Number(n) => Ok(Value::Number(n)),
            Token::StrLit(lit) => Ok(Value::Str(lit)),
            Token::Sym(sym) => {
                for env in self.scopes.iter().rev() {
                    if let Some(val) = env.map.get(&sym) {
                        return Ok(val.clone());
                    }
                }

                Err(FuncError::UndeclaredSymbol(sym))
            },
            Token::List(mut tokens) => {
                self.sub_scope(); // each list has its own scope
                let func = try!(self.eval_token(tokens.remove(0)));

                match func {
                    Value::HardFunc(hard_func) => {
                        let mut args = Vec::new();

                        for token in tokens {
                            args.push(try!(self.eval_token(token)));
                        }

                        match hard_func.args {
                            Args::Variant => (),
                            Args::Fixed(count) => {
                                if args.len() != count {
                                    return Err(FuncError::InvalidArguments);
                                }
                            },
                            Args::Multiple(possible_counts) => {
                                let mut arg_match = false;

                                // I wish I could label match statements and break out of them...
                                for count in possible_counts {
                                    if args.len() == count {
                                        arg_match = true;
                                        break;
                                    }
                                }

                                if !arg_match {
                                    return Err(FuncError::InvalidArguments);
                                }
                            },
                        }

                        (hard_func.func)(args, self)
                    },
                    _ => Err(FuncError::AttemptToCallNonFunction),
                }
            },
			Token::Quoted(tok) => Ok(Value::Quote(*tok)),
        }
    }

    pub fn set_global<T: ToLisp>(&mut self, name: &str, value: T) {
        self.scopes[0].set(name, value);
    }

    pub fn sub_scope(&mut self) {
        self.scopes.push(Env::new());
    }

    pub fn cur_scope(&mut self) -> &mut Env {
        let index = self.scopes.len() - 1;
        &mut self.scopes[index]
    }
}

impl fmt::Debug for Value {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Value::List(ref values) => write!(fmt, "{:?}", values),
            &Value::Str(ref string) => write!(fmt, "{:?}", string),
            &Value::Number(num) => write!(fmt, "{}", num),
            &Value::HardFunc(ref func) => write!(fmt, "HardFunc({:?})", func.args),
            &Value::Nil => write!(fmt, "nil"),
            &Value::Bool(val) => write!(fmt, "{}", val),
			&Value::Quote(ref tok) => write!(fmt, "Quote({:?})", tok),
        }
    }
}

<commit_msg>Scopes now properly exit<commit_after>
use std::io;
use std::fmt;
use std::collections::HashMap;

use parse::{self, Token, ParseError};
use value::{Value, Func, Args, FromLisp, ToLisp};
use env::Env;

pub type FuncResult = Result<Value, FuncError>;

#[derive(Debug)]
pub enum FuncError {
    InvalidArguments,
    InvalidType,
    UndeclaredSymbol(String),
    AttemptToCallNonFunction,
    IoError(io::Error),

    ParsingErr(ParseError),
}

pub struct Lisp {
    scopes: Vec<Env>,
}

impl Lisp {
    pub fn new() -> Lisp {
        Lisp {
            scopes: vec![Env::std_lib()],
        }
    }

    pub fn eval<T: FromLisp>(&mut self, code: &str) -> Result<T, FuncError> {
        let result = try!(self.eval_raw(code));

        return T::from_lisp(result);
    }

    pub fn eval_raw(&mut self, code: &str) -> FuncResult {
        let mut token = match parse::tokenize_str(code) {
            Ok(tok) => tok,
            Err(err) => return Err(FuncError::ParsingErr(err)),
        };

        self.eval_token(token)
    }

    pub fn eval_token(&mut self, token: Token) -> FuncResult {
        match token {
            Token::Number(n) => Ok(Value::Number(n)),
            Token::StrLit(lit) => Ok(Value::Str(lit)),
            Token::Sym(sym) => {
                for env in self.scopes.iter().rev() {
                    if let Some(val) = env.map.get(&sym) {
                        return Ok(val.clone());
                    }
                }

                Err(FuncError::UndeclaredSymbol(sym))
            },
            Token::List(mut tokens) => {
                self.sub_scope(); // each list has its own scope
                let func = try!(self.eval_token(tokens.remove(0)));

                match func {
                    Value::HardFunc(hard_func) => {
                        let mut args = Vec::new();

                        for token in tokens {
                            args.push(try!(self.eval_token(token)));
                        }

                        match hard_func.args {
                            Args::Variant => (),
                            Args::Fixed(count) => {
                                if args.len() != count {
                                    return Err(FuncError::InvalidArguments);
                                }
                            },
                            Args::Multiple(possible_counts) => {
                                let mut arg_match = false;

                                // I wish I could label match statements and break out of them...
                                for count in possible_counts {
                                    if args.len() == count {
                                        arg_match = true;
                                        break;
                                    }
                                }

                                if !arg_match {
                                    return Err(FuncError::InvalidArguments);
                                }
                            },
                        }

                        let result = (hard_func.func)(args, self);
                        self.exit_scope();

                        result
                    },
                    _ => Err(FuncError::AttemptToCallNonFunction),
                }

            },
			Token::Quoted(tok) => Ok(Value::Quote(*tok)),
        }
    }

    pub fn set_global<T: ToLisp>(&mut self, name: &str, value: T) {
        self.scopes[0].set(name, value);
    }

    pub fn sub_scope(&mut self) {
        self.scopes.push(Env::new());
    }

    pub fn exit_scope(&mut self) {
        self.scopes.pop();
    }

    pub fn cur_scope(&mut self) -> &mut Env {
        let index = self.scopes.len() - 1;
        &mut self.scopes[index]
    }
}

impl fmt::Debug for Value {
    fn fmt(&self, fmt: &mut fmt::Formatter) -> fmt::Result {
        match self {
            &Value::List(ref values) => write!(fmt, "{:?}", values),
            &Value::Str(ref string) => write!(fmt, "{:?}", string),
            &Value::Number(num) => write!(fmt, "{}", num),
            &Value::HardFunc(ref func) => write!(fmt, "HardFunc({:?})", func.args),
            &Value::Nil => write!(fmt, "nil"),
            &Value::Bool(val) => write!(fmt, "{}", val),
			&Value::Quote(ref tok) => write!(fmt, "Quote({:?})", tok),
        }
    }
}

<|endoftext|>