<commit_before>use libc::c_char;
use ffi::{core, LLVMMemoryBuffer};
use ffi::prelude::LLVMMemoryBufferRef;
use cbox::{CBox, DisposeRef};
use std::ops::Deref;
use std::mem;
use util;

pub struct MemoryBuffer;
native_ref!(&MemoryBuffer = LLVMMemoryBufferRef);
impl MemoryBuffer {
    pub fn new_from_file(path: &str) -> Result<CBox<MemoryBuffer>, CBox<str>> {
        util::with_cstr(path, |path| unsafe {
            let mut output = mem::uninitialized();
            let mut error = mem::uninitialized();
            if core::LLVMCreateMemoryBufferWithContentsOfFile(path, &mut output, &mut error) == 1 {
                Err(CBox::new(error))
            } else {
                Ok(CBox::new(output))
            }
        })
    }
}
impl Deref for MemoryBuffer {
    type Target = str;
    fn deref(&self) -> &str {
        unsafe {
            #[allow(dead_code)]
            struct StrSlice {
                data: *const c_char,
                len: usize
            }
            mem::transmute(StrSlice {
                data: core::LLVMGetBufferStart(self.into()),
                len: core::LLVMGetBufferSize(self.into()) as usize
            })
        }
    }
}
impl DisposeRef for MemoryBuffer {
    type RefTo = LLVMMemoryBuffer;
    unsafe fn dispose(ptr: LLVMMemoryBufferRef) {
        core::LLVMDisposeMemoryBuffer(ptr)
    }
}
<commit_msg>Reformat buffer.rs.<commit_after>use std::ops::Deref;
use std::mem;

use cbox::{CBox, DisposeRef};
use ffi::{core, LLVMMemoryBuffer};
use ffi::prelude::LLVMMemoryBufferRef;
use libc::c_char;

use util;

pub struct MemoryBuffer;
native_ref!(&MemoryBuffer = LLVMMemoryBufferRef);

impl MemoryBuffer
{
  pub fn new_from_file(path: &str) -> Result<CBox<MemoryBuffer>, CBox<str>>
  {
    util::with_cstr(path, |path| unsafe {
      let mut output = mem::uninitialized();
      let mut error = mem::uninitialized();
      if core::LLVMCreateMemoryBufferWithContentsOfFile(path, &mut output, &mut error) == 1 {
          Err(CBox::new(error))
      } else {
          Ok(CBox::new(output))
      }
    })
  }
}

impl Deref for MemoryBuffer
{
  type Target = str;
  fn deref(&self) -> &str {
    unsafe {
      #[allow(dead_code)]
      struct StrSlice {
        data: *const c_char,
        len: usize
      }
      mem::transmute(StrSlice {
        data: core::LLVMGetBufferStart(self.into()),
        len: core::LLVMGetBufferSize(self.into()) as usize
      })
    }
  }
}

impl DisposeRef for MemoryBuffer
{
  type RefTo = LLVMMemoryBuffer;
  unsafe fn dispose(ptr: LLVMMemoryBufferRef) {
      core::LLVMDisposeMemoryBuffer(ptr)
  }
}
<|endoftext|>


<commit_before>use calx::dijkstra::Dijkstra;
use world;
use location::{Location};
use dir6::Dir6;
use flags;
use mob;
use mob::status;
use mob::intrinsic;
use super::MobKind;
use spatial;
use action;
use fov::Fov;

/// Game object handle.
#[deriving(PartialEq, Eq, Clone, Hash, Show, Decodable, Encodable)]
pub struct Entity(pub uint);

impl Entity {
    /// Place the entity in a location in the game world.
    pub fn place(self, loc: Location) {
        world::get().borrow_mut().spatial.insert_at(self, loc);
        self.on_move_to(loc);
    }

    /// Remove the entity from all the game world systems. THE ENTITY VALUE
    /// WILL BE INVALID FROM HERE ON AND USING IT WILL LEAD TO BUGS. THE
    /// CALLER IS RESPONSIBLE FOR ENSUING THAT AN ENTITY WILL NOT BE
    /// USED FROM ANYWHERE AFTER THE DELETE OPERATION.
    pub fn delete(self) {
        // LABYRINTH OF COMPONENTS
        // This needs to call every toplevel component system.
        world::get().borrow_mut().comp.remove(self);
        world::get().borrow_mut().spatial.remove(self);
        world::get().borrow_mut().ecs.delete(self);
    }

    pub fn blocks_walk(self) -> bool { self.is_mob() }

    /// Return the kind of the entity.
    pub fn kind(self) -> ::EntityKind {
        // XXX: Will crash if an entity has no kind specified.
        *world::get().borrow().comp.kind.get(self).unwrap()
    }

// Spatial methods /////////////////////////////////////////////////////

    pub fn can_enter(self, loc: Location) -> bool {
        if self.is_mob() && loc.has_mobs() { return false; }
        if loc.blocks_walk() { return false; }
        true
    }

    /// Return whether the entity can move in a direction.
    pub fn can_step(self, dir: Dir6) -> bool {
        let place = world::get().borrow().spatial.get(self);
        if let Some(spatial::At(loc)) = place {
            let new_loc = loc + dir.to_v2();
            return self.can_enter(new_loc);
        }
        return false;
    }

    /// Try to move the entity in direction.
    pub fn step(self, dir: Dir6) {
        let place = world::get().borrow().spatial.get(self);
        if let Some(spatial::At(loc)) = place {
            let new_loc = loc + dir.to_v2();
            if self.can_enter(new_loc) {
                world::get().borrow_mut().spatial.insert_at(self, new_loc);
                self.on_move_to(new_loc);
            }
        }
    }

    pub fn location(self) -> Option<Location> {
        match world::get().borrow().spatial.get(self) {
            Some(spatial::At(loc)) => Some(loc),
            Some(spatial::In(e)) => e.location(),
            _ => None
        }
    }

    pub fn distance_from(self, other: Entity) -> Option<int> {
        if let (Some(loc1), Some(loc2)) = (self.location(), other.location()) {
            loc1.distance_from(loc2)
        } else {
            None
        }
    }

// Mob methods /////////////////////////////////////////////////////////

    pub fn is_mob(self) -> bool {
        if let Some(&MobKind(_)) = world::get().borrow().comp.kind.get(self) {
            return true;
        }
        return false;
    }

    /// Return whether this mob is the player avatar.
    pub fn is_player(self) -> bool {
        if let Some(&MobKind(mob::Player)) = world::get().borrow().comp.kind.get(self) {
            return true;
        }
        return false;
    }

    pub fn has_status(self, status: status::Status) -> bool {
        if let Some(&mob) = world::get().borrow().comp.mob.get(self) {
            return mob.has_status(status);
        }
        return false;
    }

    pub fn add_status(self, status: status::Status) {
        if !self.is_mob() { return; }
        world::get().borrow_mut().comp.mob.get_mut(self).unwrap().add_status(status);
        assert!(self.has_status(status));
    }

    pub fn remove_status(self, status: status::Status) {
        if !self.is_mob() { return; }
        world::get().borrow_mut().comp.mob.get_mut(self).unwrap().remove_status(status);
        assert!(!self.has_status(status));
    }

    pub fn has_intrinsic(self, intrinsic: mob::intrinsic::Intrinsic) -> bool {
        if let Some(&MobKind(mt)) = world::get().borrow().comp.kind.get(self) {
            return mob::SPECS[mt as uint].intrinsics & intrinsic as int != 0;
        }
        return false;
    }

    /// Return whether this entity is an awake mob.
    pub fn is_active(self) -> bool {
        self.is_mob() && !self.has_status(status::Asleep)
    }

    /// Return if the entity is a mob that should get an update this frame
    /// based on its speed properties. Does not check for status effects like
    /// sleep that might prevent actual action.
    pub fn ticks_this_frame(self) -> bool {
        if !self.is_mob() { return false; }

        let tick = flags::get_tick();
        // Go through a cycle of 5 phases to get 4 possible speeds.
        // System idea from Jeff Lait.
        let phase = tick % 5;
        match phase {
            0 => return true,
            1 => return self.has_intrinsic(intrinsic::Fast),
            2 => return true,
            3 => return self.has_status(status::Quick),
            4 => return !self.has_intrinsic(intrinsic::Slow)
                        && !self.has_status(status::Slow),
            _ => panic!("Invalid action phase"),
        }
    }

    /// Return whether the entity is a mob that will act this frame.
    pub fn acts_this_frame(self) -> bool {
        if !self.is_active() { return false; }
        return self.ticks_this_frame();
    }

    /// Return whether the entity is an awake non-player mob and should be
    /// animated with a bob.
    pub fn is_bobbing(self) -> bool {
        self.is_active() && !self.is_player()
    }

// AI methods /////////////////////////////////////////////////////////

    /// Top-level method called each frame to update the entity.
    pub fn update(self) {
        if self.is_mob() && !self.is_player() && self.ticks_this_frame() {
            self.mob_ai();
        }
    }

    /// AI routine for autonomous mobs.
    fn mob_ai(self) {
        assert!(self.is_mob());
        assert!(!self.is_player());
        assert!(self.ticks_this_frame());

        if self.has_status(status::Asleep) {
            if let Some(p) = action::player() {
                // TODO: Line-of-sight, stealth concerns, other enemies than
                // player etc.
                if let Some(d) = p.distance_from(self) {
                    if d < 6 {
                        self.remove_status(status::Asleep);
                    }
                }
            }

            return;
        }

        if let Some(p) = action::player() {
            let pathing = Dijkstra::new(vec![p.location().unwrap()], |&loc| !loc.blocks_walk(), 64);
            let loc = self.location().unwrap();

            let steps = pathing.sorted_neighbors(&loc);
            self.step(loc.dir6_towards(steps[0]).unwrap());
        }
    }

// Callbacks ///////////////////////////////////////////////////////////

    /// Called after the entity is moved to a new location.
    pub fn on_move_to(self, _loc: Location) {
        self.do_fov();
    }

// Misc ////////////////////////////////////////////////////////////////

    fn has_map_memory(self) -> bool {
        world::get().borrow().comp.map_memory.get(self).is_some()
    }

    fn do_fov(self) {
        let range = 12u;
        if let Some(loc) = self.location() {
            if self.has_map_memory() {
                let seen: Vec<Location> = Fov::new(
                    |pt| (loc + pt).blocks_sight(), range)
                    .map(|pt| loc + pt)
                    .collect();
                if let Some(ref mut mm) = world::get().borrow_mut().comp.map_memory.get_mut(self) {
                    mm.seen.clear();
                    mm.seen.extend(seen.clone().into_iter());
                    mm.remembered.extend(seen.into_iter());
                } else {
                    panic!("Couldn't bind map memory");
                }
            }
        }
    }
}
<commit_msg>Guard for path finding dead ends<commit_after>use calx::dijkstra::Dijkstra;
use world;
use location::{Location};
use dir6::Dir6;
use flags;
use mob;
use mob::status;
use mob::intrinsic;
use super::MobKind;
use spatial;
use action;
use fov::Fov;

/// Game object handle.
#[deriving(PartialEq, Eq, Clone, Hash, Show, Decodable, Encodable)]
pub struct Entity(pub uint);

impl Entity {
    /// Place the entity in a location in the game world.
    pub fn place(self, loc: Location) {
        world::get().borrow_mut().spatial.insert_at(self, loc);
        self.on_move_to(loc);
    }

    /// Remove the entity from all the game world systems. THE ENTITY VALUE
    /// WILL BE INVALID FROM HERE ON AND USING IT WILL LEAD TO BUGS. THE
    /// CALLER IS RESPONSIBLE FOR ENSUING THAT AN ENTITY WILL NOT BE
    /// USED FROM ANYWHERE AFTER THE DELETE OPERATION.
    pub fn delete(self) {
        // LABYRINTH OF COMPONENTS
        // This needs to call every toplevel component system.
        world::get().borrow_mut().comp.remove(self);
        world::get().borrow_mut().spatial.remove(self);
        world::get().borrow_mut().ecs.delete(self);
    }

    pub fn blocks_walk(self) -> bool { self.is_mob() }

    /// Return the kind of the entity.
    pub fn kind(self) -> ::EntityKind {
        // XXX: Will crash if an entity has no kind specified.
        *world::get().borrow().comp.kind.get(self).unwrap()
    }

// Spatial methods /////////////////////////////////////////////////////

    pub fn can_enter(self, loc: Location) -> bool {
        if self.is_mob() && loc.has_mobs() { return false; }
        if loc.blocks_walk() { return false; }
        true
    }

    /// Return whether the entity can move in a direction.
    pub fn can_step(self, dir: Dir6) -> bool {
        let place = world::get().borrow().spatial.get(self);
        if let Some(spatial::At(loc)) = place {
            let new_loc = loc + dir.to_v2();
            return self.can_enter(new_loc);
        }
        return false;
    }

    /// Try to move the entity in direction.
    pub fn step(self, dir: Dir6) {
        let place = world::get().borrow().spatial.get(self);
        if let Some(spatial::At(loc)) = place {
            let new_loc = loc + dir.to_v2();
            if self.can_enter(new_loc) {
                world::get().borrow_mut().spatial.insert_at(self, new_loc);
                self.on_move_to(new_loc);
            }
        }
    }

    pub fn location(self) -> Option<Location> {
        match world::get().borrow().spatial.get(self) {
            Some(spatial::At(loc)) => Some(loc),
            Some(spatial::In(e)) => e.location(),
            _ => None
        }
    }

    pub fn distance_from(self, other: Entity) -> Option<int> {
        if let (Some(loc1), Some(loc2)) = (self.location(), other.location()) {
            loc1.distance_from(loc2)
        } else {
            None
        }
    }

// Mob methods /////////////////////////////////////////////////////////

    pub fn is_mob(self) -> bool {
        if let Some(&MobKind(_)) = world::get().borrow().comp.kind.get(self) {
            return true;
        }
        return false;
    }

    /// Return whether this mob is the player avatar.
    pub fn is_player(self) -> bool {
        if let Some(&MobKind(mob::Player)) = world::get().borrow().comp.kind.get(self) {
            return true;
        }
        return false;
    }

    pub fn has_status(self, status: status::Status) -> bool {
        if let Some(&mob) = world::get().borrow().comp.mob.get(self) {
            return mob.has_status(status);
        }
        return false;
    }

    pub fn add_status(self, status: status::Status) {
        if !self.is_mob() { return; }
        world::get().borrow_mut().comp.mob.get_mut(self).unwrap().add_status(status);
        assert!(self.has_status(status));
    }

    pub fn remove_status(self, status: status::Status) {
        if !self.is_mob() { return; }
        world::get().borrow_mut().comp.mob.get_mut(self).unwrap().remove_status(status);
        assert!(!self.has_status(status));
    }

    pub fn has_intrinsic(self, intrinsic: mob::intrinsic::Intrinsic) -> bool {
        if let Some(&MobKind(mt)) = world::get().borrow().comp.kind.get(self) {
            return mob::SPECS[mt as uint].intrinsics & intrinsic as int != 0;
        }
        return false;
    }

    /// Return whether this entity is an awake mob.
    pub fn is_active(self) -> bool {
        self.is_mob() && !self.has_status(status::Asleep)
    }

    /// Return if the entity is a mob that should get an update this frame
    /// based on its speed properties. Does not check for status effects like
    /// sleep that might prevent actual action.
    pub fn ticks_this_frame(self) -> bool {
        if !self.is_mob() { return false; }

        let tick = flags::get_tick();
        // Go through a cycle of 5 phases to get 4 possible speeds.
        // System idea from Jeff Lait.
        let phase = tick % 5;
        match phase {
            0 => return true,
            1 => return self.has_intrinsic(intrinsic::Fast),
            2 => return true,
            3 => return self.has_status(status::Quick),
            4 => return !self.has_intrinsic(intrinsic::Slow)
                        && !self.has_status(status::Slow),
            _ => panic!("Invalid action phase"),
        }
    }

    /// Return whether the entity is a mob that will act this frame.
    pub fn acts_this_frame(self) -> bool {
        if !self.is_active() { return false; }
        return self.ticks_this_frame();
    }

    /// Return whether the entity is an awake non-player mob and should be
    /// animated with a bob.
    pub fn is_bobbing(self) -> bool {
        self.is_active() && !self.is_player()
    }

// AI methods /////////////////////////////////////////////////////////

    /// Top-level method called each frame to update the entity.
    pub fn update(self) {
        if self.is_mob() && !self.is_player() && self.ticks_this_frame() {
            self.mob_ai();
        }
    }

    /// AI routine for autonomous mobs.
    fn mob_ai(self) {
        assert!(self.is_mob());
        assert!(!self.is_player());
        assert!(self.ticks_this_frame());

        if self.has_status(status::Asleep) {
            if let Some(p) = action::player() {
                // TODO: Line-of-sight, stealth concerns, other enemies than
                // player etc.
                if let Some(d) = p.distance_from(self) {
                    if d < 6 {
                        self.remove_status(status::Asleep);
                    }
                }
            }

            return;
        }

        if let Some(p) = action::player() {
            let pathing = Dijkstra::new(vec![p.location().unwrap()], |&loc| !loc.blocks_walk(), 64);
            let loc = self.location().unwrap();

            let steps = pathing.sorted_neighbors(&loc);
            if steps.len() > 0 {
                self.step(loc.dir6_towards(steps[0]).unwrap());
            } else {
                // TODO: Random dir step
            }
        }
    }

// Callbacks ///////////////////////////////////////////////////////////

    /// Called after the entity is moved to a new location.
    pub fn on_move_to(self, _loc: Location) {
        self.do_fov();
    }

// Misc ////////////////////////////////////////////////////////////////

    fn has_map_memory(self) -> bool {
        world::get().borrow().comp.map_memory.get(self).is_some()
    }

    fn do_fov(self) {
        let range = 12u;
        if let Some(loc) = self.location() {
            if self.has_map_memory() {
                let seen: Vec<Location> = Fov::new(
                    |pt| (loc + pt).blocks_sight(), range)
                    .map(|pt| loc + pt)
                    .collect();
                if let Some(ref mut mm) = world::get().borrow_mut().comp.map_memory.get_mut(self) {
                    mm.seen.clear();
                    mm.seen.extend(seen.clone().into_iter());
                    mm.remembered.extend(seen.into_iter());
                } else {
                    panic!("Couldn't bind map memory");
                }
            }
        }
    }
}
<|endoftext|>


<commit_before>use ascii::{AsciiStr, AsciiString, FromAsciiError};
use std::cmp::Ordering;
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;

use chrono::*;

/// Status code of a request or response.
#[derive(Eq, PartialEq, Clone, Debug, Ord, PartialOrd)]
pub struct StatusCode(pub u16);

impl StatusCode {
    /// Returns the default reason phrase for this status code.
    /// For example the status code 404 corresponds to "Not Found".
    pub fn default_reason_phrase(&self) -> &'static str {
        match self.0 {
            100 => "Continue",
            101 => "Switching Protocols",
            102 => "Processing",
            103 => "Early Hints",

            200 => "OK",
            201 => "Created",
            202 => "Accepted",
            203 => "Non-Authoritative Information",
            204 => "No Content",
            205 => "Reset Content",
            206 => "Partial Content",
            207 => "Multi-Status",
            208 => "Already Reported",
            226 => "IM Used",

            300 => "Multiple Choices",
            301 => "Moved Permanently",
            302 => "Found",
            303 => "See Other",
            304 => "Not Modified",
            305 => "Use Proxy",
            307 => "Temporary Redirect",
            308 => "Permanent Redirect",

            400 => "Bad Request",
            401 => "Unauthorized",
            402 => "Payment Required",
            403 => "Forbidden",
            404 => "Not Found",
            405 => "Method Not Allowed",
            406 => "Not Acceptable",
            407 => "Proxy Authentication Required",
            408 => "Request Timeout",
            409 => "Conflict",
            410 => "Gone",
            411 => "Length Required",
            412 => "Precondition Failed",
            413 => "Payload Too Large",
            414 => "URI Too Long",
            415 => "Unsupported Media Type",
            416 => "Range Not Satisfiable",
            417 => "Expectation Failed",
            421 => "Misdirected Request",
            422 => "Unprocessable Entity",
            423 => "Locked",
            424 => "Failed Dependency",
            426 => "Upgrade Required",
            428 => "Precondition Required",
            429 => "Too Many Requests",
            431 => "Request Header Fields Too Large",
            451 => "Unavailable For Legal Reasons",

            500 => "Internal Server Error",
            501 => "Not Implemented",
            502 => "Bad Gateway",
            503 => "Service Unavailable",
            504 => "Gateway Timeout",
            505 => "HTTP Version Not Supported",
            506 => "Variant Also Negotiates",
            507 => "Insufficient Storage",
            508 => "Loop Detected",
            510 => "Not Extended",
            511 => "Network Authentication Required",
            _ => "Unknown",
        }
    }
}

impl From<i8> for StatusCode {
    fn from(in_code: i8) -> StatusCode {
        StatusCode(in_code as u16)
    }
}

impl From<u8> for StatusCode {
    fn from(in_code: u8) -> StatusCode {
        StatusCode(in_code as u16)
    }
}

impl From<i16> for StatusCode {
    fn from(in_code: i16) -> StatusCode {
        StatusCode(in_code as u16)
    }
}

impl From<u16> for StatusCode {
    fn from(in_code: u16) -> StatusCode {
        StatusCode(in_code)
    }
}

impl From<i32> for StatusCode {
    fn from(in_code: i32) -> StatusCode {
        StatusCode(in_code as u16)
    }
}

impl From<u32> for StatusCode {
    fn from(in_code: u32) -> StatusCode {
        StatusCode(in_code as u16)
    }
}

impl AsRef<u16> for StatusCode {
    fn as_ref(&self) -> &u16 {
        &self.0
    }
}

impl PartialEq<u16> for StatusCode {
    fn eq(&self, other: &u16) -> bool {
        &self.0 == other
    }
}

impl PartialEq<StatusCode> for u16 {
    fn eq(&self, other: &StatusCode) -> bool {
        self == &other.0
    }
}

impl PartialOrd<u16> for StatusCode {
    fn partial_cmp(&self, other: &u16) -> Option<Ordering> {
        self.0.partial_cmp(other)
    }
}

impl PartialOrd<StatusCode> for u16 {
    fn partial_cmp(&self, other: &StatusCode) -> Option<Ordering> {
        self.partial_cmp(&other.0)
    }
}

/// Represents a HTTP header.
#[derive(Debug, Clone)]
pub struct Header {
    pub field: HeaderField,
    pub value: AsciiString,
}

impl Header {
    /// Builds a `Header` from two `Vec<u8>`s or two `&[u8]`s.
    ///
    /// Example:
    ///
    /// ```
    /// let header = tiny_http::Header::from_bytes(&b"Content-Type"[..], &b"text/plain"[..]).unwrap();
    /// ```
    pub fn from_bytes<B1, B2>(header: B1, value: B2) -> Result<Header, ()>
    where
        B1: Into<Vec<u8>> + AsRef<[u8]>,
        B2: Into<Vec<u8>> + AsRef<[u8]>,
    {
        let header = HeaderField::from_bytes(header).or(Err(()))?;
        let value = AsciiString::from_ascii(value).or(Err(()))?;

        Ok(Header {
            field: header,
            value,
        })
    }
}

impl FromStr for Header {
    type Err = ();

    fn from_str(input: &str) -> Result<Header, ()> {
        let mut elems = input.splitn(2, ':');

        let field = elems.next();
        let value = elems.next();

        let (field, value) = match (field, value) {
            (Some(f), Some(v)) => (f, v),
            _ => return Err(()),
        };

        let field = match FromStr::from_str(field) {
            Ok(f) => f,
            _ => return Err(()),
        };

        let value = AsciiString::from_ascii(value.trim()).map_err(|_| ())?;

        Ok(Header { field, value })
    }
}

impl Display for Header {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        write!(formatter, "{}: {}", self.field, self.value.as_str())
    }
}

/// Field of a header (eg. `Content-Type`, `Content-Length`, etc.)
///
/// Comparison between two `HeaderField`s ignores case.
#[derive(Debug, Clone)]
pub struct HeaderField(AsciiString);

impl HeaderField {
    pub fn from_bytes<B>(bytes: B) -> Result<HeaderField, FromAsciiError<B>>
    where
        B: Into<Vec<u8>> + AsRef<[u8]>,
    {
        AsciiString::from_ascii(bytes).map(HeaderField)
    }

    pub fn as_str(&self) -> &AsciiStr {
        match self {
            HeaderField(ref s) => s,
        }
    }

    pub fn equiv(&self, other: &'static str) -> bool {
        other.eq_ignore_ascii_case(self.as_str().as_str())
    }
}

impl FromStr for HeaderField {
    type Err = ();

    fn from_str(s: &str) -> Result<HeaderField, ()> {
        AsciiString::from_ascii(s)
            .map(HeaderField)
            .map_err(|_| ())
    }
}

impl Display for HeaderField {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        let method = self.as_str();
        write!(formatter, "{}", method.as_str())
    }
}

impl PartialEq for HeaderField {
    fn eq(&self, other: &HeaderField) -> bool {
        let self_str: &str = self.as_str().as_ref();
        let other_str = other.as_str().as_ref();
        self_str.eq_ignore_ascii_case(other_str)
    }
}

impl Eq for HeaderField {}

/// HTTP request methods
///
/// As per [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.1) and
/// [RFC 5789](https://tools.ietf.org/html/rfc5789)
#[derive(Debug, Clone)]
pub enum Method {
    /// `GET`
    Get,

    /// `HEAD`
    Head,

    /// `POST`
    Post,

    /// `PUT`
    Put,

    /// `DELETE`
    Delete,

    /// `CONNECT`
    Connect,

    /// `OPTIONS`
    Options,

    /// `TRACE`
    Trace,

    /// `PATCH`
    Patch,

    /// Request methods not standardized by the IETF
    NonStandard(AsciiString),
}

impl Method {
    pub fn as_str(&self) -> &str {
        match *self {
            Method::Get => "GET",
            Method::Head => "HEAD",
            Method::Post => "POST",
            Method::Put => "PUT",
            Method::Delete => "DELETE",
            Method::Connect => "CONNECT",
            Method::Options => "OPTIONS",
            Method::Trace => "TRACE",
            Method::Patch => "PATCH",
            Method::NonStandard(ref s) => s.as_str(),
        }
    }
}

impl FromStr for Method {
    type Err = ();

    fn from_str(s: &str) -> Result<Method, ()> {
        Ok(match s {
            s if s.eq_ignore_ascii_case("GET") => Method::Get,
            s if s.eq_ignore_ascii_case("HEAD") => Method::Head,
            s if s.eq_ignore_ascii_case("POST") => Method::Post,
            s if s.eq_ignore_ascii_case("PUT") => Method::Put,
            s if s.eq_ignore_ascii_case("DELETE") => Method::Delete,
            s if s.eq_ignore_ascii_case("CONNECT") => Method::Connect,
            s if s.eq_ignore_ascii_case("OPTIONS") => Method::Options,
            s if s.eq_ignore_ascii_case("TRACE") => Method::Trace,
            s if s.eq_ignore_ascii_case("PATCH") => Method::Patch,
            s => {
                let ascii_string = AsciiString::from_ascii(s).map_err(|_| ())?;
                Method::NonStandard(ascii_string)
            }
        })
    }
}

impl Display for Method {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        write!(formatter, "{}", self.as_str())
    }
}

impl PartialEq for Method {
    fn eq(&self, other: &Method) -> bool {
        match (self, other) {
            (&Method::NonStandard(ref s1), &Method::NonStandard(ref s2)) => {
                s1.as_str().eq_ignore_ascii_case(s2.as_str())
            }
            (&Method::Get, &Method::Get) => true,
            (&Method::Head, &Method::Head) => true,
            (&Method::Post, &Method::Post) => true,
            (&Method::Put, &Method::Put) => true,
            (&Method::Delete, &Method::Delete) => true,
            (&Method::Connect, &Method::Connect) => true,
            (&Method::Options, &Method::Options) => true,
            (&Method::Trace, &Method::Trace) => true,
            (&Method::Patch, &Method::Patch) => true,
            _ => false,
        }
    }
}

impl Eq for Method {}

/// HTTP version (usually 1.0 or 1.1).
#[derive(Debug, Clone, PartialEq, Eq, Ord)]
pub struct HTTPVersion(pub u8, pub u8);

impl Display for HTTPVersion {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        let (major, minor) = match self {
            HTTPVersion(m, n) => (m, n),
        };
        write!(formatter, "{}.{}", major, minor)
    }
}

impl PartialOrd for HTTPVersion {
    fn partial_cmp(&self, other: &HTTPVersion) -> Option<Ordering> {
        let HTTPVersion(my_major, my_minor) = *self;
        let HTTPVersion(other_major, other_minor) = *other;

        if my_major != other_major {
            return my_major.partial_cmp(&other_major);
        }

        my_minor.partial_cmp(&other_minor)
    }
}

impl PartialEq<(u8, u8)> for HTTPVersion {
    fn eq(&self, &(major, minor): &(u8, u8)) -> bool {
        self.eq(&HTTPVersion(major, minor))
    }
}

impl PartialEq<HTTPVersion> for (u8, u8) {
    fn eq(&self, other: &HTTPVersion) -> bool {
        let &(major, minor) = self;
        HTTPVersion(major, minor).eq(other)
    }
}

impl PartialOrd<(u8, u8)> for HTTPVersion {
    fn partial_cmp(&self, &(major, minor): &(u8, u8)) -> Option<Ordering> {
        self.partial_cmp(&HTTPVersion(major, minor))
    }
}

impl PartialOrd<HTTPVersion> for (u8, u8) {
    fn partial_cmp(&self, other: &HTTPVersion) -> Option<Ordering> {
        let &(major, minor) = self;
        HTTPVersion(major, minor).partial_cmp(other)
    }
}

impl From<(u8, u8)> for HTTPVersion {
    fn from((major, minor): (u8, u8)) -> HTTPVersion {
        HTTPVersion(major, minor)
    }
}
/// Represents the current date, expressed in RFC 1123 format, e.g. Sun, 06 Nov 1994 08:49:37 GMT
pub struct HTTPDate {
    d: DateTime<Utc>,
}

impl HTTPDate {
    pub fn new() -> HTTPDate {
        HTTPDate { d: Utc::now() }
    }
}

impl ToString for HTTPDate {
    fn to_string(&self) -> String {
        self.d.format("%a, %e %b %Y %H:%M:%S GMT").to_string()
    }
}

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

    #[test]
    fn test_parse_header() {
        let header: Header = "Content-Type: text/html".parse().unwrap();

        assert!(header.field.equiv(&"content-type"));
        assert!(header.value.as_str() == "text/html");

        assert!("hello world".parse::<Header>().is_err());
    }

    #[test]
    fn test_parse_header_with_doublecolon() {
        let header: Header = "Time: 20: 34".parse().unwrap();

        assert!(header.field.equiv(&"time"));
        assert!(header.value.as_str() == "20: 34");
    }

    // This tests reslstance to RUSTSEC-2020-0031: "HTTP Request smuggling
    // through malformed Transfer Encoding headers"
    // (https://rustsec.org/advisories/RUSTSEC-2020-0031.html).
    #[test]
    fn test_strict_headers() {
        let smuggled = "Transfer-Encoding : chunked".parse::<Header>().unwrap();
        assert!(!smuggled.field.equiv("Transfer-Encoding"));
    }
}
<commit_msg>Header fields can't contain whitespace.<commit_after>use ascii::{AsciiStr, AsciiString, FromAsciiError};
use std::cmp::Ordering;
use std::fmt::{self, Display, Formatter};
use std::str::FromStr;

use chrono::*;

/// Status code of a request or response.
#[derive(Eq, PartialEq, Clone, Debug, Ord, PartialOrd)]
pub struct StatusCode(pub u16);

impl StatusCode {
    /// Returns the default reason phrase for this status code.
    /// For example the status code 404 corresponds to "Not Found".
    pub fn default_reason_phrase(&self) -> &'static str {
        match self.0 {
            100 => "Continue",
            101 => "Switching Protocols",
            102 => "Processing",
            103 => "Early Hints",

            200 => "OK",
            201 => "Created",
            202 => "Accepted",
            203 => "Non-Authoritative Information",
            204 => "No Content",
            205 => "Reset Content",
            206 => "Partial Content",
            207 => "Multi-Status",
            208 => "Already Reported",
            226 => "IM Used",

            300 => "Multiple Choices",
            301 => "Moved Permanently",
            302 => "Found",
            303 => "See Other",
            304 => "Not Modified",
            305 => "Use Proxy",
            307 => "Temporary Redirect",
            308 => "Permanent Redirect",

            400 => "Bad Request",
            401 => "Unauthorized",
            402 => "Payment Required",
            403 => "Forbidden",
            404 => "Not Found",
            405 => "Method Not Allowed",
            406 => "Not Acceptable",
            407 => "Proxy Authentication Required",
            408 => "Request Timeout",
            409 => "Conflict",
            410 => "Gone",
            411 => "Length Required",
            412 => "Precondition Failed",
            413 => "Payload Too Large",
            414 => "URI Too Long",
            415 => "Unsupported Media Type",
            416 => "Range Not Satisfiable",
            417 => "Expectation Failed",
            421 => "Misdirected Request",
            422 => "Unprocessable Entity",
            423 => "Locked",
            424 => "Failed Dependency",
            426 => "Upgrade Required",
            428 => "Precondition Required",
            429 => "Too Many Requests",
            431 => "Request Header Fields Too Large",
            451 => "Unavailable For Legal Reasons",

            500 => "Internal Server Error",
            501 => "Not Implemented",
            502 => "Bad Gateway",
            503 => "Service Unavailable",
            504 => "Gateway Timeout",
            505 => "HTTP Version Not Supported",
            506 => "Variant Also Negotiates",
            507 => "Insufficient Storage",
            508 => "Loop Detected",
            510 => "Not Extended",
            511 => "Network Authentication Required",
            _ => "Unknown",
        }
    }
}

impl From<i8> for StatusCode {
    fn from(in_code: i8) -> StatusCode {
        StatusCode(in_code as u16)
    }
}

impl From<u8> for StatusCode {
    fn from(in_code: u8) -> StatusCode {
        StatusCode(in_code as u16)
    }
}

impl From<i16> for StatusCode {
    fn from(in_code: i16) -> StatusCode {
        StatusCode(in_code as u16)
    }
}

impl From<u16> for StatusCode {
    fn from(in_code: u16) -> StatusCode {
        StatusCode(in_code)
    }
}

impl From<i32> for StatusCode {
    fn from(in_code: i32) -> StatusCode {
        StatusCode(in_code as u16)
    }
}

impl From<u32> for StatusCode {
    fn from(in_code: u32) -> StatusCode {
        StatusCode(in_code as u16)
    }
}

impl AsRef<u16> for StatusCode {
    fn as_ref(&self) -> &u16 {
        &self.0
    }
}

impl PartialEq<u16> for StatusCode {
    fn eq(&self, other: &u16) -> bool {
        &self.0 == other
    }
}

impl PartialEq<StatusCode> for u16 {
    fn eq(&self, other: &StatusCode) -> bool {
        self == &other.0
    }
}

impl PartialOrd<u16> for StatusCode {
    fn partial_cmp(&self, other: &u16) -> Option<Ordering> {
        self.0.partial_cmp(other)
    }
}

impl PartialOrd<StatusCode> for u16 {
    fn partial_cmp(&self, other: &StatusCode) -> Option<Ordering> {
        self.partial_cmp(&other.0)
    }
}

/// Represents a HTTP header.
#[derive(Debug, Clone)]
pub struct Header {
    pub field: HeaderField,
    pub value: AsciiString,
}

impl Header {
    /// Builds a `Header` from two `Vec<u8>`s or two `&[u8]`s.
    ///
    /// Example:
    ///
    /// ```
    /// let header = tiny_http::Header::from_bytes(&b"Content-Type"[..], &b"text/plain"[..]).unwrap();
    /// ```
    pub fn from_bytes<B1, B2>(header: B1, value: B2) -> Result<Header, ()>
    where
        B1: Into<Vec<u8>> + AsRef<[u8]>,
        B2: Into<Vec<u8>> + AsRef<[u8]>,
    {
        let header = HeaderField::from_bytes(header).or(Err(()))?;
        let value = AsciiString::from_ascii(value).or(Err(()))?;

        Ok(Header {
            field: header,
            value,
        })
    }
}

impl FromStr for Header {
    type Err = ();

    fn from_str(input: &str) -> Result<Header, ()> {
        let mut elems = input.splitn(2, ':');

        let field = elems.next();
        let value = elems.next();

        let (field, value) = match (field, value) {
            (Some(f), Some(v)) => (f, v),
            _ => return Err(()),
        };

        let field = match FromStr::from_str(field) {
            Ok(f) => f,
            _ => return Err(()),
        };

        let value = AsciiString::from_ascii(value.trim()).map_err(|_| ())?;

        Ok(Header { field, value })
    }
}

impl Display for Header {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        write!(formatter, "{}: {}", self.field, self.value.as_str())
    }
}

/// Field of a header (eg. `Content-Type`, `Content-Length`, etc.)
///
/// Comparison between two `HeaderField`s ignores case.
#[derive(Debug, Clone)]
pub struct HeaderField(AsciiString);

impl HeaderField {
    pub fn from_bytes<B>(bytes: B) -> Result<HeaderField, FromAsciiError<B>>
    where
        B: Into<Vec<u8>> + AsRef<[u8]>,
    {
        AsciiString::from_ascii(bytes).map(HeaderField)
    }

    pub fn as_str(&self) -> &AsciiStr {
        match self {
            HeaderField(ref s) => s,
        }
    }

    pub fn equiv(&self, other: &'static str) -> bool {
        other.eq_ignore_ascii_case(self.as_str().as_str())
    }
}

impl FromStr for HeaderField {
    type Err = ();

    fn from_str(s: &str) -> Result<HeaderField, ()> {
        if s.contains(char::is_whitespace) {
            Err(())
        } else {
            AsciiString::from_ascii(s)
                .map(HeaderField)
                .map_err(|_| ())
        }
    }
}

impl Display for HeaderField {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        let method = self.as_str();
        write!(formatter, "{}", method.as_str())
    }
}

impl PartialEq for HeaderField {
    fn eq(&self, other: &HeaderField) -> bool {
        let self_str: &str = self.as_str().as_ref();
        let other_str = other.as_str().as_ref();
        self_str.eq_ignore_ascii_case(other_str)
    }
}

impl Eq for HeaderField {}

/// HTTP request methods
///
/// As per [RFC 7231](https://tools.ietf.org/html/rfc7231#section-4.1) and
/// [RFC 5789](https://tools.ietf.org/html/rfc5789)
#[derive(Debug, Clone)]
pub enum Method {
    /// `GET`
    Get,

    /// `HEAD`
    Head,

    /// `POST`
    Post,

    /// `PUT`
    Put,

    /// `DELETE`
    Delete,

    /// `CONNECT`
    Connect,

    /// `OPTIONS`
    Options,

    /// `TRACE`
    Trace,

    /// `PATCH`
    Patch,

    /// Request methods not standardized by the IETF
    NonStandard(AsciiString),
}

impl Method {
    pub fn as_str(&self) -> &str {
        match *self {
            Method::Get => "GET",
            Method::Head => "HEAD",
            Method::Post => "POST",
            Method::Put => "PUT",
            Method::Delete => "DELETE",
            Method::Connect => "CONNECT",
            Method::Options => "OPTIONS",
            Method::Trace => "TRACE",
            Method::Patch => "PATCH",
            Method::NonStandard(ref s) => s.as_str(),
        }
    }
}

impl FromStr for Method {
    type Err = ();

    fn from_str(s: &str) -> Result<Method, ()> {
        Ok(match s {
            s if s.eq_ignore_ascii_case("GET") => Method::Get,
            s if s.eq_ignore_ascii_case("HEAD") => Method::Head,
            s if s.eq_ignore_ascii_case("POST") => Method::Post,
            s if s.eq_ignore_ascii_case("PUT") => Method::Put,
            s if s.eq_ignore_ascii_case("DELETE") => Method::Delete,
            s if s.eq_ignore_ascii_case("CONNECT") => Method::Connect,
            s if s.eq_ignore_ascii_case("OPTIONS") => Method::Options,
            s if s.eq_ignore_ascii_case("TRACE") => Method::Trace,
            s if s.eq_ignore_ascii_case("PATCH") => Method::Patch,
            s => {
                let ascii_string = AsciiString::from_ascii(s).map_err(|_| ())?;
                Method::NonStandard(ascii_string)
            }
        })
    }
}

impl Display for Method {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        write!(formatter, "{}", self.as_str())
    }
}

impl PartialEq for Method {
    fn eq(&self, other: &Method) -> bool {
        match (self, other) {
            (&Method::NonStandard(ref s1), &Method::NonStandard(ref s2)) => {
                s1.as_str().eq_ignore_ascii_case(s2.as_str())
            }
            (&Method::Get, &Method::Get) => true,
            (&Method::Head, &Method::Head) => true,
            (&Method::Post, &Method::Post) => true,
            (&Method::Put, &Method::Put) => true,
            (&Method::Delete, &Method::Delete) => true,
            (&Method::Connect, &Method::Connect) => true,
            (&Method::Options, &Method::Options) => true,
            (&Method::Trace, &Method::Trace) => true,
            (&Method::Patch, &Method::Patch) => true,
            _ => false,
        }
    }
}

impl Eq for Method {}

/// HTTP version (usually 1.0 or 1.1).
#[derive(Debug, Clone, PartialEq, Eq, Ord)]
pub struct HTTPVersion(pub u8, pub u8);

impl Display for HTTPVersion {
    fn fmt(&self, formatter: &mut Formatter) -> Result<(), fmt::Error> {
        let (major, minor) = match self {
            HTTPVersion(m, n) => (m, n),
        };
        write!(formatter, "{}.{}", major, minor)
    }
}

impl PartialOrd for HTTPVersion {
    fn partial_cmp(&self, other: &HTTPVersion) -> Option<Ordering> {
        let HTTPVersion(my_major, my_minor) = *self;
        let HTTPVersion(other_major, other_minor) = *other;

        if my_major != other_major {
            return my_major.partial_cmp(&other_major);
        }

        my_minor.partial_cmp(&other_minor)
    }
}

impl PartialEq<(u8, u8)> for HTTPVersion {
    fn eq(&self, &(major, minor): &(u8, u8)) -> bool {
        self.eq(&HTTPVersion(major, minor))
    }
}

impl PartialEq<HTTPVersion> for (u8, u8) {
    fn eq(&self, other: &HTTPVersion) -> bool {
        let &(major, minor) = self;
        HTTPVersion(major, minor).eq(other)
    }
}

impl PartialOrd<(u8, u8)> for HTTPVersion {
    fn partial_cmp(&self, &(major, minor): &(u8, u8)) -> Option<Ordering> {
        self.partial_cmp(&HTTPVersion(major, minor))
    }
}

impl PartialOrd<HTTPVersion> for (u8, u8) {
    fn partial_cmp(&self, other: &HTTPVersion) -> Option<Ordering> {
        let &(major, minor) = self;
        HTTPVersion(major, minor).partial_cmp(other)
    }
}

impl From<(u8, u8)> for HTTPVersion {
    fn from((major, minor): (u8, u8)) -> HTTPVersion {
        HTTPVersion(major, minor)
    }
}
/// Represents the current date, expressed in RFC 1123 format, e.g. Sun, 06 Nov 1994 08:49:37 GMT
pub struct HTTPDate {
    d: DateTime<Utc>,
}

impl HTTPDate {
    pub fn new() -> HTTPDate {
        HTTPDate { d: Utc::now() }
    }
}

impl ToString for HTTPDate {
    fn to_string(&self) -> String {
        self.d.format("%a, %e %b %Y %H:%M:%S GMT").to_string()
    }
}

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

    #[test]
    fn test_parse_header() {
        let header: Header = "Content-Type: text/html".parse().unwrap();

        assert!(header.field.equiv(&"content-type"));
        assert!(header.value.as_str() == "text/html");

        assert!("hello world".parse::<Header>().is_err());
    }

    #[test]
    fn test_parse_header_with_doublecolon() {
        let header: Header = "Time: 20: 34".parse().unwrap();

        assert!(header.field.equiv(&"time"));
        assert!(header.value.as_str() == "20: 34");
    }

    // This tests reslstance to RUSTSEC-2020-0031: "HTTP Request smuggling
    // through malformed Transfer Encoding headers"
    // (https://rustsec.org/advisories/RUSTSEC-2020-0031.html).
    #[test]
    fn test_strict_headers() {
        assert!("Transfer-Encoding : chunked".parse::<Header>().is_err());
        assert!(" Transfer-Encoding: chunked".parse::<Header>().is_err());
        assert!("Transfer Encoding: chunked".parse::<Header>().is_err());
        assert!(" Transfer\tEncoding : chunked".parse::<Header>().is_err());
        assert!("Transfer-Encoding: chunked".parse::<Header>().is_ok());
        assert!("Transfer-Encoding: chunked ".parse::<Header>().is_ok());
        assert!("Transfer-Encoding:   chunked ".parse::<Header>().is_ok());
    }
}
<|endoftext|>


<commit_before>use actix_web::{HttpRequest, HttpResponse};
use hyper::header::CONTENT_TYPE;
use json;
use mustache;
use mustache::MapBuilder;
#[cfg(feature = "mocking")]
use reqwest_mock::Client;
use std::collections::HashMap;
#[cfg(feature = "mocking")]
use std::ops::Deref;
use std::sync::Mutex;
use url::percent_encoding;

lazy_static! {
    static ref TEMPLATES: HashMap<&'static str, &'static str> = {
        let mut m = HashMap::new();
        include!(concat!(env!("OUT_DIR"), "/templates.rs"));
        m
    };
}

pub enum ClientType {
    LIVE,
    #[cfg(test)]
    TESTING,
}

lazy_static! {
    static ref CLIENT: Mutex<Option<ClientType>> = Mutex::new(Some(ClientType::LIVE));
}

#[cfg(test)]
pub fn set_client(ct: ClientType) {
    CLIENT.lock().unwrap().replace(ct);
}

#[cfg(feature = "mocking")]
fn get_data(url: &String) -> Result<String, String> {
    let client = match CLIENT.lock().unwrap().deref() {
        Some(ClientType::LIVE) => reqwest_mock::client::GenericClient::direct(),
        #[cfg(test)]
        Some(ClientType::TESTING) => reqwest_mock::client::GenericClient::replay_dir("tests/requests"),
        None => panic!(),
    };
    let res = match client.get(url).send() {
        Ok(val) => val,
        Err(err) => {
            return Err(format!("Can't connect to TfL: {}", err));
        }
    };
    return res.body_to_utf8().map_err(|e| format!("{:?}", e));
}

#[cfg(not(feature = "mocking"))]
fn get_data(url: &String) -> Result<String, String> {
    return reqwest::get(url)
        .and_then(|mut r| r.text())
        .map_err(|e| format!("{:?}", e));
}

pub fn json_for_url(url: &String) -> Result<json::JsonValue, String> {
    let buffer = get_data(url)?;
    let obj = match json::parse(&buffer) {
        Ok(val) => val,
        Err(_) => {
            return Err(format!("Bad json: {} ", buffer));
        }
    };
    return Ok(obj);
}

pub fn render_to_response(path: &str, data: &mustache::Data) -> HttpResponse {
    let template_data = TEMPLATES
        .get(path)
        .expect(&format!("Expected template for {}", path));
    let template = mustache::compile_str(template_data).expect("working template");
    let mut buffer: Vec<u8> = vec![];
    template.render_data(&mut buffer, data).unwrap();
    let mut response = HttpResponse::Ok();
    response.header(CONTENT_TYPE, "text/html");
    response.body(buffer)
}

pub static KEY: &'static str = "favourites";

pub fn favourites(req: &HttpRequest) -> json::JsonValue {
    let cookie = req.cookie(KEY);
    match cookie {
        Some(val) => {
            match json::parse(&val.value()) {
                Ok(val) => val,
                Err(_) => json::JsonValue::new_object(), // assume junk
            }
        }
        None => json::JsonValue::new_object(),
    }
}

pub fn mustache_favourites(req: &HttpRequest) -> mustache::Data {
    let favourites = favourites(req);
    MapBuilder::new()
        .insert_vec("favourites", |vecbuilder| {
            let mut vecb = vecbuilder;
            for fav in favourites.entries() {
                vecb = vecb
                    .push_map(|mapbuilder| mapbuilder.insert_str("key", fav.0).insert_str("value", fav.1));
            }
            vecb
        })
        .build()
}

pub fn query_encode(input: &str) -> String {
    percent_encoding::utf8_percent_encode(input, percent_encoding::QUERY_ENCODE_SET).collect::<String>()
}
<commit_msg>Better info on where Bad JSON errors come from<commit_after>use actix_web::{HttpRequest, HttpResponse};
use hyper::header::CONTENT_TYPE;
use json;
use mustache;
use mustache::MapBuilder;
#[cfg(feature = "mocking")]
use reqwest_mock::Client;
use std::collections::HashMap;
#[cfg(feature = "mocking")]
use std::ops::Deref;
use std::sync::Mutex;
use url::percent_encoding;

lazy_static! {
    static ref TEMPLATES: HashMap<&'static str, &'static str> = {
        let mut m = HashMap::new();
        include!(concat!(env!("OUT_DIR"), "/templates.rs"));
        m
    };
}

pub enum ClientType {
    LIVE,
    #[cfg(test)]
    TESTING,
}

lazy_static! {
    static ref CLIENT: Mutex<Option<ClientType>> = Mutex::new(Some(ClientType::LIVE));
}

#[cfg(test)]
pub fn set_client(ct: ClientType) {
    CLIENT.lock().unwrap().replace(ct);
}

#[cfg(feature = "mocking")]
fn get_data(url: &String) -> Result<String, String> {
    let client = match CLIENT.lock().unwrap().deref() {
        Some(ClientType::LIVE) => reqwest_mock::client::GenericClient::direct(),
        #[cfg(test)]
        Some(ClientType::TESTING) => reqwest_mock::client::GenericClient::replay_dir("tests/requests"),
        None => panic!(),
    };
    let res = match client.get(url).send() {
        Ok(val) => val,
        Err(err) => {
            return Err(format!("Can't connect to TfL: {}", err));
        }
    };
    return res.body_to_utf8().map_err(|e| format!("{:?}", e));
}

#[cfg(not(feature = "mocking"))]
fn get_data(url: &String) -> Result<String, String> {
    return reqwest::get(url)
        .and_then(|mut r| r.text())
        .map_err(|e| format!("{:?}", e));
}

pub fn json_for_url(url: &String) -> Result<json::JsonValue, String> {
    let buffer = get_data(url)?;
    let obj = match json::parse(&buffer) {
        Ok(val) => val,
        Err(_) => {
            return Err(format!("Bad json for {}: {} ", url, buffer));
        }
    };
    return Ok(obj);
}

pub fn render_to_response(path: &str, data: &mustache::Data) -> HttpResponse {
    let template_data = TEMPLATES
        .get(path)
        .expect(&format!("Expected template for {}", path));
    let template = mustache::compile_str(template_data).expect("working template");
    let mut buffer: Vec<u8> = vec![];
    template.render_data(&mut buffer, data).unwrap();
    let mut response = HttpResponse::Ok();
    response.header(CONTENT_TYPE, "text/html");
    response.body(buffer)
}

pub static KEY: &'static str = "favourites";

pub fn favourites(req: &HttpRequest) -> json::JsonValue {
    let cookie = req.cookie(KEY);
    match cookie {
        Some(val) => {
            match json::parse(&val.value()) {
                Ok(val) => val,
                Err(_) => json::JsonValue::new_object(), // assume junk
            }
        }
        None => json::JsonValue::new_object(),
    }
}

pub fn mustache_favourites(req: &HttpRequest) -> mustache::Data {
    let favourites = favourites(req);
    MapBuilder::new()
        .insert_vec("favourites", |vecbuilder| {
            let mut vecb = vecbuilder;
            for fav in favourites.entries() {
                vecb = vecb
                    .push_map(|mapbuilder| mapbuilder.insert_str("key", fav.0).insert_str("value", fav.1));
            }
            vecb
        })
        .build()
}

pub fn query_encode(input: &str) -> String {
    percent_encoding::utf8_percent_encode(input, percent_encoding::QUERY_ENCODE_SET).collect::<String>()
}
<|endoftext|>


<commit_before>//! Serde `Deserializer` module

use crate::{
    de::{
        escape::EscapedDeserializer, BorrowingReader, Deserializer, INNER_VALUE, UNFLATTEN_PREFIX,
    },
    errors::serialize::DeError,
    events::{BytesStart, Event},
};
use serde::de::{self, DeserializeSeed, IntoDeserializer};

enum MapValue {
    Empty,
    /// Value should be deserialized from the attribute value
    Attribute { value: Vec<u8> },
    Nested,
    /// Value should be deserialized from the text content of the XML node:
    ///
    /// ```xml
    /// <...>text content for field value<...>
    /// ```
    InnerValue,
}

/// A deserializer for `Attributes`
pub(crate) struct MapAccess<'de, 'a, R: BorrowingReader<'de> + 'a> {
    /// Tag -- owner of attributes
    start: BytesStart<'de>,
    de: &'a mut Deserializer<'de, R>,
    /// Position in flat byte slice of all attributes from which next
    /// attribute should be parsed. This field is required because we
    /// do not store reference to `Attributes` itself but instead create
    /// a new object on each advance of `Attributes` iterator, so we need
    /// to restore last position before advance.
    position: usize,
    value: MapValue,
}

impl<'de, 'a, R: BorrowingReader<'de>> MapAccess<'de, 'a, R> {
    /// Create a new MapAccess
    pub fn new(de: &'a mut Deserializer<'de, R>, start: BytesStart<'de>) -> Result<Self, DeError> {
        let position = start.attributes().position;
        Ok(MapAccess {
            de,
            start,
            position,
            value: MapValue::Empty,
        })
    }

    fn next_attr(&mut self) -> Result<Option<(Vec<u8>, Vec<u8>)>, DeError> {
        let mut attributes = self.start.attributes();
        attributes.position = self.position;
        let next_att = attributes.next().transpose()?;
        self.position = attributes.position;
        Ok(next_att.map(|a| (a.key.to_owned(), a.value.into_owned())))
    }
}

impl<'de, 'a, R: BorrowingReader<'de> + 'a> de::MapAccess<'de> for MapAccess<'de, 'a, R> {
    type Error = DeError;

    fn next_key_seed<K: DeserializeSeed<'de>>(
        &mut self,
        seed: K,
    ) -> Result<Option<K::Value>, Self::Error> {
        let decoder = self.de.reader.decoder();
        let has_value_field = self.de.has_value_field;
        let has_unflatten_field = self.de.has_unflatten_field;
        if let Some((key, value)) = self.next_attr()? {
            // try getting map from attributes (key= "value")
            self.value = MapValue::Attribute { value };
            seed.deserialize(EscapedDeserializer::new(key, decoder, false))
                .map(Some)
        } else {
            // try getting from events (<key>value</key>)
            match self.de.peek()? {
                Some(Event::Text(_)) => {
                    self.value = MapValue::InnerValue;
                    // Deserialize `key` from special attribute name which means
                    // that value should be taken from the text content of the
                    // XML node
                    seed.deserialize(INNER_VALUE.into_deserializer()).map(Some)
                }
                // Used to deserialize collections of enums, like:
                // <root>
                //
                //
                //   <C/>
                // </root>
                //
                // into
                //
                // enum Enum { A, B, С }
                // struct Root {
                //     #[serde(rename = "$value")]
                //     items: Vec<Enum>,
                // }
                // TODO: This should be handled by #[serde(flatten)]
                // See https://github.com/serde-rs/serde/issues/1905
                Some(Event::Start(_)) if has_value_field => {
                    self.value = MapValue::InnerValue;
                    seed.deserialize(INNER_VALUE.into_deserializer()).map(Some)
                }
                Some(Event::Start(e)) if has_unflatten_field => {
                    self.value = MapValue::InnerValue;
                    let key = format!(
                        "{}{}",
                        UNFLATTEN_PREFIX,
                        String::from_utf8(e.local_name().to_vec())
                            .expect("$unflatten= did not contain valid Rust identifier")
                    );
                    seed.deserialize(key.into_deserializer()).map(Some)
                }
                Some(Event::Start(e)) => {
                    let name = e.local_name().to_owned();

                    self.value = MapValue::Nested;
                    seed.deserialize(EscapedDeserializer::new(name, decoder, false))
                        .map(Some)
                }
                _ => Ok(None),
            }
        }
    }

    fn next_value_seed<K: DeserializeSeed<'de>>(
        &mut self,
        seed: K,
    ) -> Result<K::Value, Self::Error> {
        match std::mem::replace(&mut self.value, MapValue::Empty) {
            MapValue::Attribute { value } => seed.deserialize(EscapedDeserializer::new(
                value,
                self.de.reader.decoder(),
                true,
            )),
            MapValue::Nested | MapValue::InnerValue => seed.deserialize(&mut *self.de),
            MapValue::Empty => Err(DeError::EndOfAttributes),
        }
    }
}
<commit_msg>Run cargo fmt<commit_after>//! Serde `Deserializer` module

use crate::{
    de::{
        escape::EscapedDeserializer, BorrowingReader, Deserializer, INNER_VALUE, UNFLATTEN_PREFIX,
    },
    errors::serialize::DeError,
    events::{BytesStart, Event},
};
use serde::de::{self, DeserializeSeed, IntoDeserializer};

enum MapValue {
    Empty,
    /// Value should be deserialized from the attribute value
    Attribute {
        value: Vec<u8>,
    },
    Nested,
    /// Value should be deserialized from the text content of the XML node:
    ///
    /// ```xml
    /// <...>text content for field value<...>
    /// ```
    InnerValue,
}

/// A deserializer for `Attributes`
pub(crate) struct MapAccess<'de, 'a, R: BorrowingReader<'de> + 'a> {
    /// Tag -- owner of attributes
    start: BytesStart<'de>,
    de: &'a mut Deserializer<'de, R>,
    /// Position in flat byte slice of all attributes from which next
    /// attribute should be parsed. This field is required because we
    /// do not store reference to `Attributes` itself but instead create
    /// a new object on each advance of `Attributes` iterator, so we need
    /// to restore last position before advance.
    position: usize,
    value: MapValue,
}

impl<'de, 'a, R: BorrowingReader<'de>> MapAccess<'de, 'a, R> {
    /// Create a new MapAccess
    pub fn new(de: &'a mut Deserializer<'de, R>, start: BytesStart<'de>) -> Result<Self, DeError> {
        let position = start.attributes().position;
        Ok(MapAccess {
            de,
            start,
            position,
            value: MapValue::Empty,
        })
    }

    fn next_attr(&mut self) -> Result<Option<(Vec<u8>, Vec<u8>)>, DeError> {
        let mut attributes = self.start.attributes();
        attributes.position = self.position;
        let next_att = attributes.next().transpose()?;
        self.position = attributes.position;
        Ok(next_att.map(|a| (a.key.to_owned(), a.value.into_owned())))
    }
}

impl<'de, 'a, R: BorrowingReader<'de> + 'a> de::MapAccess<'de> for MapAccess<'de, 'a, R> {
    type Error = DeError;

    fn next_key_seed<K: DeserializeSeed<'de>>(
        &mut self,
        seed: K,
    ) -> Result<Option<K::Value>, Self::Error> {
        let decoder = self.de.reader.decoder();
        let has_value_field = self.de.has_value_field;
        let has_unflatten_field = self.de.has_unflatten_field;
        if let Some((key, value)) = self.next_attr()? {
            // try getting map from attributes (key= "value")
            self.value = MapValue::Attribute { value };
            seed.deserialize(EscapedDeserializer::new(key, decoder, false))
                .map(Some)
        } else {
            // try getting from events (<key>value</key>)
            match self.de.peek()? {
                Some(Event::Text(_)) => {
                    self.value = MapValue::InnerValue;
                    // Deserialize `key` from special attribute name which means
                    // that value should be taken from the text content of the
                    // XML node
                    seed.deserialize(INNER_VALUE.into_deserializer()).map(Some)
                }
                // Used to deserialize collections of enums, like:
                // <root>
                //
                //
                //   <C/>
                // </root>
                //
                // into
                //
                // enum Enum { A, B, С }
                // struct Root {
                //     #[serde(rename = "$value")]
                //     items: Vec<Enum>,
                // }
                // TODO: This should be handled by #[serde(flatten)]
                // See https://github.com/serde-rs/serde/issues/1905
                Some(Event::Start(_)) if has_value_field => {
                    self.value = MapValue::InnerValue;
                    seed.deserialize(INNER_VALUE.into_deserializer()).map(Some)
                }
                Some(Event::Start(e)) if has_unflatten_field => {
                    self.value = MapValue::InnerValue;
                    let key = format!(
                        "{}{}",
                        UNFLATTEN_PREFIX,
                        String::from_utf8(e.local_name().to_vec())
                            .expect("$unflatten= did not contain valid Rust identifier")
                    );
                    seed.deserialize(key.into_deserializer()).map(Some)
                }
                Some(Event::Start(e)) => {
                    let name = e.local_name().to_owned();

                    self.value = MapValue::Nested;
                    seed.deserialize(EscapedDeserializer::new(name, decoder, false))
                        .map(Some)
                }
                _ => Ok(None),
            }
        }
    }

    fn next_value_seed<K: DeserializeSeed<'de>>(
        &mut self,
        seed: K,
    ) -> Result<K::Value, Self::Error> {
        match std::mem::replace(&mut self.value, MapValue::Empty) {
            MapValue::Attribute { value } => seed.deserialize(EscapedDeserializer::new(
                value,
                self.de.reader.decoder(),
                true,
            )),
            MapValue::Nested | MapValue::InnerValue => seed.deserialize(&mut *self.de),
            MapValue::Empty => Err(DeError::EndOfAttributes),
        }
    }
}
<|endoftext|>


<commit_before>// (c) 2016 Joost Yervante Damad <joost@productize.be>

use serde;
use serde::de;
use std::mem;

use Sexp;

use error::{Result, Error};

// loosely based on serde-yaml, toml-rs, serde_json

/// decode a symbolic expression to a rust expression using serde
pub fn decode<T: serde::Deserialize>(exp: Sexp) -> Result<T> {
    serde::Deserialize::deserialize(&mut Deserializer::new(exp))
}

struct Deserializer {
    pub exp: Sexp,
}

impl Deserializer {
    pub fn new(exp: Sexp) -> Deserializer {
        Deserializer { exp: exp }
    }

    pub fn take(&mut self) -> Sexp {
        let mut exp = Sexp::Empty;
        mem::swap(&mut exp, &mut self.exp);
        exp
    }
}

impl de::Deserializer for Deserializer {
    type Error = Error;

    /// called when we call deserialize below for a nested part
    fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        //println!("deserialize: {}", self.exp);
        if self.exp.is_string() {
            return self.deserialize_string(visitor)
        }
        if self.exp.is_list() {
            return self.deserialize_seq(visitor)
        }
        Err(Error::Decoder(format!("expecting specific deserializer to be called for {}", self.exp)))
    }

    /// deserialize any string in a symbolic expression
    fn deserialize_string<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_string(try!(self.exp.take_string()))
    }

    /// the empty symbolic-expression
    fn deserialize_unit<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        match self.exp {
            Sexp::Empty => visitor.visit_unit(),
            _ => Err(Error::Decoder(format!("expecting unit got {}", self.exp))),
        }
    }

    /// a symbolic expression of the form (name value1 value2 ...)
    fn deserialize_tuple_struct<V>(&mut self,
                                   name: &'static str,
                                   len: usize,
                                   mut visitor: V)
                                   -> Result<V::Value>
        where V: de::Visitor
    {
        //println!("des tuple struct: {}", self.exp);
        let v = match self.exp.take_list() {
            Ok(v) => v,
            _ => return Err(Error::Decoder(format!("expecting list for tuple struct, got {}", self.exp))),
        };
        if v.len() != len + 1 {
            return Err(Error::Decoder(format!("expecting {} elements for tuple struct \
                                               in {}",
                                              len,
                                              Sexp::List(v))));
        }
        let name2 = try!(v[0].string()).to_lowercase();
        let name = name.to_lowercase();
        if name != name2 {
            return Err(Error::Decoder(format!("expecting name {} got {} in {}",
                                              name,
                                              name2,
                                              Sexp::List(v))));
        }
        visitor.visit_seq(SeqVisitor::new(v, true))
    }

    fn deserialize_struct<V>(&mut self,
                             name: &'static str,
                             _fields: &'static [&'static str],
                             mut visitor: V)
                             -> Result<V::Value>
        where V: de::Visitor
    {
        let v = match self.exp.take_list() {
            Ok(v) => v,
            _ => return Err(Error::Decoder(format!("expecting list for deserialize struct, got {}", self.exp))),
        };
        if v.len() < 1 {
            return Err(Error::Decoder(format!("missing struct name {} in {:?}",
                                              name,
                                              v)));
        }
        let name2 = try!(v[0].string()).to_lowercase();
        let name = name.to_lowercase();
        if name != name2 {
            return Err(Error::Decoder(format!("expecting name {} got {} in {}",
                                              name,
                                              name2,
                                              self.exp)));
        }
        visitor.visit_map(StructVisitor::new(v))
    }

    fn deserialize_seq<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        //println!("des seq: {}", self.exp);
        let v = try!(self.exp.take_list());
        visitor.visit_seq(SeqVisitor::new(v, false))
    }

    fn deserialize_newtype_struct<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        //println!("des newtype: {} {}", name, self.exp);
        // if the name is the first element of a list
        // consider the list without the first element to be the
        // content of the struct
        let name = name.to_lowercase();
        let mut found = false;
        {
            if self.exp.is_list() {
                let v = try!(self.exp.list()); // Ok
                if v.len() > 1 {
                    if v[0].is_string() {
                        let s = try!(v[0].string());
                        if name.as_str() == s.as_str() {
                            found = true;
                        }
                    }
                }
            }
        }
        if found {
            let mut v = try!(self.exp.take_list());
            v.remove(0);
            let exp = Sexp::List(v);
            return visitor.visit_newtype_struct(&mut Deserializer::new(exp))
        }
        // Parses a newtype struct as the underlying value.
        visitor.visit_newtype_struct(self)
    }

    fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_some(self)
    }

    fn deserialize_enum<V>(&mut self,
                           name: &'static str,
                           variants: &'static [&'static str],
                           mut visitor: V)
                           -> Result<V::Value> where V: de::EnumVisitor {
        //println!("Variant: name: {}", name);
        let mut exp = self.take();
        if exp.is_list() {
            let (found, found_name, v) = {
                let mut v = try!(exp.take_list());
                if v.len() < 1 {
                    return Err(Error::Decoder(format!("missing variant name in {:?} in {}",
                                                      v,
                                                      name)));
                }
                let found_name = try!(v[0].string()).to_lowercase();
                let mut found = false;
                let mut variant_found:String = "".into();
                for &variant in variants {
                    if variant.to_lowercase() == found_name {
                        found = true;
                        variant_found.push_str(variant);
                        v[0] = Sexp::String(variant.into());
                        break
                    }
                }
                (found, found_name, v)
            };
            if found {
                let l = Sexp::List(v);
                //println!(".... going for {}", l);
                visitor.visit(VariantVisitor::new(l))
            } else {
                Err(Error::Decoder(format!("unknown variant {} in {}", found_name, name)))
            }
        } else if exp.is_string() {
            let s = try!(exp.take_string());
            let mut found = false;
            let mut variant_found:String = "".into();
            for &variant in variants {
                if variant.to_lowercase() == s {
                    found = true;
                    variant_found.push_str(variant);
                    break
                }
            }
            if found {
                visitor.visit(VariantVisitor::new(Sexp::String(variant_found)))
            } else {
                Err(Error::Decoder(format!("unknown variant {} in {}", s, name)))
            }
        } else {
            Err(Error::Decoder("can't do variant for Empty".into()))
        }
    }

    forward_to_deserialize!{
        bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
        seq_fixed_size bytes map unit_struct
        struct_field tuple ignored_any
    }
}

struct SeqVisitor {
    seq: Vec<Sexp>,
    i: usize,
}

impl SeqVisitor {
    fn new(seq: Vec<Sexp>, skip: bool) -> Self {
        let i = if skip {
            1
        } else {
            0
        };
        SeqVisitor { seq: seq, i: i }
    }
}

impl de::SeqVisitor for SeqVisitor {
    type Error = Error;

    fn visit<T>(&mut self) -> Result<Option<T>>
        where T: de::Deserialize
    {
        if self.i >= self.seq.len() {
            return Ok(None);
        }
        //println!("seq Visit {}", self.i);
        let mut t = Sexp::Empty;
        mem::swap(&mut t, &mut self.seq[self.i]);
        self.i += 1;
        de::Deserialize::deserialize(&mut Deserializer::new(t)).map(Some)
    }

    fn end(&mut self) -> Result<()> {
        Ok(())
    }
}

struct StructVisitor {
    seq: Vec<Sexp>,
    i: usize,
    value: Option<Sexp>,
}

impl<'a> StructVisitor {
    fn new(seq: Vec<Sexp>) -> Self {
        StructVisitor {
            seq: seq,
            i: 1,
            value: None,
        }
    }
}

impl de::MapVisitor for StructVisitor {
    type Error = Error;

    fn visit_key<K>(&mut self) -> Result<Option<K>>
        where K: de::Deserialize
    {
        if self.i >= self.seq.len() {
            return Ok(None);
        }
        let mut exp = Sexp::Empty;
        mem::swap(&mut exp, &mut self.seq[self.i]);
        self.i += 1;
        let mut v = try!(exp.take_list());
        if v.len() < 2 {
            return Err(Error::Decoder(format!("can't decode as map: {:?}", v)));
        }
        if v[0].is_string() {
            if v.len() == 2 {
                let mut value = Sexp::Empty;
                mem::swap(&mut value, &mut v[1]);
                self.value = Some(value);
                let mut key = Sexp::Empty;
                mem::swap(&mut key, &mut v[0]);
                de::Deserialize::deserialize(&mut Deserializer::new(key)).map(Some)
            } else {
                // deserialize whole element, which could be a tuple struct
                let key = v[0].clone();
                self.value = Some(Sexp::List(v));
                de::Deserialize::deserialize(&mut Deserializer::new(key)).map(Some)
            }
        } else {
            return Err(Error::Decoder(format!("key is not a string: {}", v[0])));
        }
    }

    fn visit_value<V>(&mut self) -> Result<V>
        where V: de::Deserialize
    {
        let vo = self.value.take();
        match vo {
            Some(v) => de::Deserialize::deserialize(&mut Deserializer::new(v)),
            None => Err(Error::Decoder(format!("missing value!"))),
        }
    }

    fn end(&mut self) -> Result<()> {
        Ok(())
    }

    fn missing_field<V>(&mut self, field: &'static str) -> Result<V>
        where V: de::Deserialize
    {
        struct MissingFieldDeserializer(&'static str);

        impl de::Deserializer for MissingFieldDeserializer {
            type Error = Error;

            fn deserialize<V>(&mut self, _visitor: V) -> Result<V::Value>
                where V: de::Visitor
            {
                Err(de::Error::missing_field(self.0))
            }

            fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value>
                where V: de::Visitor
            {
                visitor.visit_none()
            }

            forward_to_deserialize!{
                bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
                string unit seq seq_fixed_size bytes map unit_struct
                newtype_struct tuple_struct struct struct_field tuple enum
                ignored_any
            }
        }

        let mut de = MissingFieldDeserializer(field);
        Ok(try!(de::Deserialize::deserialize(&mut de)))
    }
}

struct VariantVisitor {
    exp:Sexp,
}

impl VariantVisitor {
    fn new(exp:Sexp) -> Self {
        VariantVisitor { exp:exp }
    }

    fn take(&mut self) -> Sexp {
        let mut exp = Sexp::Empty;
        mem::swap(&mut exp, &mut self.exp);
        exp
    }
}

impl de::VariantVisitor for VariantVisitor {
    type Error = Error;

    fn visit_variant<V>(&mut self) -> Result<V>
        where V: de::Deserialize {
        //println!("VariantVisitor: {}", self.exp);
        match self.exp {
            Sexp::String(_) => {
                de::Deserialize::deserialize(&mut Deserializer::new(self.exp.clone()))
            },
            Sexp::List(ref v) => {
                if v.len() >= 1 {
                    if v[0].is_string() {
                        de::Deserialize::deserialize(&mut Deserializer::new(v[0].clone()))

                    } else {
                        Err(Error::Decoder(format!("unexpected non-string in Variant name {}", v[0])))
                    }
                } else {
                    Err(Error::Decoder(format!("unexpected empty list in Variant {}", self.exp)))
                }
            },
            Sexp::Empty => Err(Error::Decoder(format!("unexpected Empty in Variant {}", self.exp)))
        }
    }

    fn visit_unit(&mut self) -> Result<()> {
        Ok(())
    }

    fn visit_newtype<T>(&mut self) -> Result<T>
        where T: de::Deserialize,
    {
        let mut exp = self.take();
        match exp {
            Sexp::String(_) => de::Deserialize::deserialize(&mut Deserializer::new(exp)),
            Sexp::List(_) => {
                let v = try!(exp.take_list());
                if v.len() < 2 {
                    return Err(Error::Decoder(format!("not enough elements in variant: {:?}", v)))
                }
                de::Deserialize::deserialize(&mut Deserializer::new(v[1].clone()))
            },
            Sexp::Empty => Err(Error::Decoder(format!("unexpected Empty in Variant visit_newtype {}", self.exp))),
        }
    }

    fn visit_tuple<V>(&mut self, _len: usize, visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        de::Deserializer::deserialize(&mut Deserializer::new(self.take()),
                                      visitor)
    }

    fn visit_struct<V>(
        &mut self,
        _fields: &'static [&'static str],
        visitor: V
    ) -> Result<V::Value>
        where V: de::Visitor,
    {
        //println!("VariantVisitor::visit_struct: {}", self.exp);
        de::Deserializer::deserialize(&mut Deserializer::new(self.take()),
                                      visitor)
    }
}
<commit_msg>don't special case two element subs<commit_after>// (c) 2016 Joost Yervante Damad <joost@productize.be>

use serde;
use serde::de;
use std::mem;

use Sexp;

use error::{Result, Error};

// loosely based on serde-yaml, toml-rs, serde_json

/// decode a symbolic expression to a rust expression using serde
pub fn decode<T: serde::Deserialize>(exp: Sexp) -> Result<T> {
    serde::Deserialize::deserialize(&mut Deserializer::new(exp))
}

struct Deserializer {
    pub exp: Sexp,
}

impl Deserializer {
    pub fn new(exp: Sexp) -> Deserializer {
        Deserializer { exp: exp }
    }

    pub fn take(&mut self) -> Sexp {
        let mut exp = Sexp::Empty;
        mem::swap(&mut exp, &mut self.exp);
        exp
    }
}

impl de::Deserializer for Deserializer {
    type Error = Error;

    /// called when we call deserialize below for a nested part
    fn deserialize<V>(&mut self, visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        //println!("deserialize: {}", self.exp);
        if self.exp.is_string() {
            return self.deserialize_string(visitor)
        }
        if self.exp.is_list() {
            return self.deserialize_seq(visitor)
        }
        Err(Error::Decoder(format!("expecting specific deserializer to be called for {}", self.exp)))
    }

    /// deserialize any string in a symbolic expression
    fn deserialize_string<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_string(try!(self.exp.take_string()))
    }

    /// the empty symbolic-expression
    fn deserialize_unit<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        match self.exp {
            Sexp::Empty => visitor.visit_unit(),
            _ => Err(Error::Decoder(format!("expecting unit got {}", self.exp))),
        }
    }

    /// a symbolic expression of the form (name value1 value2 ...)
    fn deserialize_tuple_struct<V>(&mut self,
                                   name: &'static str,
                                   len: usize,
                                   mut visitor: V)
                                   -> Result<V::Value>
        where V: de::Visitor
    {
        //println!("des tuple struct: {}", self.exp);
        let v = match self.exp.take_list() {
            Ok(v) => v,
            _ => return Err(Error::Decoder(format!("expecting list for tuple struct, got {}", self.exp))),
        };
        if v.len() != len + 1 {
            return Err(Error::Decoder(format!("expecting {} elements for tuple struct \
                                               in {}",
                                              len,
                                              Sexp::List(v))));
        }
        let name2 = try!(v[0].string()).to_lowercase();
        let name = name.to_lowercase();
        if name != name2 {
            return Err(Error::Decoder(format!("expecting name {} got {} in {}",
                                              name,
                                              name2,
                                              Sexp::List(v))));
        }
        visitor.visit_seq(SeqVisitor::new(v, true))
    }

    fn deserialize_struct<V>(&mut self,
                             name: &'static str,
                             _fields: &'static [&'static str],
                             mut visitor: V)
                             -> Result<V::Value>
        where V: de::Visitor
    {
        let v = match self.exp.take_list() {
            Ok(v) => v,
            _ => return Err(Error::Decoder(format!("expecting list for deserialize struct, got {}", self.exp))),
        };
        if v.len() < 1 {
            return Err(Error::Decoder(format!("missing struct name {} in {:?}",
                                              name,
                                              v)));
        }
        let name2 = try!(v[0].string()).to_lowercase();
        let name = name.to_lowercase();
        if name != name2 {
            return Err(Error::Decoder(format!("expecting name {} got {} in {}",
                                              name,
                                              name2,
                                              self.exp)));
        }
        visitor.visit_map(StructVisitor::new(v))
    }

    fn deserialize_seq<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        //println!("des seq: {}", self.exp);
        let v = try!(self.exp.take_list());
        visitor.visit_seq(SeqVisitor::new(v, false))
    }

    fn deserialize_newtype_struct<V>(&mut self, name: &str, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        //println!("des newtype: {} {}", name, self.exp);
        // if the name is the first element of a list
        // consider the list without the first element to be the
        // content of the struct
        let name = name.to_lowercase();
        let mut found = false;
        {
            if self.exp.is_list() {
                let v = try!(self.exp.list()); // Ok
                if v.len() > 2 {
                    if v[0].is_string() {
                        let s = try!(v[0].string());
                        if name.as_str() == s.as_str() {
                            found = true;
                        }
                    }
                }
            }
        }
        if found {
            let mut v = try!(self.exp.take_list());
            v.remove(0);
            let exp = Sexp::List(v);
            return visitor.visit_newtype_struct(&mut Deserializer::new(exp))
        }
        // Parses a newtype struct as the underlying value.
        visitor.visit_newtype_struct(self)
    }

    fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value>
        where V: de::Visitor
    {
        visitor.visit_some(self)
    }

    fn deserialize_enum<V>(&mut self,
                           name: &'static str,
                           variants: &'static [&'static str],
                           mut visitor: V)
                           -> Result<V::Value> where V: de::EnumVisitor {
        //println!("Variant: name: {}", name);
        let mut exp = self.take();
        if exp.is_list() {
            let (found, found_name, v) = {
                let mut v = try!(exp.take_list());
                if v.len() < 1 {
                    return Err(Error::Decoder(format!("missing variant name in {:?} in {}",
                                                      v,
                                                      name)));
                }
                let found_name = try!(v[0].string()).to_lowercase();
                let mut found = false;
                let mut variant_found:String = "".into();
                for &variant in variants {
                    if variant.to_lowercase() == found_name {
                        found = true;
                        variant_found.push_str(variant);
                        v[0] = Sexp::String(variant.into());
                        break
                    }
                }
                (found, found_name, v)
            };
            if found {
                let l = Sexp::List(v);
                //println!(".... going for {}", l);
                visitor.visit(VariantVisitor::new(l))
            } else {
                Err(Error::Decoder(format!("unknown variant {} in {}", found_name, name)))
            }
        } else if exp.is_string() {
            let s = try!(exp.take_string());
            let mut found = false;
            let mut variant_found:String = "".into();
            for &variant in variants {
                if variant.to_lowercase() == s {
                    found = true;
                    variant_found.push_str(variant);
                    break
                }
            }
            if found {
                visitor.visit(VariantVisitor::new(Sexp::String(variant_found)))
            } else {
                Err(Error::Decoder(format!("unknown variant {} in {}", s, name)))
            }
        } else {
            Err(Error::Decoder("can't do variant for Empty".into()))
        }
    }

    forward_to_deserialize!{
        bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
        seq_fixed_size bytes map unit_struct
        struct_field tuple ignored_any
    }
}

struct SeqVisitor {
    seq: Vec<Sexp>,
    i: usize,
}

impl SeqVisitor {
    fn new(seq: Vec<Sexp>, skip: bool) -> Self {
        let i = if skip {
            1
        } else {
            0
        };
        SeqVisitor { seq: seq, i: i }
    }
}

impl de::SeqVisitor for SeqVisitor {
    type Error = Error;

    fn visit<T>(&mut self) -> Result<Option<T>>
        where T: de::Deserialize
    {
        if self.i >= self.seq.len() {
            return Ok(None);
        }
        //println!("seq Visit {}", self.i);
        let mut t = Sexp::Empty;
        mem::swap(&mut t, &mut self.seq[self.i]);
        self.i += 1;
        de::Deserialize::deserialize(&mut Deserializer::new(t)).map(Some)
    }

    fn end(&mut self) -> Result<()> {
        Ok(())
    }
}

struct StructVisitor {
    seq: Vec<Sexp>,
    i: usize,
    value: Option<Sexp>,
}

impl<'a> StructVisitor {
    fn new(seq: Vec<Sexp>) -> Self {
        StructVisitor {
            seq: seq,
            i: 1,
            value: None,
        }
    }
}

impl de::MapVisitor for StructVisitor {
    type Error = Error;

    fn visit_key<K>(&mut self) -> Result<Option<K>>
        where K: de::Deserialize
    {
        if self.i >= self.seq.len() {
            return Ok(None);
        }
        let mut exp = Sexp::Empty;
        mem::swap(&mut exp, &mut self.seq[self.i]);
        self.i += 1;
        let mut v = try!(exp.take_list());
        if v.len() < 2 {
            return Err(Error::Decoder(format!("can't decode as map: {:?}", v)));
        }
        if v[0].is_string() {
            if v.len() == 2 {
                let mut value = Sexp::Empty;
                mem::swap(&mut value, &mut v[1]);
                self.value = Some(value);
                let mut key = Sexp::Empty;
                mem::swap(&mut key, &mut v[0]);
                de::Deserialize::deserialize(&mut Deserializer::new(key)).map(Some)
            } else {
                // deserialize whole element, which could be a tuple struct
                let key = v[0].clone();
                self.value = Some(Sexp::List(v));
                de::Deserialize::deserialize(&mut Deserializer::new(key)).map(Some)
            }
        } else {
            return Err(Error::Decoder(format!("key is not a string: {}", v[0])));
        }
    }

    fn visit_value<V>(&mut self) -> Result<V>
        where V: de::Deserialize
    {
        let vo = self.value.take();
        match vo {
            Some(v) => de::Deserialize::deserialize(&mut Deserializer::new(v)),
            None => Err(Error::Decoder(format!("missing value!"))),
        }
    }

    fn end(&mut self) -> Result<()> {
        Ok(())
    }

    fn missing_field<V>(&mut self, field: &'static str) -> Result<V>
        where V: de::Deserialize
    {
        struct MissingFieldDeserializer(&'static str);

        impl de::Deserializer for MissingFieldDeserializer {
            type Error = Error;

            fn deserialize<V>(&mut self, _visitor: V) -> Result<V::Value>
                where V: de::Visitor
            {
                Err(de::Error::missing_field(self.0))
            }

            fn deserialize_option<V>(&mut self, mut visitor: V) -> Result<V::Value>
                where V: de::Visitor
            {
                visitor.visit_none()
            }

            forward_to_deserialize!{
                bool usize u8 u16 u32 u64 isize i8 i16 i32 i64 f32 f64 char str
                string unit seq seq_fixed_size bytes map unit_struct
                newtype_struct tuple_struct struct struct_field tuple enum
                ignored_any
            }
        }

        let mut de = MissingFieldDeserializer(field);
        Ok(try!(de::Deserialize::deserialize(&mut de)))
    }
}

struct VariantVisitor {
    exp:Sexp,
}

impl VariantVisitor {
    fn new(exp:Sexp) -> Self {
        VariantVisitor { exp:exp }
    }

    fn take(&mut self) -> Sexp {
        let mut exp = Sexp::Empty;
        mem::swap(&mut exp, &mut self.exp);
        exp
    }
}

impl de::VariantVisitor for VariantVisitor {
    type Error = Error;

    fn visit_variant<V>(&mut self) -> Result<V>
        where V: de::Deserialize {
        //println!("VariantVisitor: {}", self.exp);
        match self.exp {
            Sexp::String(_) => {
                de::Deserialize::deserialize(&mut Deserializer::new(self.exp.clone()))
            },
            Sexp::List(ref v) => {
                if v.len() >= 1 {
                    if v[0].is_string() {
                        de::Deserialize::deserialize(&mut Deserializer::new(v[0].clone()))

                    } else {
                        Err(Error::Decoder(format!("unexpected non-string in Variant name {}", v[0])))
                    }
                } else {
                    Err(Error::Decoder(format!("unexpected empty list in Variant {}", self.exp)))
                }
            },
            Sexp::Empty => Err(Error::Decoder(format!("unexpected Empty in Variant {}", self.exp)))
        }
    }

    fn visit_unit(&mut self) -> Result<()> {
        Ok(())
    }

    fn visit_newtype<T>(&mut self) -> Result<T>
        where T: de::Deserialize,
    {
        let mut exp = self.take();
        match exp {
            Sexp::String(_) => de::Deserialize::deserialize(&mut Deserializer::new(exp)),
            Sexp::List(_) => {
                let v = try!(exp.take_list());
                if v.len() < 2 {
                    return Err(Error::Decoder(format!("not enough elements in variant: {:?}", v)))
                }
                de::Deserialize::deserialize(&mut Deserializer::new(v[1].clone()))
            },
            Sexp::Empty => Err(Error::Decoder(format!("unexpected Empty in Variant visit_newtype {}", self.exp))),
        }
    }

    fn visit_tuple<V>(&mut self, _len: usize, visitor: V) -> Result<V::Value>
        where V: de::Visitor,
    {
        de::Deserializer::deserialize(&mut Deserializer::new(self.take()),
                                      visitor)
    }

    fn visit_struct<V>(
        &mut self,
        _fields: &'static [&'static str],
        visitor: V
    ) -> Result<V::Value>
        where V: de::Visitor,
    {
        //println!("VariantVisitor::visit_struct: {}", self.exp);
        de::Deserializer::deserialize(&mut Deserializer::new(self.take()),
                                      visitor)
    }
}
<|endoftext|>