<commit_before>use std::error::Error as StdError;
use std::fmt::{Display, Formatter, Result as FmtResult};

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

/// Serializes `value` and returns it as string.
pub fn to_string<T>(value: &T) -> Result<String>
    where T: Serialize
{
    let mut s = Serializer { output: String::new() };
    value.serialize(&mut s)?;
    Ok(s.output)
}

type Result<T> = ::std::result::Result<T, Error>;

// This is a bare-bones implementation. A real library would provide additional
// information in its error type, for example the line and column at which the
// error occurred, the byte offset into the input, or the current key being
// processed.
#[derive(Clone, Debug, PartialEq)]
pub enum Error {
    /// A custom error emitted by a serialized value.
    Message(String),
}

impl Display for Error {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        match *self {
            Error::Message(ref e) => write!(f, "Cusom message: {}", e),
        }
    }
}

impl ser::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error::Message(msg.to_string())
    }
}

impl StdError for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Message(ref e) => e,
        }
    }
}

pub struct Serializer {
    output: String,
}

impl<'a> ser::Serializer for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Self;
    type SerializeTuple = Self;
    type SerializeTupleStruct = Self;
    type SerializeTupleVariant = Self;
    type SerializeMap = Self;
    type SerializeStruct = Self;
    type SerializeStructVariant = Self;

    fn serialize_bool(self, v: bool) -> Result<()> {
        self.output += if v { "true" } else { "false" };
        Ok(())
    }

    fn serialize_i8(self, v: i8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i16(self, v: i16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i32(self, v: i32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i64(self, v: i64) -> Result<()> {
        // TODO optimize
        self.output += &v.to_string();
        Ok(())
    }

    fn serialize_u8(self, v: u8) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_u16(self, v: u16) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_u32(self, v: u32) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_u64(self, v: u64) -> Result<()> {
        self.output += &v.to_string();
        Ok(())
    }

    fn serialize_f32(self, v: f32) -> Result<()> {
        self.serialize_f64(v as f64)
    }

    fn serialize_f64(self, v: f64) -> Result<()> {
        self.output += &v.to_string();
        Ok(())
    }

    fn serialize_char(self, v: char) -> Result<()> {
        self.serialize_str(&v.to_string())
    }

    fn serialize_str(self, v: &str) -> Result<()> {
        self.output += "\"";
        self.output += v;
        self.output += "\"";
        Ok(())
    }

    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
        use serde::ser::SerializeSeq;
        let mut seq = self.serialize_seq(Some(v.len()))?;
        for byte in v {
            seq.serialize_element(byte)?;
        }
        seq.end()
    }

    fn serialize_none(self) -> Result<()> {
        self.output += "None";

        Ok(())
    }

    fn serialize_some<T>(self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += "Some(";
        value.serialize(&mut *self)?;
        self.output += ")";

        Ok(())
    }

    fn serialize_unit(self) -> Result<()> {
        self.output += "()";

        Ok(())
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
        self.output += name;

        Ok(())
    }

    fn serialize_unit_variant(
        self,
        _: &'static str,
        _: u32,
        variant: &'static str
    ) -> Result<()> {
        self.output += variant;

        Ok(())
    }

    fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += name;
        self.output += "(";
        value.serialize(&mut *self)?;
        self.output += ")";

        Ok(())
    }

    fn serialize_newtype_variant<T>(
        self,
        _: &'static str,
        _: u32,
        variant: &'static str,
        value: &T
    ) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += variant;
        self.output += "(";
        value.serialize(&mut *self)?;
        self.output += ",)";
        Ok(())
    }

    fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
        self.output += "[";

        Ok(self)
    }

    fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
        self.output += "(";

        Ok(self)
    }

    fn serialize_tuple_struct(
        self,
        name: &'static str,
        len: usize
    ) -> Result<Self::SerializeTupleStruct> {
        self.output += name;

        self.serialize_tuple(len)
    }

    fn serialize_tuple_variant(
        self,
        _: &'static str,
        _: u32,
        variant: &'static str,
        _: usize
    ) -> Result<Self::SerializeTupleVariant> {
        self.output += variant;
        self.output += "(";

        Ok(self)
    }

    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
        self.output += "{";

        Ok(self)
    }

    fn serialize_struct(
        self,
        name: &'static str,
        _: usize
    ) -> Result<Self::SerializeStruct> {
        self.output += name;
        self.output += "(";

        Ok(self)
    }

    fn serialize_struct_variant(
        self,
        _: &'static str,
        _: u32,
        variant: &'static str,
        _: usize
    ) -> Result<Self::SerializeStructVariant> {
        self.output += variant;
        self.output += "(";
        Ok(self)
    }
}

impl<'a> ser::SerializeSeq for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        value.serialize(&mut **self)?;
        self.output += ",";
        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += "]";
        Ok(())
    }
}

impl<'a> ser::SerializeTuple for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        value.serialize(&mut **self)?;
        self.output += ",";

        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += ")";

        Ok(())
    }
}

// Same thing but for tuple structs.
impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        value.serialize(&mut **self)?;
        self.output += ",";

        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += ")";

        Ok(())
    }
}

impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        value.serialize(&mut **self)?;
        self.output += ",";

        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += ")";
        Ok(())
    }
}

impl<'a> ser::SerializeMap for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        key.serialize(&mut **self)
    }

    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += ":";
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<()> {
        self.output += "}";
        Ok(())
    }
}

impl<'a> ser::SerializeStruct for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += key;
        self.output += ":";
        value.serialize(&mut **self)?;
        self.output += ",";

        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += ")";
        Ok(())
    }
}

impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += key;
        self.output += ":";
        value.serialize(&mut **self)?;
        self.output += ",";

        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += ")";
        Ok(())
    }
}

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

    #[derive(Serialize)]
    struct EmptyStruct1;

    #[derive(Serialize)]
    struct EmptyStruct2 {}

    #[derive(Serialize)]
    struct MyStruct { x: f32, y: f32 }

    #[derive(Serialize)]
    enum MyEnum {
        A,
        B(bool),
        C(bool, f32),
        D { a: i32, b: i32 }
    }

    #[test]
    fn test_empty_struct() {
        assert_eq!(to_string(&EmptyStruct1).unwrap(), "EmptyStruct1");
        assert_eq!(to_string(&EmptyStruct2 {}).unwrap(), "EmptyStruct2()");
    }

    #[test]
    fn test_struct() {
        let my_struct = MyStruct { x: 4.0, y: 7.0 };

        assert_eq!(to_string(&my_struct).unwrap(), "MyStruct(x:4,y:7,)");
    }

    #[test]
    fn test_enum() {
        assert_eq!(to_string(&MyEnum::A).unwrap(), "A");
        assert_eq!(to_string(&MyEnum::B(true)).unwrap(), "B(true,)");
        assert_eq!(to_string(&MyEnum::C(true, 3.5)).unwrap(), "C(true,3.5,)");
        assert_eq!(to_string(&MyEnum::D { a: 2, b: 3 }).unwrap(), "D(a:2,b:3,)");
    }
}
<commit_msg>Demonstrate weird sized / unsized behavior<commit_after>use std::error::Error as StdError;
use std::fmt::{Display, Formatter, Result as FmtResult};

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

/// Serializes `value` and returns it as string.
pub fn to_string<T>(value: &T) -> Result<String>
    where T: Serialize
{
    let mut s = Serializer { output: String::new() };
    value.serialize(&mut s)?;
    Ok(s.output)
}

type Result<T> = ::std::result::Result<T, Error>;

// This is a bare-bones implementation. A real library would provide additional
// information in its error type, for example the line and column at which the
// error occurred, the byte offset into the input, or the current key being
// processed.
#[derive(Clone, Debug, PartialEq)]
pub enum Error {
    /// A custom error emitted by a serialized value.
    Message(String),
}

impl Display for Error {
    fn fmt(&self, f: &mut Formatter) -> FmtResult {
        match *self {
            Error::Message(ref e) => write!(f, "Cusom message: {}", e),
        }
    }
}

impl ser::Error for Error {
    fn custom<T: Display>(msg: T) -> Self {
        Error::Message(msg.to_string())
    }
}

impl StdError for Error {
    fn description(&self) -> &str {
        match *self {
            Error::Message(ref e) => e,
        }
    }
}

pub struct Serializer {
    output: String,
}

impl<'a> ser::Serializer for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    type SerializeSeq = Self;
    type SerializeTuple = Self;
    type SerializeTupleStruct = Self;
    type SerializeTupleVariant = Self;
    type SerializeMap = Self;
    type SerializeStruct = Self;
    type SerializeStructVariant = Self;

    fn serialize_bool(self, v: bool) -> Result<()> {
        self.output += if v { "true" } else { "false" };
        Ok(())
    }

    fn serialize_i8(self, v: i8) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i16(self, v: i16) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i32(self, v: i32) -> Result<()> {
        self.serialize_i64(v as i64)
    }

    fn serialize_i64(self, v: i64) -> Result<()> {
        // TODO optimize
        self.output += &v.to_string();
        Ok(())
    }

    fn serialize_u8(self, v: u8) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_u16(self, v: u16) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_u32(self, v: u32) -> Result<()> {
        self.serialize_u64(v as u64)
    }

    fn serialize_u64(self, v: u64) -> Result<()> {
        self.output += &v.to_string();
        Ok(())
    }

    fn serialize_f32(self, v: f32) -> Result<()> {
        self.serialize_f64(v as f64)
    }

    fn serialize_f64(self, v: f64) -> Result<()> {
        self.output += &v.to_string();
        Ok(())
    }

    fn serialize_char(self, v: char) -> Result<()> {
        self.serialize_str(&v.to_string())
    }

    fn serialize_str(self, v: &str) -> Result<()> {
        self.output += "\"";
        self.output += v;
        self.output += "\"";
        Ok(())
    }

    fn serialize_bytes(self, v: &[u8]) -> Result<()> {
        use serde::ser::SerializeSeq;
        let mut seq = self.serialize_seq(Some(v.len()))?;
        for byte in v {
            seq.serialize_element(byte)?;
        }
        seq.end()
    }

    fn serialize_none(self) -> Result<()> {
        self.output += "None";

        Ok(())
    }

    fn serialize_some<T>(self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += "Some(";
        value.serialize(&mut *self)?;
        self.output += ")";

        Ok(())
    }

    fn serialize_unit(self) -> Result<()> {
        self.output += "()";

        Ok(())
    }

    fn serialize_unit_struct(self, name: &'static str) -> Result<()> {
        self.output += name;

        Ok(())
    }

    fn serialize_unit_variant(
        self,
        _: &'static str,
        _: u32,
        variant: &'static str
    ) -> Result<()> {
        self.output += variant;

        Ok(())
    }

    fn serialize_newtype_struct<T>(self, name: &'static str, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += name;
        self.output += "(";
        value.serialize(&mut *self)?;
        self.output += ")";

        Ok(())
    }

    fn serialize_newtype_variant<T>(
        self,
        _: &'static str,
        _: u32,
        variant: &'static str,
        value: &T
    ) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += variant;
        self.output += "(";
        value.serialize(&mut *self)?;
        self.output += ",)";
        Ok(())
    }

    fn serialize_seq(self, _: Option<usize>) -> Result<Self::SerializeSeq> {
        self.output += "[";

        Ok(self)
    }

    fn serialize_tuple(self, _: usize) -> Result<Self::SerializeTuple> {
        self.output += "(";

        Ok(self)
    }

    fn serialize_tuple_struct(
        self,
        name: &'static str,
        len: usize
    ) -> Result<Self::SerializeTupleStruct> {
        self.output += name;

        self.serialize_tuple(len)
    }

    fn serialize_tuple_variant(
        self,
        _: &'static str,
        _: u32,
        variant: &'static str,
        _: usize
    ) -> Result<Self::SerializeTupleVariant> {
        self.output += variant;
        self.output += "(";

        Ok(self)
    }

    fn serialize_map(self, _len: Option<usize>) -> Result<Self::SerializeMap> {
        self.output += "{";

        Ok(self)
    }

    fn serialize_struct(
        self,
        name: &'static str,
        _: usize
    ) -> Result<Self::SerializeStruct> {
        self.output += name;
        self.output += "(";

        Ok(self)
    }

    fn serialize_struct_variant(
        self,
        _: &'static str,
        _: u32,
        variant: &'static str,
        _: usize
    ) -> Result<Self::SerializeStructVariant> {
        self.output += variant;
        self.output += "(";
        Ok(self)
    }
}

impl<'a> ser::SerializeSeq for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        value.serialize(&mut **self)?;
        self.output += ",";
        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += "]";
        Ok(())
    }
}

impl<'a> ser::SerializeTuple for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_element<T>(&mut self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        value.serialize(&mut **self)?;
        self.output += ",";

        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += ")";

        Ok(())
    }
}

// Same thing but for tuple structs.
impl<'a> ser::SerializeTupleStruct for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        value.serialize(&mut **self)?;
        self.output += ",";

        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += ")";

        Ok(())
    }
}

impl<'a> ser::SerializeTupleVariant for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        value.serialize(&mut **self)?;
        self.output += ",";

        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += ")";
        Ok(())
    }
}

impl<'a> ser::SerializeMap for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_key<T>(&mut self, key: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        key.serialize(&mut **self)
    }

    fn serialize_value<T>(&mut self, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += ":";
        value.serialize(&mut **self)
    }

    fn end(self) -> Result<()> {
        self.output += "}";
        Ok(())
    }
}

impl<'a> ser::SerializeStruct for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += key;
        self.output += ":";
        value.serialize(&mut **self)?;
        self.output += ",";

        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += ")";
        Ok(())
    }
}

impl<'a> ser::SerializeStructVariant for &'a mut Serializer {
    type Ok = ();
    type Error = Error;

    fn serialize_field<T>(&mut self, key: &'static str, value: &T) -> Result<()>
        where T: ?Sized + Serialize
    {
        self.output += key;
        self.output += ":";
        value.serialize(&mut **self)?;
        self.output += ",";

        Ok(())
    }

    fn end(self) -> Result<()> {
        self.output += ")";
        Ok(())
    }
}

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

    #[derive(Serialize)]
    struct EmptyStruct1;

    #[derive(Serialize)]
    struct EmptyStruct2 {}

    #[derive(Serialize)]
    struct MyStruct { x: f32, y: f32 }

    #[derive(Serialize)]
    enum MyEnum {
        A,
        B(bool),
        C(bool, f32),
        D { a: i32, b: i32 }
    }

    #[test]
    fn test_empty_struct() {
        assert_eq!(to_string(&EmptyStruct1).unwrap(), "EmptyStruct1");
        assert_eq!(to_string(&EmptyStruct2 {}).unwrap(), "EmptyStruct2()");
    }

    #[test]
    fn test_struct() {
        let my_struct = MyStruct { x: 4.0, y: 7.0 };

        assert_eq!(to_string(&my_struct).unwrap(), "MyStruct(x:4,y:7,)");
    }

    #[test]
    fn test_enum() {
        assert_eq!(to_string(&MyEnum::A).unwrap(), "A");
        assert_eq!(to_string(&MyEnum::B(true)).unwrap(), "B(true,)");
        assert_eq!(to_string(&MyEnum::C(true, 3.5)).unwrap(), "C(true,3.5,)");
        assert_eq!(to_string(&MyEnum::D { a: 2, b: 3 }).unwrap(), "D(a:2,b:3,)");
    }

    #[test]
    fn test_array() {
        let empty: [i32; 0] = [];
        assert_eq!(to_string(&empty).unwrap(), "()");
        let empty_ref: &[i32] = ∅
        assert_eq!(to_string(&empty_ref).unwrap(), "[]");
    }
}
<|endoftext|>


<commit_before>use std::io::{IoResult, IoError, IoErrorKind, TcpStream, ConnectionRefused,
              ConnectionFailed, OtherIoError};

enum AuthMethod<'s> {
    NoAuth,
    UPass(&'s str, &'s str)
}

pub struct Socks5<'a> {
    socks_host: &'a str,
    socks_port: u16,
    socks_auth: AuthMethod<'a>,
}

impl<'a> Socks5<'a> {
    pub fn new(host: &'a str, port: u16) -> Socks5 {
        Socks5 {
            socks_host: host,
            socks_port: port,
            socks_auth: NoAuth
        }
    }

    pub fn login(&mut self, uname: &'a str, passwd: &'a str) {
        self.socks_auth = UPass(uname, passwd);
    }

    pub fn connect(&mut self, host: &str, port: u16) -> IoResult<TcpStream> {
        let mut stream = try!(TcpStream::connect(self.socks_host, self.socks_port));
        try!(stream.write([0x05u8]));
        match self.socks_auth {
            NoAuth => { try!(stream.write([0x01u8, 0x00])); },
            UPass(..) => { try!(stream.write([0x01u8, 0x02])); }
        }

        if try!(stream.read_u8()) != 0x05 {
            return io_err(OtherIoError, "Unexpected SOCKS version number");
        }

        match try!(stream.read_u8()) {
            0x00 => {
                match self.socks_auth {
                    NoAuth => { /* Continue */ },
                    _ => return io_err(OtherIoError,
                        "Wrong authentication method from server")
                }
            }
            0x02 => {
                match self.socks_auth {
                    UPass(uname, passwd) => {
                        try!(stream.write([0x01u8, uname.len() as u8]));
                        try!(stream.write_str(uname));
                        try!(stream.write([passwd.len() as u8]));
                        try!(stream.write_str(passwd));

                        if try!(stream.read_u8()) != 0x01 {
                            return io_err(OtherIoError,
                                "Invalid authentication version");
                        }

                        if try!(stream.read_u8()) != 0x00 {
                            return io_err(ConnectionRefused, "Authentication failed");
                        }
                    }
                    _ => { return io_err(OtherIoError,
                            "Wrong authentication method from server");
                    }
                }
            }
            0xFF => { return io_err(ConnectionRefused,
                      "Server refused authentication methods"); }
            _ => { return io_err(OtherIoError,
                    "Wrong authentication method from server"); }
        }

        try!(stream.write([0x05u8, 0x01, 0x00, 0x03, host.len() as u8]));
        try!(stream.write_str(host));
        try!(stream.write_be_u16(port));

        if try!(stream.read_u8()) != 0x05 {
            return io_err(OtherIoError, "Invalid SOCKS version number");
        }

        match try!(stream.read_u8()) {
            0x00 => {
                let _null = try!(stream.read_u8());

                match try!(stream.read_u8()) {
                    0x01 => {
                        let mut _ipv4 = [0,.. 4];
                        try!(stream.read_at_least(4, &mut _ipv4));
                    }
                    0x03 => {
                        let addrlen = try!(stream.read_u8());
                        let _domain = try!(stream.read_exact(addrlen as uint));
                    }
                    0x04 => {
                        let mut _ipv6 = [0,.. 16];
                        try!(stream.read_at_least(16, &mut _ipv6));
                    }
                    _ => return io_err(OtherIoError, "Invalid address type"),
                }

                let _port = try!(stream.read_be_u16());
                Ok(stream)
            }
            0x01 => io_err(OtherIoError, "General failure"),
            0x02 => io_err(OtherIoError, "Connection not allowed by ruleset"),
            0x03 => io_err(ConnectionFailed, "Network unreachable"),
            0x04 => io_err(ConnectionFailed, "Host unreachable"),
            0x05 => io_err(ConnectionRefused, "Connection refused by destination"),
            0x06 => io_err(ConnectionFailed, "TTL expired"),
            0x07 => io_err(OtherIoError, "Protocol Error"),
            0x08 => io_err(OtherIoError, "Address type not supported"),
            _ => io_err(OtherIoError, "Unknown error")
        }
    }
}

fn io_err<T>(kind: IoErrorKind, desc: &'static str) -> IoResult<T> {
    Err(IoError { kind: kind, desc: desc, detail: None })
}
<commit_msg>Accept Domain/Ipv4/Ipv6 destinations.<commit_after>use std::io::{IoResult, IoError, IoErrorKind, TcpStream, ConnectionRefused,
              ConnectionFailed, OtherIoError};
use std::io::net::ip::{IpAddr, Ipv4Addr, Ipv6Addr};

enum AuthMethod<'s> {
    NoAuth,
    UPass(&'s str, &'s str)
}

pub trait Socks5Destination {
    fn write_destination(&self, &mut TcpStream) -> IoResult<()>;
}

impl<'a> Socks5Destination for &'a str {
    fn write_destination(&self, stream: &mut TcpStream) -> IoResult<()> {
        if self.len() > 255 {
            return io_err(OtherIoError, "Domain length is too long");
        }

        try!(stream.write([0x03, self.len() as u8]));
        try!(stream.write_str(*self));
        Ok(())
    }
}

impl<'a> Socks5Destination for IpAddr {
    fn write_destination(&self, stream: &mut TcpStream) -> IoResult<()> {
        match *self {
            Ipv4Addr(a, b, c, d) => try!(stream.write([0x01, a, b, c, d])),
            Ipv6Addr(a, b, c, d, e, f, g, h) => {
                try!(stream.write_u8(0x04));
                for &pair in [a, b, c, d, e, f, g, h].iter() {
                    try!(stream.write_be_u16(pair));
                }
            }
        }

        Ok(())
    }
}

pub struct Socks5<'a> {
    socks_host: &'a str,
    socks_port: u16,
    socks_auth: AuthMethod<'a>,
}

impl<'a> Socks5<'a> {
    pub fn new(host: &'a str, port: u16) -> Socks5 {
        Socks5 {
            socks_host: host,
            socks_port: port,
            socks_auth: NoAuth
        }
    }

    pub fn login(&mut self, uname: &'a str, passwd: &'a str) {
        self.socks_auth = UPass(uname, passwd);
    }

    pub fn connect<T: Socks5Destination>(&mut self, destination: T, port: u16)
                                                        -> IoResult<TcpStream> {
        let mut stream = try!(TcpStream::connect(self.socks_host, self.socks_port));
        try!(stream.write([0x05u8]));
        match self.socks_auth {
            NoAuth => { try!(stream.write([0x01u8, 0x00])); },
            UPass(..) => { try!(stream.write([0x01u8, 0x02])); }
        }

        if try!(stream.read_u8()) != 0x05 {
            return io_err(OtherIoError, "Unexpected SOCKS version number");
        }

        match try!(stream.read_u8()) {
            0x00 => {
                match self.socks_auth {
                    NoAuth => { /* Continue */ },
                    _ => return io_err(OtherIoError,
                        "Wrong authentication method from server")
                }
            }
            0x02 => {
                match self.socks_auth {
                    UPass(uname, passwd) => {
                        try!(stream.write([0x01u8, uname.len() as u8]));
                        try!(stream.write_str(uname));
                        try!(stream.write([passwd.len() as u8]));
                        try!(stream.write_str(passwd));

                        if try!(stream.read_u8()) != 0x01 {
                            return io_err(OtherIoError,
                                "Invalid authentication version");
                        }

                        if try!(stream.read_u8()) != 0x00 {
                            return io_err(ConnectionRefused, "Authentication failed");
                        }
                    }
                    _ => { return io_err(OtherIoError,
                            "Wrong authentication method from server");
                    }
                }
            }
            0xFF => { return io_err(ConnectionRefused,
                      "Server refused authentication methods"); }
            _ => { return io_err(OtherIoError,
                    "Wrong authentication method from server"); }
        }

        try!(stream.write([0x05u8, 0x01, 0x00]));
        try!(destination.write_destination(&mut stream));
        try!(stream.write_be_u16(port));

        if try!(stream.read_u8()) != 0x05 {
            return io_err(OtherIoError, "Invalid SOCKS version number");
        }

        match try!(stream.read_u8()) {
            0x00 => {
                let _null = try!(stream.read_u8());

                match try!(stream.read_u8()) {
                    0x01 => {
                        let mut _ipv4 = [0,.. 4];
                        try!(stream.read_at_least(4, &mut _ipv4));
                    }
                    0x03 => {
                        let addrlen = try!(stream.read_u8());
                        let _domain = try!(stream.read_exact(addrlen as uint));
                    }
                    0x04 => {
                        let mut _ipv6 = [0,.. 16];
                        try!(stream.read_at_least(16, &mut _ipv6));
                    }
                    _ => return io_err(OtherIoError, "Invalid address type"),
                }

                let _port = try!(stream.read_be_u16());
                Ok(stream)
            }
            0x01 => io_err(OtherIoError, "General failure"),
            0x02 => io_err(OtherIoError, "Connection not allowed by ruleset"),
            0x03 => io_err(ConnectionFailed, "Network unreachable"),
            0x04 => io_err(ConnectionFailed, "Host unreachable"),
            0x05 => io_err(ConnectionRefused, "Connection refused by destination"),
            0x06 => io_err(ConnectionFailed, "TTL expired"),
            0x07 => io_err(OtherIoError, "Protocol Error"),
            0x08 => io_err(OtherIoError, "Address type not supported"),
            _ => io_err(OtherIoError, "Unknown error")
        }
    }
}

fn io_err<T>(kind: IoErrorKind, desc: &'static str) -> IoResult<T> {
    Err(IoError { kind: kind, desc: desc, detail: None })
}
<|endoftext|>


<commit_before>use crate::error::*;

use crate::buffer::Buffered;
use std::any::Any;
use std::io::SeekFrom;
use std::sync::Arc;

use crate::common::*;

use crate::data::packet::Packet;
use crate::stream::Stream;

/// Events processed by a demuxer analyzing a source.
#[non_exhaustive]
#[derive(Clone, Debug)]
pub enum Event {
    /// A new packet is found by a demuxer.
    NewPacket(Packet),
    /// A new stream is found by a demuxer.
    NewStream(Stream),
    /// More data are needed by a demuxer to complete its operations.
    MoreDataNeeded(usize),
    /// Event not processable by a demuxer.
    ///
    /// Demux the next event.
    Continue,
    /// End of File.
    ///
    /// Stop demuxing data.
    Eof,
}

/// Used to implement demuxing operations.
pub trait Demuxer: Send + Sync {
    /// Reads stream headers and global information from a data structure
    /// implementing the `Buffered` trait.
    ///
    /// Global information are saved into a `GlobalInfo` structure.
    fn read_headers(&mut self, buf: &mut dyn Buffered, info: &mut GlobalInfo) -> Result<SeekFrom>;
    /// Reads an event from a data structure implementing the `Buffered` trait.
    fn read_event(&mut self, buf: &mut dyn Buffered) -> Result<(SeekFrom, Event)>;
}

/// Auxiliary structure to encapsulate a demuxer object and
/// its additional data.
pub struct Context<D: Demuxer, R: Buffered> {
    demuxer: D,
    reader: R,
    /// Global media file information.
    pub info: GlobalInfo,
    /// User private data.
    ///
    /// This data cannot be cloned.
    pub user_private: Option<Arc<dyn Any + Send + Sync>>,
}

impl<D: Demuxer, R: Buffered> Context<D, R> {
    /// Creates a new `Context` instance.
    pub fn new(demuxer: D, reader: R) -> Self {
        Context {
            demuxer,
            reader,
            info: GlobalInfo {
                duration: None,
                timebase: None,
                streams: Vec::with_capacity(2),
            },
            user_private: None,
        }
    }

    /// Returns the underlying demuxer.
    pub fn demuxer(&self) -> &D {
        &self.demuxer
    }

    fn read_headers_internal(&mut self) -> Result<()> {
        let demux = &mut self.demuxer;

        let res = demux.read_headers(&mut self.reader, &mut self.info);
        match res {
            Err(e) => Err(e),
            Ok(seek) => {
                //TODO: handle seeking here
                let res = self.reader.seek(seek);
                trace!("stream now at index: {:?}", res);
                Ok(())
            }
        }
    }

    /// Reads stream headers and global information from a data source.
    pub fn read_headers(&mut self) -> Result<()> {
        loop {
            // TODO: wrap fill_buf() with a check for Eof
            self.reader.fill_buf()?;
            match self.read_headers_internal() {
                Err(e) => match e {
                    Error::MoreDataNeeded(needed) => {
                        self.reader.grow(needed);
                    }
                    _ => return Err(e),
                },
                Ok(_) => return Ok(()),
            }
        }
    }

    fn read_event_internal(&mut self) -> Result<Event> {
        let demux = &mut self.demuxer;

        let res = demux.read_event(&mut self.reader);
        match res {
            Err(e) => Err(e),
            Ok((seek, mut event)) => {
                //TODO: handle seeking here
                let _ = self.reader.seek(seek)?;
                if let Event::NewStream(ref st) = event {
                    self.info.streams.push(st.clone());
                }
                if let Event::MoreDataNeeded(size) = event {
                    return Err(Error::MoreDataNeeded(size));
                }
                if let Event::NewPacket(ref mut pkt) = event {
                    if pkt.t.timebase.is_none() {
                        if let Some(st) = self
                            .info
                            .streams
                            .iter()
                            .find(|s| s.index as isize == pkt.stream_index)
                        {
                            pkt.t.timebase = Some(st.timebase);
                        }
                    }
                }
                Ok(event)
            }
        }
    }

    /// Reads an event from a data source.
    pub fn read_event(&mut self) -> Result<Event> {
        // TODO: guard against infiniloops and maybe factor the loop.
        loop {
            match self.read_event_internal() {
                Err(e) => match e {
                    Error::MoreDataNeeded(needed) => {
                        let len = self.reader.data().len();

                        // we might have sent MoreDatNeeded(0) to request a new call
                        if len >= needed {
                            continue;
                        }
                        self.reader.grow(needed);
                        self.reader.fill_buf()?;
                        if self.reader.data().len() <= len {
                            return Ok(Event::Eof);
                        }
                    }
                    _ => return Err(e),
                },
                Ok(ev) => return Ok(ev),
            }
        }
    }
}

/// Format descriptor.
///
/// Contains information on a format and its own demuxer.
#[derive(Clone, Debug, PartialEq)]
pub struct Descr {
    /// Format name.
    pub name: &'static str,
    /// Demuxer name.
    pub demuxer: &'static str,
    /// Format description.
    pub description: &'static str,
    /// Format media file extensions.
    pub extensions: &'static [&'static str],
    /// Format MIME.
    pub mime: &'static [&'static str],
}

/// Used to get a format descriptor and create a new demuxer.
pub trait Descriptor {
    type OutputDemuxer: Demuxer;

    /// Creates a new demuxer for the requested format.
    fn create(&self) -> Self::OutputDemuxer;
    /// Returns the descriptor of a format.
    fn describe(&self) -> &Descr;

    /// Returns a score which represents how much the input data are associated
    /// to a format.
    fn probe(&self, data: &[u8]) -> u8;
}

/// Maximum data size to probe a format.
pub const PROBE_DATA: usize = 4 * 1024;

/// Data whose probe score is equal or greater than the value of this constant
/// surely is associated to the format currently being analyzed.
pub const PROBE_SCORE_EXTENSION: u8 = 50;

/// Used to define different ways to probe a format.
pub trait Probe<T: Descriptor + ?Sized> {
    /// Probes whether the input data is associated to a determined format.
    fn probe(&self, data: &[u8]) -> Option<&'static T>;
}

impl<'a, T: Descriptor + ?Sized> Probe<T> for [&'static T] {
    fn probe(&self, data: &[u8]) -> Option<&'static T> {
        let mut max = u8::min_value();
        let mut candidate: Option<&'static T> = None;
        for desc in self {
            let score = desc.probe(data);

            if score > max {
                max = score;
                candidate = Some(*desc);
            }
        }

        if max > PROBE_SCORE_EXTENSION {
            candidate
        } else {
            None
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::data::packet::Packet;
    use std::io::SeekFrom;

    struct DummyDes {
        d: Descr,
    }

    struct DummyDemuxer {}

    impl Demuxer for DummyDemuxer {
        fn read_headers(
            &mut self,
            buf: &mut dyn Buffered,
            _info: &mut GlobalInfo,
        ) -> Result<SeekFrom> {
            let len = buf.data().len();
            if 9 > len {
                let needed = 9 - len;
                Err(Error::MoreDataNeeded(needed))
            } else {
                Ok(SeekFrom::Current(9))
            }
        }
        fn read_event(&mut self, buf: &mut dyn Buffered) -> Result<(SeekFrom, Event)> {
            let size = 2;
            let len = buf.data().len();
            if size > len {
                Err(Error::MoreDataNeeded(size - len))
            } else {
                debug!("{:?}", buf.data());
                match &buf.data()[..2] {
                    b"p1" => Ok((SeekFrom::Current(3), Event::NewPacket(Packet::new()))),
                    b"e1" => Ok((SeekFrom::Current(3), Event::MoreDataNeeded(0))),
                    _ => Err(Error::InvalidData),
                }
            }
        }
    }

    impl Descriptor for DummyDes {
        type OutputDemuxer = DummyDemuxer;

        fn create(&self) -> Self::OutputDemuxer {
            DummyDemuxer {}
        }
        fn describe<'a>(&'_ self) -> &'_ Descr {
            &self.d
        }
        fn probe(&self, data: &[u8]) -> u8 {
            match data {
                b"dummy" => 100,
                _ => 0,
            }
        }
    }

    const DUMMY_DES: &dyn Descriptor<OutputDemuxer = DummyDemuxer> = &DummyDes {
        d: Descr {
            name: "dummy",
            demuxer: "dummy",
            description: "Dummy dem",
            extensions: &["dm", "dum"],
            mime: &["application/dummy"],
        },
    };

    #[test]
    fn probe() {
        let demuxers: &[&'static dyn Descriptor<OutputDemuxer = DummyDemuxer>] = &[DUMMY_DES];

        demuxers.probe(b"dummy").unwrap();
    }

    use crate::buffer::*;
    use std::io::Cursor;

    #[test]
    fn read_headers() {
        let buf = b"dummy header";
        let r = AccReader::with_capacity(4, Cursor::new(buf));
        let d = DUMMY_DES.create();
        let mut c = Context::new(d, r);

        c.read_headers().unwrap();
    }

    #[test]
    fn read_event() {
        let buf = b"dummy header p1 e1 p1 ";

        let r = AccReader::with_capacity(4, Cursor::new(buf));
        let d = DUMMY_DES.create();
        let mut c = Context::new(d, r);

        c.read_headers().unwrap();

        println!("{:?}", c.read_event());
        println!("{:?}", c.read_event());
        println!("{:?}", c.read_event());
        println!("{:?}", c.read_event());
    }
}
<commit_msg>format: Remove a useless lifetime<commit_after>use crate::error::*;

use crate::buffer::Buffered;
use std::any::Any;
use std::io::SeekFrom;
use std::sync::Arc;

use crate::common::*;

use crate::data::packet::Packet;
use crate::stream::Stream;

/// Events processed by a demuxer analyzing a source.
#[non_exhaustive]
#[derive(Clone, Debug)]
pub enum Event {
    /// A new packet is found by a demuxer.
    NewPacket(Packet),
    /// A new stream is found by a demuxer.
    NewStream(Stream),
    /// More data are needed by a demuxer to complete its operations.
    MoreDataNeeded(usize),
    /// Event not processable by a demuxer.
    ///
    /// Demux the next event.
    Continue,
    /// End of File.
    ///
    /// Stop demuxing data.
    Eof,
}

/// Used to implement demuxing operations.
pub trait Demuxer: Send + Sync {
    /// Reads stream headers and global information from a data structure
    /// implementing the `Buffered` trait.
    ///
    /// Global information are saved into a `GlobalInfo` structure.
    fn read_headers(&mut self, buf: &mut dyn Buffered, info: &mut GlobalInfo) -> Result<SeekFrom>;
    /// Reads an event from a data structure implementing the `Buffered` trait.
    fn read_event(&mut self, buf: &mut dyn Buffered) -> Result<(SeekFrom, Event)>;
}

/// Auxiliary structure to encapsulate a demuxer object and
/// its additional data.
pub struct Context<D: Demuxer, R: Buffered> {
    demuxer: D,
    reader: R,
    /// Global media file information.
    pub info: GlobalInfo,
    /// User private data.
    ///
    /// This data cannot be cloned.
    pub user_private: Option<Arc<dyn Any + Send + Sync>>,
}

impl<D: Demuxer, R: Buffered> Context<D, R> {
    /// Creates a new `Context` instance.
    pub fn new(demuxer: D, reader: R) -> Self {
        Context {
            demuxer,
            reader,
            info: GlobalInfo {
                duration: None,
                timebase: None,
                streams: Vec::with_capacity(2),
            },
            user_private: None,
        }
    }

    /// Returns the underlying demuxer.
    pub fn demuxer(&self) -> &D {
        &self.demuxer
    }

    fn read_headers_internal(&mut self) -> Result<()> {
        let demux = &mut self.demuxer;

        let res = demux.read_headers(&mut self.reader, &mut self.info);
        match res {
            Err(e) => Err(e),
            Ok(seek) => {
                //TODO: handle seeking here
                let res = self.reader.seek(seek);
                trace!("stream now at index: {:?}", res);
                Ok(())
            }
        }
    }

    /// Reads stream headers and global information from a data source.
    pub fn read_headers(&mut self) -> Result<()> {
        loop {
            // TODO: wrap fill_buf() with a check for Eof
            self.reader.fill_buf()?;
            match self.read_headers_internal() {
                Err(e) => match e {
                    Error::MoreDataNeeded(needed) => {
                        self.reader.grow(needed);
                    }
                    _ => return Err(e),
                },
                Ok(_) => return Ok(()),
            }
        }
    }

    fn read_event_internal(&mut self) -> Result<Event> {
        let demux = &mut self.demuxer;

        let res = demux.read_event(&mut self.reader);
        match res {
            Err(e) => Err(e),
            Ok((seek, mut event)) => {
                //TODO: handle seeking here
                let _ = self.reader.seek(seek)?;
                if let Event::NewStream(ref st) = event {
                    self.info.streams.push(st.clone());
                }
                if let Event::MoreDataNeeded(size) = event {
                    return Err(Error::MoreDataNeeded(size));
                }
                if let Event::NewPacket(ref mut pkt) = event {
                    if pkt.t.timebase.is_none() {
                        if let Some(st) = self
                            .info
                            .streams
                            .iter()
                            .find(|s| s.index as isize == pkt.stream_index)
                        {
                            pkt.t.timebase = Some(st.timebase);
                        }
                    }
                }
                Ok(event)
            }
        }
    }

    /// Reads an event from a data source.
    pub fn read_event(&mut self) -> Result<Event> {
        // TODO: guard against infiniloops and maybe factor the loop.
        loop {
            match self.read_event_internal() {
                Err(e) => match e {
                    Error::MoreDataNeeded(needed) => {
                        let len = self.reader.data().len();

                        // we might have sent MoreDatNeeded(0) to request a new call
                        if len >= needed {
                            continue;
                        }
                        self.reader.grow(needed);
                        self.reader.fill_buf()?;
                        if self.reader.data().len() <= len {
                            return Ok(Event::Eof);
                        }
                    }
                    _ => return Err(e),
                },
                Ok(ev) => return Ok(ev),
            }
        }
    }
}

/// Format descriptor.
///
/// Contains information on a format and its own demuxer.
#[derive(Clone, Debug, PartialEq)]
pub struct Descr {
    /// Format name.
    pub name: &'static str,
    /// Demuxer name.
    pub demuxer: &'static str,
    /// Format description.
    pub description: &'static str,
    /// Format media file extensions.
    pub extensions: &'static [&'static str],
    /// Format MIME.
    pub mime: &'static [&'static str],
}

/// Used to get a format descriptor and create a new demuxer.
pub trait Descriptor {
    type OutputDemuxer: Demuxer;

    /// Creates a new demuxer for the requested format.
    fn create(&self) -> Self::OutputDemuxer;
    /// Returns the descriptor of a format.
    fn describe(&self) -> &Descr;

    /// Returns a score which represents how much the input data are associated
    /// to a format.
    fn probe(&self, data: &[u8]) -> u8;
}

/// Maximum data size to probe a format.
pub const PROBE_DATA: usize = 4 * 1024;

/// Data whose probe score is equal or greater than the value of this constant
/// surely is associated to the format currently being analyzed.
pub const PROBE_SCORE_EXTENSION: u8 = 50;

/// Used to define different ways to probe a format.
pub trait Probe<T: Descriptor + ?Sized> {
    /// Probes whether the input data is associated to a determined format.
    fn probe(&self, data: &[u8]) -> Option<&'static T>;
}

impl<T: Descriptor + ?Sized> Probe<T> for [&'static T] {
    fn probe(&self, data: &[u8]) -> Option<&'static T> {
        let mut max = u8::min_value();
        let mut candidate: Option<&'static T> = None;
        for desc in self {
            let score = desc.probe(data);

            if score > max {
                max = score;
                candidate = Some(*desc);
            }
        }

        if max > PROBE_SCORE_EXTENSION {
            candidate
        } else {
            None
        }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use crate::data::packet::Packet;
    use std::io::SeekFrom;

    struct DummyDes {
        d: Descr,
    }

    struct DummyDemuxer {}

    impl Demuxer for DummyDemuxer {
        fn read_headers(
            &mut self,
            buf: &mut dyn Buffered,
            _info: &mut GlobalInfo,
        ) -> Result<SeekFrom> {
            let len = buf.data().len();
            if 9 > len {
                let needed = 9 - len;
                Err(Error::MoreDataNeeded(needed))
            } else {
                Ok(SeekFrom::Current(9))
            }
        }
        fn read_event(&mut self, buf: &mut dyn Buffered) -> Result<(SeekFrom, Event)> {
            let size = 2;
            let len = buf.data().len();
            if size > len {
                Err(Error::MoreDataNeeded(size - len))
            } else {
                debug!("{:?}", buf.data());
                match &buf.data()[..2] {
                    b"p1" => Ok((SeekFrom::Current(3), Event::NewPacket(Packet::new()))),
                    b"e1" => Ok((SeekFrom::Current(3), Event::MoreDataNeeded(0))),
                    _ => Err(Error::InvalidData),
                }
            }
        }
    }

    impl Descriptor for DummyDes {
        type OutputDemuxer = DummyDemuxer;

        fn create(&self) -> Self::OutputDemuxer {
            DummyDemuxer {}
        }
        fn describe<'a>(&'_ self) -> &'_ Descr {
            &self.d
        }
        fn probe(&self, data: &[u8]) -> u8 {
            match data {
                b"dummy" => 100,
                _ => 0,
            }
        }
    }

    const DUMMY_DES: &dyn Descriptor<OutputDemuxer = DummyDemuxer> = &DummyDes {
        d: Descr {
            name: "dummy",
            demuxer: "dummy",
            description: "Dummy dem",
            extensions: &["dm", "dum"],
            mime: &["application/dummy"],
        },
    };

    #[test]
    fn probe() {
        let demuxers: &[&'static dyn Descriptor<OutputDemuxer = DummyDemuxer>] = &[DUMMY_DES];

        demuxers.probe(b"dummy").unwrap();
    }

    use crate::buffer::*;
    use std::io::Cursor;

    #[test]
    fn read_headers() {
        let buf = b"dummy header";
        let r = AccReader::with_capacity(4, Cursor::new(buf));
        let d = DUMMY_DES.create();
        let mut c = Context::new(d, r);

        c.read_headers().unwrap();
    }

    #[test]
    fn read_event() {
        let buf = b"dummy header p1 e1 p1 ";

        let r = AccReader::with_capacity(4, Cursor::new(buf));
        let d = DUMMY_DES.create();
        let mut c = Context::new(d, r);

        c.read_headers().unwrap();

        println!("{:?}", c.read_event());
        println!("{:?}", c.read_event());
        println!("{:?}", c.read_event());
        println!("{:?}", c.read_event());
    }
}
<|endoftext|>


<commit_before>use std::ops::{Deref, DerefMut};
use std::mem;
use std::collections::HashMap;

#[derive(Debug)]
pub enum GraphProperty {
    Int(i64),
    Float(f64),
    String(String),
}

use edge::{Edge,EdgeProxy};

/*
* storing in & out edges seperately should cut down on the number of "things" i have to traverse
* if a vertex has 10k edges (5k in and out 5k out) then doing something like*   g(v).outV()
* should be ok
*/
#[derive(Debug)]
pub struct Vertex {
    pub id: i64,
    pub properties: HashMap<String, GraphProperty>,
    // pointers on both sides, yay
    pub out_edges: Vec<*mut Edge>,
    pub in_edges:  Vec<*mut Edge>,
}

impl Vertex {
    pub fn new(id: i64) -> Box<Vertex> {
        let mut props  = HashMap::new();
        Box::new(Vertex{id:id,
                        properties: props,
                        out_edges: Vec::new(),
                        in_edges: Vec::new()})
    }

}

pub struct VertexProxy {
    pub id: i64,
    pub v: *mut Vertex,
}

impl VertexProxy {

	pub fn new(v: *mut Vertex) {

	}

    pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) -> EdgeProxy {
        let in_vertex: &mut Vertex;
        let out_vertex: &mut Vertex;

        unsafe {
            in_vertex =  &mut *(self.v);
            out_vertex = &mut *(to_vertex.v);
        }

        // create the edge
        let e = Box::new(Edge{from_vertex: self.v, to_vertex: to_vertex.v});

        // keep it on the heap but manage it myself
        let edge: *mut Edge = unsafe { mem::transmute(e) };

        in_vertex.out_edges.push(edge);
        out_vertex.in_edges.push(edge);
        EdgeProxy{edge:edge}
    }

    pub fn set_property(&mut self, field: String, value: GraphProperty) {
        self.properties.insert(field, value);
    }

    pub fn get_property(&self, field:String) -> Option<&GraphProperty> {
        self.properties.get(&field)
    }

    pub fn query(self) {
        unimplemented!()
    }

	/* basic traversal operations
	   cannot be chained
	   look at traversal.rs for breadth first chaining
	*/

	/* returns all the outV vertex proxies
	   mainly for internal use
	*/
	pub fn outV(&self) -> Vec<VertexProxy> {
		let mut result = Vec::new();
		unsafe {
			for x in self.out_edges.iter() {
				let edge: Edge = mem::transmute(x);
				let vertex: Vertex = mem::transmute(edge.to_vertex);
//				let vertex = edge.to_vertex.as_mut().unwrap();
				let proxy = VertexProxy{id:vertex.id, v:edge.to_vertex};
				result.push(proxy);
			}
			result
		}
	}
}

impl Deref for VertexProxy {
    type Target = Vertex;

    fn deref<'a>(&'a self) -> &'a Vertex {
        unsafe {
            &*(self.v)
        }
    }
}

impl DerefMut for VertexProxy {
    fn deref_mut<'a>(&'a mut self) -> &'a mut Vertex {
        unsafe {
            &mut *(self.v)
        }
    }
}

<commit_msg>removed dead code<commit_after>use std::ops::{Deref, DerefMut};
use std::mem;
use std::collections::HashMap;

#[derive(Debug)]
pub enum GraphProperty {
    Int(i64),
    Float(f64),
    String(String),
}

use edge::{Edge,EdgeProxy};

/*
* storing in & out edges seperately should cut down on the number of "things" i have to traverse
* if a vertex has 10k edges (5k in and out 5k out) then doing something like*   g(v).outV()
* should be ok
*/
#[derive(Debug)]
pub struct Vertex {
    pub id: i64,
    pub properties: HashMap<String, GraphProperty>,
    // pointers on both sides, yay
    pub out_edges: Vec<*mut Edge>,
    pub in_edges:  Vec<*mut Edge>,
}

impl Vertex {
    pub fn new(id: i64) -> Box<Vertex> {
        let mut props  = HashMap::new();
        Box::new(Vertex{id:id,
                        properties: props,
                        out_edges: Vec::new(),
                        in_edges: Vec::new()})
    }

}

pub struct VertexProxy {
    pub id: i64,
    pub v: *mut Vertex,
}

impl VertexProxy {

	pub fn new(v: *mut Vertex) {

	}

    pub fn add_edge(&mut self, to_vertex: &mut VertexProxy) -> EdgeProxy {
        let in_vertex: &mut Vertex;
        let out_vertex: &mut Vertex;

        unsafe {
            in_vertex =  &mut *(self.v);
            out_vertex = &mut *(to_vertex.v);
        }

        // create the edge
        let e = Box::new(Edge{from_vertex: self.v, to_vertex: to_vertex.v});

        // keep it on the heap but manage it myself
        let edge: *mut Edge = unsafe { mem::transmute(e) };

        in_vertex.out_edges.push(edge);
        out_vertex.in_edges.push(edge);
        EdgeProxy{edge:edge}
    }

    pub fn set_property(&mut self, field: String, value: GraphProperty) {
        self.properties.insert(field, value);
    }

    pub fn get_property(&self, field:String) -> Option<&GraphProperty> {
        self.properties.get(&field)
    }

    pub fn query(self) {
        unimplemented!()
    }

	/* basic traversal operations
	   cannot be chained
	   look at traversal.rs for breadth first chaining
	*/

	/* returns all the outV vertex proxies
	   mainly for internal use
	*/
	pub fn outV(&self) -> Vec<VertexProxy> {
		let mut result = Vec::new();
		unsafe {
			for x in self.out_edges.iter() {
				let edge: Edge = mem::transmute(x);
				let vertex: Vertex = mem::transmute(edge.to_vertex);
				let proxy = VertexProxy{id:vertex.id, v:edge.to_vertex};
				result.push(proxy);
			}
			result
		}
	}
}

impl Deref for VertexProxy {
    type Target = Vertex;

    fn deref<'a>(&'a self) -> &'a Vertex {
        unsafe {
            &*(self.v)
        }
    }
}

impl DerefMut for VertexProxy {
    fn deref_mut<'a>(&'a mut self) -> &'a mut Vertex {
        unsafe {
            &mut *(self.v)
        }
    }
}

<|endoftext|>


<commit_before>use alloc::heap;
use std::mem::{align_of, size_of};
use std::ops::{Deref, DerefMut};
use std::{self, fmt, ptr, slice};

use class::Class;

pub const DISPLAY_SIZE: usize = 6;

pub struct VTableBox<'ast>(*mut VTable <'ast>);

impl<'ast> VTableBox<'ast> {
    pub fn new(classptr: *mut Class<'ast>, entries: &[usize]) -> VTableBox<'ast> {
        let size = VTable::size_of(entries.len());
        let vtable = VTable {
            classptr: classptr,
            subtype_depth: 0,
            subtype_display: [ptr::null(); DISPLAY_SIZE],
            subtype_overflow: ptr::null(),
            table_length: entries.len(),
            table: [0],
        };

        unsafe {
            let ptr = heap::allocate(size, align_of::<VTable<'ast>>()) as *mut VTable<'ast>;
            ptr::write(ptr, vtable);

            ptr::copy(entries.as_ptr(), &mut (&mut *ptr).table[0], entries.len());

            VTableBox(ptr)
        }
    }
}

impl<'ast> fmt::Debug for VTableBox<'ast> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let vtable = self.deref();

        vtable.fmt(f)
    }
}

impl<'ast> Deref for VTableBox<'ast> {
    type Target = VTable<'ast>;

    fn deref(&self) -> &VTable<'ast> {
        unsafe { &*self.0 }
    }
}

impl<'ast> DerefMut for VTableBox<'ast> {
    fn deref_mut(&mut self) -> &mut VTable<'ast> {
        unsafe { &mut *self.0 }
    }
}

impl<'ast> Drop for VTableBox<'ast> {
    fn drop(&mut self) {
        unsafe {
            let len = (&*self.0).table_length;
            ptr::drop_in_place(self.0);

            heap::deallocate(self.0 as *mut u8, VTable::size_of(len),
                             align_of::<VTable<'ast>>());
        }
    }
}

#[derive(Debug)]
pub struct VTable<'ast> {
    pub classptr: *mut Class<'ast>,
    pub subtype_depth: i32,
    pub subtype_display: [*const VTable<'ast>; DISPLAY_SIZE],
    pub subtype_overflow: *const VTable<'ast>,
    pub table_length: usize,
    pub table: [usize; 1],
}

impl<'ast> VTable<'ast> {
    pub fn size_of(table_length: usize) -> usize {
        std::mem::size_of::<VTable>() + table_length * std::mem::size_of::<usize>()
    }

    pub fn classptr(&self) -> *mut Class<'ast> {
        self.classptr
    }

    pub fn class(&self) -> &mut Class<'ast> {
        unsafe { &mut *self.classptr }
    }

    pub fn table(&self) -> &[usize] {
        let ptr: *const usize = self.table.as_ptr();

        unsafe {
            slice::from_raw_parts(ptr, self.table_length)
        }
    }

    pub fn table_mut(&self) -> &mut [usize] {
        let ptr = self.table.as_ptr() as *mut usize;

        unsafe {
            slice::from_raw_parts_mut(ptr, self.table_length)
        }
    }

    pub fn offset_of_depth() -> i32 {
        offset_of!(VTable, subtype_depth) as i32

    }

    pub fn offset_of_display() -> i32 {
        offset_of!(VTable, subtype_display) as i32
    }

    pub fn offset_of_method_table() -> i32 {
        size_of::<VTable>() as i32
    }

    pub fn offset_of_overflow() -> i32 {
        offset_of!(VTable, subtype_overflow) as i32
    }

    pub fn get_subtype_overflow(&self, ind: usize) -> *const VTable<'ast> {
        assert!(self.subtype_depth as usize >= DISPLAY_SIZE &&
                ind < self.subtype_depth as usize - DISPLAY_SIZE + 1);

        unsafe {
            let ptr = self.subtype_overflow.offset(ind as isize) as *mut _;

            *ptr
        }
    }

    pub fn allocate_overflow(&mut self, num: usize) {
        assert!(self.subtype_overflow.is_null());

        unsafe {
            self.subtype_overflow = heap::allocate(num * size_of::<*const VTable<'ast>>(),
                                                   align_of::<*const VTable<'ast>>()) as *mut VTable<'ast>;
        }
    }

    pub fn deallocate_overflow(&mut self, num: usize) {
        unsafe {
            heap::deallocate(self.subtype_overflow as *const u8 as *mut u8,
                             num * size_of::<*const VTable<'ast>>(),
                             align_of::<*const VTable<'ast>>());
        }
    }
}

impl<'ast> Drop for VTable<'ast> {
    fn drop(&mut self) {
        if !self.subtype_overflow.is_null() {
            let elems = self.subtype_depth as usize - DISPLAY_SIZE + 1;
            self.deallocate_overflow(elems);
        }
    }
}
<commit_msg>fix: offset_of_method_table<commit_after>use alloc::heap;
use std::mem::{align_of, size_of};
use std::ops::{Deref, DerefMut};
use std::{self, fmt, ptr, slice};

use class::Class;

pub const DISPLAY_SIZE: usize = 6;

pub struct VTableBox<'ast>(*mut VTable <'ast>);

impl<'ast> VTableBox<'ast> {
    pub fn new(classptr: *mut Class<'ast>, entries: &[usize]) -> VTableBox<'ast> {
        let size = VTable::size_of(entries.len());
        let vtable = VTable {
            classptr: classptr,
            subtype_depth: 0,
            subtype_display: [ptr::null(); DISPLAY_SIZE],
            subtype_overflow: ptr::null(),
            table_length: entries.len(),
            table: [0],
        };

        unsafe {
            let ptr = heap::allocate(size, align_of::<VTable<'ast>>()) as *mut VTable<'ast>;
            ptr::write(ptr, vtable);

            ptr::copy(entries.as_ptr(), &mut (&mut *ptr).table[0], entries.len());

            VTableBox(ptr)
        }
    }
}

impl<'ast> fmt::Debug for VTableBox<'ast> {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        let vtable = self.deref();

        vtable.fmt(f)
    }
}

impl<'ast> Deref for VTableBox<'ast> {
    type Target = VTable<'ast>;

    fn deref(&self) -> &VTable<'ast> {
        unsafe { &*self.0 }
    }
}

impl<'ast> DerefMut for VTableBox<'ast> {
    fn deref_mut(&mut self) -> &mut VTable<'ast> {
        unsafe { &mut *self.0 }
    }
}

impl<'ast> Drop for VTableBox<'ast> {
    fn drop(&mut self) {
        unsafe {
            let len = (&*self.0).table_length;
            ptr::drop_in_place(self.0);

            heap::deallocate(self.0 as *mut u8, VTable::size_of(len),
                             align_of::<VTable<'ast>>());
        }
    }
}

#[derive(Debug)]
pub struct VTable<'ast> {
    pub classptr: *mut Class<'ast>,
    pub subtype_depth: i32,
    pub subtype_display: [*const VTable<'ast>; DISPLAY_SIZE],
    pub subtype_overflow: *const VTable<'ast>,
    pub table_length: usize,
    pub table: [usize; 1],
}

impl<'ast> VTable<'ast> {
    pub fn size_of(table_length: usize) -> usize {
        std::mem::size_of::<VTable>() + table_length * std::mem::size_of::<usize>()
    }

    pub fn classptr(&self) -> *mut Class<'ast> {
        self.classptr
    }

    pub fn class(&self) -> &mut Class<'ast> {
        unsafe { &mut *self.classptr }
    }

    pub fn table(&self) -> &[usize] {
        let ptr: *const usize = self.table.as_ptr();

        unsafe {
            slice::from_raw_parts(ptr, self.table_length)
        }
    }

    pub fn table_mut(&self) -> &mut [usize] {
        let ptr = self.table.as_ptr() as *mut usize;

        unsafe {
            slice::from_raw_parts_mut(ptr, self.table_length)
        }
    }

    pub fn offset_of_depth() -> i32 {
        offset_of!(VTable, subtype_depth) as i32

    }

    pub fn offset_of_display() -> i32 {
        offset_of!(VTable, subtype_display) as i32
    }

    pub fn offset_of_method_table() -> i32 {
        offset_of!(VTable, table) as i32
    }

    pub fn offset_of_overflow() -> i32 {
        offset_of!(VTable, subtype_overflow) as i32
    }

    pub fn get_subtype_overflow(&self, ind: usize) -> *const VTable<'ast> {
        assert!(self.subtype_depth as usize >= DISPLAY_SIZE &&
                ind < self.subtype_depth as usize - DISPLAY_SIZE + 1);

        unsafe {
            let ptr = self.subtype_overflow.offset(ind as isize) as *mut _;

            *ptr
        }
    }

    pub fn allocate_overflow(&mut self, num: usize) {
        assert!(self.subtype_overflow.is_null());

        unsafe {
            self.subtype_overflow = heap::allocate(num * size_of::<*const VTable<'ast>>(),
                                                   align_of::<*const VTable<'ast>>()) as *mut VTable<'ast>;
        }
    }

    pub fn deallocate_overflow(&mut self, num: usize) {
        unsafe {
            heap::deallocate(self.subtype_overflow as *const u8 as *mut u8,
                             num * size_of::<*const VTable<'ast>>(),
                             align_of::<*const VTable<'ast>>());
        }
    }
}

impl<'ast> Drop for VTable<'ast> {
    fn drop(&mut self) {
        if !self.subtype_overflow.is_null() {
            let elems = self.subtype_depth as usize - DISPLAY_SIZE + 1;
            self.deallocate_overflow(elems);
        }
    }
}
<|endoftext|>


<commit_before>#[deriving(Show)]
struct Vec2<T> {
    x: T,
    y: T,
}

impl<
    // Bound: `T` must implement the `Add` trait
    T: Add<T, T>
> Add<Vec2<T>, Vec2<T>>
for Vec2<T> {
    fn add(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            // `x` and `y` are of type `T`, and implement the `add` method
            x: self.x.add(&rhs.x),
            // The sugary `+` operator can also be used
            y: self.y + rhs.y,
        }
    }
}

impl<
    // Bound: `T` must implement the `Sub` trait
    T: Sub<T, T>
> Sub<Vec2<T>, Vec2<T>>
for Vec2<T> {
    fn sub(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            x: self.x - rhs.x,
            y: self.y - rhs.y,
        }
    }
}

impl<
    // Bound: `T` must implement *both* the `Add` trait and the ` ` trait
    T: Add<T, T> + Mul<T, T>
> Vec2<T> {
    fn dot(&self, rhs: &Vec2<T>) -> T {
        (self.x * rhs.x) + (self.y * rhs.y)
    }
}

fn main() {
    // Floats implement the `Add`, `Mul` and `Sub` traits
    let v1 = Vec2 { x: 1.2, y: 3.4 };
    let v2 = Vec2 { x: 5.6, y: 7.8 };

    println!("{} + {} = {}", v1, v2, v1 + v2);
    println!("{} - {} = {}", v1, v2, v1 - v2);
    println!("{} . {} = {}", v1, v2, v1.dot(&v2));

    // Error! `char` doesn't implement the `Add` trait
    println!("{}", Vec2 { x: ' ', y: 'b' } + Vec2 { x: 'c', y: 'd' });
    // FIXME ^ Comment out this line
}
<commit_msg>Added missing trait name in bounds example.<commit_after>#[deriving(Show)]
struct Vec2<T> {
    x: T,
    y: T,
}

impl<
    // Bound: `T` must implement the `Add` trait
    T: Add<T, T>
> Add<Vec2<T>, Vec2<T>>
for Vec2<T> {
    fn add(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            // `x` and `y` are of type `T`, and implement the `add` method
            x: self.x.add(&rhs.x),
            // The sugary `+` operator can also be used
            y: self.y + rhs.y,
        }
    }
}

impl<
    // Bound: `T` must implement the `Sub` trait
    T: Sub<T, T>
> Sub<Vec2<T>, Vec2<T>>
for Vec2<T> {
    fn sub(&self, rhs: &Vec2<T>) -> Vec2<T> {
        Vec2 {
            x: self.x - rhs.x,
            y: self.y - rhs.y,
        }
    }
}

impl<
    // Bound: `T` must implement *both* the `Add` trait and the `Mul` trait
    T: Add<T, T> + Mul<T, T>
> Vec2<T> {
    fn dot(&self, rhs: &Vec2<T>) -> T {
        (self.x * rhs.x) + (self.y * rhs.y)
    }
}

fn main() {
    // Floats implement the `Add`, `Mul` and `Sub` traits
    let v1 = Vec2 { x: 1.2, y: 3.4 };
    let v2 = Vec2 { x: 5.6, y: 7.8 };

    println!("{} + {} = {}", v1, v2, v1 + v2);
    println!("{} - {} = {}", v1, v2, v1 - v2);
    println!("{} . {} = {}", v1, v2, v1.dot(&v2));

    // Error! `char` doesn't implement the `Add` trait
    println!("{}", Vec2 { x: ' ', y: 'b' } + Vec2 { x: 'c', y: 'd' });
    // FIXME ^ Comment out this line
}
<|endoftext|>


<commit_before>extern crate rustc_serialize;
extern crate tantivy;
extern crate tempdir;

use std::path::Path;
use tempdir::TempDir;
use tantivy::Index;
use tantivy::schema::*;
use tantivy::collector::TopCollector;
use tantivy::query::QueryParser;
use tantivy::query::Query;

fn main() {
    // Let's create a temporary directory for the
    // sake of this example
    if let Ok(dir) = TempDir::new("tantivy_example_dir") {
        run_example(&dir.path()).unwrap();
        dir.close().unwrap();
    }
}

fn run_example(index_path: &Path) -> tantivy::Result<()> {

    // # Defining the schema
    //
    // Tantivy index require to have a very strict schema.
    // The schema declares which fields are in the index,
    // and for each field, its type and "the way it should
    // be indexed".

    // first we need to define a schema ...
    let mut schema_builder = SchemaBuilder::default();

    // Our first field is title.
    // We want full-text search for it, and we want to be able
    // to retrieve the document after the search.
    //
    // TEXT | STORED is some syntactic sugar to describe
    // that.
    //
    // `TEXT` means the field should be tokenized and indexed,
    // along with its term frequency and term positions.
    //
    // `STORED` means that the field will also be saved
    // in a compressed, row-oriented key-value store.
    // This store is useful to reconstruct the
    // document that were selected during the search phase.
    schema_builder.add_text_field("title", TEXT | STORED);

    // Our first field is body.
    // We want full-text search for it, and we want to be able
    // to retrieve the body after the search.
    schema_builder.add_text_field("body", TEXT);

    let schema = schema_builder.build();

    // # Indexing documents
    //
    // Let's create a brand new index.
    //
    // This will actually just save a meta.json
    // with our schema the directory.
    let index = try!(Index::create(index_path, schema.clone()));

    // To insert document we need an index writer.
    // There shall be only one writer at a time.
    // Besides, this single `IndexWriter` is already
    // multithreaded.
    //
    // Here we used a buffer of 1 GB. Using a bigger
    // heap for the indexer can increase its throughput.
    // This buffer will be split between the indexing
    // threads.
    let mut index_writer = try!(index.writer(1_000_000_000));

    // Let's now index our documents!
    // We first need a handle on the title and the body field.

    // ### Create a document "manually".
    //
    // We can create a document manually, by setting adding the fields
    // one by one in a Document object.
    let title = schema.get_field("title").unwrap();
    let body = schema.get_field("body").unwrap();

    let mut old_man_doc = Document::default();
    old_man_doc.add_text(title, "The Old Man and the Sea");
    old_man_doc.add_text(body, "He was an old man who fished alone in a skiff in the Gulf Stream and he had gone eighty-four days now without taking a fish.");

    // ... and add it to the `IndexWriter`.
    try!(index_writer.add_document(old_man_doc));

    // ### Create a document directly from json.
    //
    // Alternatively, we can use our schema to parse
    // a document object directly from json.

    let mice_and_men_doc = try!(schema.parse_document(r#"{
       "title": "Of Mice and Men",
       "body": "few miles south of Soledad, the Salinas River drops in close to the hillside bank and runs deep and green. The water is warm too, for it has slipped twinkling over the yellow sands in the sunlight before reaching the narrow pool. On one side of the river the golden foothill slopes curve up to the strong and rocky Gabilan Mountains, but on the valley side the water is lined with trees—willows fresh and green with every spring, carrying in their lower leaf junctures the debris of the winter’s flooding; and sycamores with mottled, white,recumbent limbs and branches that arch over the pool"
    }"#));

    try!(index_writer.add_document(mice_and_men_doc));

    // Multi-valued field are allowed, they are
    // expressed in JSON by an array.
    // The following document has two titles.
    let frankenstein_doc = try!(schema.parse_document(r#"{
       "title": ["Frankenstein", "The Modern Promotheus"],
       "body": "You will rejoice to hear that no disaster has accompanied the commencement of an enterprise which you have regarded with such evil forebodings.  I arrived here yesterday, and my first task is to assure my dear sister of my welfare and increasing confidence in the success of my undertaking."
    }"#));
    try!(index_writer.add_document(frankenstein_doc));

    // This is an example, so we will only index 3 documents
    // here. You can check out tantivy's tutorial to index
    // the English wikipedia. Tantivy's indexing is rather fast.
    // Indexing 5 millions articles of the English wikipedia takes
    // around 4 minutes on my computer!

    // ### Committing
    //
    // At this point our documents are not searchable.
    //
    //
    // We need to call .commit() explicitely to force the
    // index_writer to finish processing the documents in the queue,
    // flush the current index on the disk, and advertise
    // the existence of new documents.
    //
    // This call is blocking.
    try!(index_writer.commit());

    // If `.commit()` returns correctly, then all of the
    // documents have been added before are guaranteed to be
    // persistently indexed.
    //
    // In the scenario of a crash or a power failure,
    // tantivy behaves as if it rollbacked to its last
    // commit.

    // # Searching
    //
    // Let's search our index. This starts
    // by creating a searcher. There can be more
    // than one searcher at a time.
    //
    // You are supposed to acquire a search
    // every time you start a "search query".
    let searcher = index.searcher();

    // The query parser can interpret human queries.
    // Here, if the user does not specify which
    // field he wants to search, tantivy will search
    // in both title and body.
    let query_parser = QueryParser::new(index.schema(), vec!(title, body));

    // QueryParser may fail if the query is not in the right
    // format. For user facing applications, this can be a problem.
    // A ticket has been filled regarding this problem.
    let query = try!(query_parser.parse_query("sea whale"));

    // A query defines a set of documents, as
    // well as the way they should be scored.
    //
    // Query created by the query parser are scoring according
    // to a metric called Tf-Idf, and will consider
    // any document matching at least one of our terms.

    // ### Collectors
    //
    // We are not interested in all of the document but
    // only in the top 10. Keep track of our top 10 best documents
    // is the role of the TopCollector.

    let mut top_collector = TopCollector::with_limit(10);

    // We can now perform our query.
    try!(query.search(&searcher, &mut top_collector));

    // Our top collector now contains are 10
    // most relevant doc ids...
    let doc_addresses = top_collector.docs();

    // The actual documents still need to be
    // retrieved from Tantivy's store.
    //
    // Since body was not configured as stored,
    // the document returned will only contain
    // a title.

    for doc_address in doc_addresses {
         let retrieved_doc = try!(searcher.doc(&doc_address));
         println!("{}", schema.to_json(&retrieved_doc));
    }

    Ok(())
}<commit_msg>minor fixes to grammar and usage in example file<commit_after>extern crate rustc_serialize;
extern crate tantivy;
extern crate tempdir;

use std::path::Path;
use tempdir::TempDir;
use tantivy::Index;
use tantivy::schema::*;
use tantivy::collector::TopCollector;
use tantivy::query::QueryParser;
use tantivy::query::Query;

fn main() {
    // Let's create a temporary directory for the
    // sake of this example
    if let Ok(dir) = TempDir::new("tantivy_example_dir") {
        run_example(&dir.path()).unwrap();
        dir.close().unwrap();
    }
}

fn run_example(index_path: &Path) -> tantivy::Result<()> {

    // # Defining the schema
    //
    // The Tantivy index requires a very strict schema.
    // The schema declares which fields are in the index,
    // and for each field, its type and "the way it should
    // be indexed".

    // first we need to define a schema ...
    let mut schema_builder = SchemaBuilder::default();

    // Our first field is title.
    // We want full-text search for it, and we want to be able
    // to retrieve the document after the search.
    //
    // TEXT | STORED is some syntactic sugar to describe
    // that.
    //
    // `TEXT` means the field should be tokenized and indexed,
    // along with its term frequency and term positions.
    //
    // `STORED` means that the field will also be saved
    // in a compressed, row-oriented key-value store.
    // This store is useful to reconstruct the
    // documents that were selected during the search phase.
    schema_builder.add_text_field("title", TEXT | STORED);

    // Our first field is body.
    // We want full-text search for it, and we want to be able
    // to retrieve the body after the search.
    schema_builder.add_text_field("body", TEXT);

    let schema = schema_builder.build();

    // # Indexing documents
    //
    // Let's create a brand new index.
    //
    // This will actually just save a meta.json
    // with our schema in the directory.
    let index = try!(Index::create(index_path, schema.clone()));

    // To insert document we need an index writer.
    // There must be only one writer at a time.
    // This single `IndexWriter` is already
    // multithreaded.
    //
    // Here we use a buffer of 1 GB. Using a bigger
    // heap for the indexer can increase its throughput.
    // This buffer will be split between the indexing
    // threads.
    let mut index_writer = try!(index.writer(1_000_000_000));

    // Let's index our documents!
    // We first need a handle on the title and the body field.

    // ### Create a document "manually".
    //
    // We can create a document manually, by setting the fields
    // one by one in a Document object.
    let title = schema.get_field("title").unwrap();
    let body = schema.get_field("body").unwrap();

    let mut old_man_doc = Document::default();
    old_man_doc.add_text(title, "The Old Man and the Sea");
    old_man_doc.add_text(body, "He was an old man who fished alone in a skiff in the Gulf Stream and he had gone eighty-four days now without taking a fish.");

    // ... and add it to the `IndexWriter`.
    try!(index_writer.add_document(old_man_doc));

    // ### Create a document directly from json.
    //
    // Alternatively, we can use our schema to parse
    // a document object directly from json.

    let mice_and_men_doc = try!(schema.parse_document(r#"{
       "title": "Of Mice and Men",
       "body": "few miles south of Soledad, the Salinas River drops in close to the hillside bank and runs deep and green. The water is warm too, for it has slipped twinkling over the yellow sands in the sunlight before reaching the narrow pool. On one side of the river the golden foothill slopes curve up to the strong and rocky Gabilan Mountains, but on the valley side the water is lined with trees—willows fresh and green with every spring, carrying in their lower leaf junctures the debris of the winter’s flooding; and sycamores with mottled, white,recumbent limbs and branches that arch over the pool"
    }"#));

    try!(index_writer.add_document(mice_and_men_doc));

    // Multi-valued field are allowed, they are
    // expressed in JSON by an array.
    // The following document has two titles.
    let frankenstein_doc = try!(schema.parse_document(r#"{
       "title": ["Frankenstein", "The Modern Promotheus"],
       "body": "You will rejoice to hear that no disaster has accompanied the commencement of an enterprise which you have regarded with such evil forebodings.  I arrived here yesterday, and my first task is to assure my dear sister of my welfare and increasing confidence in the success of my undertaking."
    }"#));
    try!(index_writer.add_document(frankenstein_doc));

    // This is an example, so we will only index 3 documents
    // here. You can check out tantivy's tutorial to index
    // the English wikipedia. Tantivy's indexing is rather fast.
    // Indexing 5 million articles of the English wikipedia takes
    // around 4 minutes on my computer!

    // ### Committing
    //
    // At this point our documents are not searchable.
    //
    //
    // We need to call .commit() explicitly to force the
    // index_writer to finish processing the documents in the queue,
    // flush the current index to the disk, and advertise
    // the existence of new documents.
    //
    // This call is blocking.
    try!(index_writer.commit());

    // If `.commit()` returns correctly, then all of the
    // documents that have been added are guaranteed to be
    // persistently indexed.
    //
    // In the scenario of a crash or a power failure,
    // tantivy behaves as if has rolled back to its last
    // commit.

    // # Searching
    //
    // Let's search our index. We start
    // by creating a searcher. There can be more
    // than one searcher at a time.
    //
    // You should create a searcher
    // every time you start a "search query".
    let searcher = index.searcher();

    // The query parser can interpret human queries.
    // Here, if the user does not specify which
    // field they want to search, tantivy will search
    // in both title and body.
    let query_parser = QueryParser::new(index.schema(), vec!(title, body));

    // QueryParser may fail if the query is not in the right
    // format. For user facing applications, this can be a problem.
    // A ticket has been opened regarding this problem.
    let query = try!(query_parser.parse_query("sea whale"));

    // A query defines a set of documents, as
    // well as the way they should be scored.
    //
    // A query created by the query parser is scored according
    // to a metric called Tf-Idf, and will consider
    // any document matching at least one of our terms.

    // ### Collectors
    //
    // We are not interested in all of the documents but
    // only in the top 10. Keeping track of our top 10 best documents
    // is the role of the TopCollector.

    let mut top_collector = TopCollector::with_limit(10);

    // We can now perform our query.
    try!(query.search(&searcher, &mut top_collector));

    // Our top collector now contains the 10
    // most relevant doc ids...
    let doc_addresses = top_collector.docs();

    // The actual documents still need to be
    // retrieved from Tantivy's store.
    //
    // Since the body field was not configured as stored,
    // the document returned will only contain
    // a title.

    for doc_address in doc_addresses {
         let retrieved_doc = try!(searcher.doc(&doc_address));
         println!("{}", schema.to_json(&retrieved_doc));
    }

    Ok(())
}
<|endoftext|>


<commit_before><commit_msg>also for storage<commit_after><|endoftext|>