<commit_before>use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
use std::marker::PhantomData;

// What does this do? You'll never guess!
type HeapId<'a> = PhantomData<std::cell::Cell<&'a mut ()>>;

// The heap is (for now) just a big Vec of Pairs
pub struct Heap<'a> {
    id: HeapId<'a>,
    storage: Vec<PairStorage<'a>>,
    freelist: *mut PairStorage<'a>,
    pins: RefCell<HashMap<*mut PairStorage<'a>, usize>>
}

pub const HEAP_SIZE: usize = 10000;

pub fn with_heap<F, O>(f: F) -> O
    where F: for<'a> FnOnce(&mut Heap<'a>) -> O
{
    f(&mut Heap::new())
}

unsafe trait Mark {
    unsafe fn mark(ptr: *mut Self);
}

unsafe trait HeapInline {
    type Heap;
    type Storage;
    unsafe fn from_heap(heap: &Self::Heap, ptr: &Self::Storage) -> Self;
    fn to_heap(self) -> Self::Storage;
}

impl<'a> Heap<'a> {
    fn new() -> Heap<'a> {
        // Allocate with the full capacity so that allocated Pairs never move
        let mut h = Heap {
            id: PhantomData,
            storage: Vec::with_capacity(HEAP_SIZE),
            freelist: std::ptr::null_mut(),
            pins: RefCell::new(HashMap::new())
        };
        for i in 0 .. HEAP_SIZE {
            h.storage.push(PairStorage {
                marked: false,
                head: ValueStorage::Null,
                tail: ValueStorage::Null
            });
            let p = &mut h.storage[i] as *mut PairStorage<'a>;
            unsafe {
                h.add_to_free_list(p);
            }
        }
        h
    }

    fn pin(&self, p: *mut PairStorage<'a>) {
        let mut pins = self.pins.borrow_mut();
        let entry = pins.entry(p).or_insert(0);
        *entry += 1;
    }

    fn unpin(&self, p: *mut PairStorage<'a>) {
        let mut pins = self.pins.borrow_mut();
        if {
            let entry = pins.entry(p).or_insert(0);
            assert!(*entry != 0);
            *entry -= 1;
            *entry == 0
        } {
            pins.remove(&p);
        }
    }

    unsafe fn add_to_free_list(&mut self, p: *mut PairStorage<'a>) {
        let listp: *mut *mut PairStorage<'a> = std::mem::transmute(p);
        *listp = self.freelist;
        assert_eq!(*listp, self.freelist);
        self.freelist = p;
    }

    pub fn try_alloc(&mut self, pair: (Value<'a>, Value<'a>)) -> Option<Pair<'a>> {
        if self.freelist.is_null() {
            unsafe {
                self.gc();
            }
            if self.freelist.is_null() {
                return None;
            }
        }

        let p = self.freelist;
        unsafe {
            let listp: *mut *mut PairStorage<'a> = std::mem::transmute(p);
            self.freelist = *listp;

            let (h, t) = pair;
            *p = PairStorage {
                marked: false,
                head: h.to_heap(),
                tail: t.to_heap()
            };
            Some(Pair::new(self, p))
        }
    }

    pub fn alloc(&mut self, pair: (Value<'a>, Value<'a>)) -> Pair<'a> {
        self.try_alloc(pair).expect("out of memory (gc did not collect anything)")
    }

    pub fn alloc_null(&mut self) -> Pair<'a> {
        self.alloc((Value::Null, Value::Null))
    }

    unsafe fn gc(&mut self) {
        // clear mark bits
        for p in &mut self.storage {
            p.marked = false;
        }

        // mark phase
        for (&p, _) in self.pins.borrow().iter() {
            Mark::mark(p);
        }

        // sweep phase
        self.freelist = std::ptr::null_mut();
        for i in 0 .. HEAP_SIZE {
            let p = &mut self.storage[i] as *mut PairStorage<'a>;
            if !(*p).marked {
                self.add_to_free_list(p);
            }
        }
    }

    #[cfg(test)]
    pub fn force_gc(&mut self) {
        unsafe { self.gc(); }
    }
}

// === Pair, the reference type

// PairStorage is the only type that is actually allocated inside the heap (private)
struct PairStorage<'a> {
    marked: bool,
    head: ValueStorage<'a>,
    tail: ValueStorage<'a>
}

unsafe impl<'a> Mark for PairStorage<'a> {
    unsafe fn mark(ptr: *mut PairStorage<'a>) {
        if !ptr.is_null() && !(*ptr).marked {
            (*ptr).marked = true;
            Mark::mark(&mut (*ptr).head as *mut ValueStorage<'a>);
            Mark::mark(&mut (*ptr).tail as *mut ValueStorage<'a>);
        }
    }
}

// Handle to a PairStorage that lives in the heap.
#[allow(raw_pointer_derive)]
#[derive(Debug, PartialEq)]
pub struct Pair<'a> {
    ptr: *mut PairStorage<'a>,
    heap: *const Heap<'a>,
    heap_id: HeapId<'a>
}

impl<'a> Drop for Pair<'a> {
    fn drop(&mut self) {
        unsafe {
            (*self.heap).unpin(self.ptr);
        }
    }
}

impl<'a> Clone for Pair<'a> {
    fn clone(&self) -> Pair<'a> {
        let &Pair { ptr, heap, heap_id } = self;
        unsafe {
            (*heap).pin(ptr);
        }
        Pair {
            ptr: ptr,
            heap: heap,
            heap_id: heap_id
        }
    }
}

impl<'a> Pair<'a> {
    unsafe fn new(heap: &Heap<'a>, p: *mut PairStorage<'a>) -> Pair<'a> {
        heap.pin(p);
        Pair {
            ptr: p,
            heap: heap as *const Heap<'a>,
            heap_id: heap.id
        }
    }

    pub fn head(&self) -> Value<'a> {
        let ptr = self.ptr;
        unsafe { Value::from_heap(&*self.heap, &(*ptr).head) }
    }

    pub fn tail(&self) -> Value<'a> {
        let ptr = self.ptr;
        unsafe { Value::from_heap(&*self.heap, &(*ptr).tail) }
    }

    pub fn set_head(&self, v: Value<'a>) {
        let ptr = self.ptr;
        unsafe { (*ptr).head = v.to_heap(); }
    }

    pub fn set_tail(&self, v: Value<'a>) {
        let ptr = self.ptr;
        unsafe { (*ptr).tail = v.to_heap(); }
    }

    #[cfg(test)]
    pub fn address(&self) -> usize {
        unsafe { std::mem::transmute(self.ptr) }
    }
}

// === Values (a heap-inline enum)

// Values inside the heap (GC heap-to-heap cross-references) (private)
enum ValueStorage<'a> {
    Null,
    Int(i32),
    Str(Rc<String>),
    Pair(*mut PairStorage<'a>, HeapId<'a>)
}

unsafe impl<'a> Mark for ValueStorage<'a> {
    unsafe fn mark(ptr: *mut ValueStorage<'a>) {
        match *ptr {
            ValueStorage::Pair(p, _) => Mark::mark(p),
            _ => {}
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum Value<'a> {
    Null,
    Int(i32),
    Str(Rc<String>),  // <-- equality is by value
    Pair(Pair<'a>)  // <-- equality is by pointer
}

unsafe impl<'a> HeapInline for Value<'a> {
    type Heap = Heap<'a>;
    type Storage = ValueStorage<'a>;

    fn to_heap(self) -> ValueStorage<'a> {
        match self {
            Value::Null => ValueStorage::Null,
            Value::Int(n) => ValueStorage::Int(n),
            Value::Str(rcstr) => ValueStorage::Str(rcstr),
            Value::Pair(Pair{ptr, heap_id, ..}) => ValueStorage::Pair(ptr, heap_id)
        }
    }

    unsafe fn from_heap(heap: &Heap<'a>, v: &ValueStorage<'a>) -> Value<'a> {
        match v {
            &ValueStorage::Null => Value::Null,
            &ValueStorage::Int(n) => Value::Int(n),
            &ValueStorage::Str(ref rcstr) => Value::Str(rcstr.clone()),
            &ValueStorage::Pair(ptr, _) => Value::Pair(Pair::new(heap, ptr))
        }
    }
}

#[cfg(test)]
mod test;
<commit_msg>Comments.<commit_after>use std::rc::Rc;
use std::cell::RefCell;
use std::collections::HashMap;
use std::marker::PhantomData;

// What does this do? You'll never guess!
type HeapId<'a> = PhantomData<std::cell::Cell<&'a mut ()>>;

// The heap is (for now) just a big Vec of Pairs
pub struct Heap<'a> {
    id: HeapId<'a>,
    storage: Vec<PairStorage<'a>>,
    freelist: *mut PairStorage<'a>,
    pins: RefCell<HashMap<*mut PairStorage<'a>, usize>>
}

pub const HEAP_SIZE: usize = 10000;

/// Create a heap, pass it to a callback, then destroy the heap.
///
/// The heap's lifetime is directly tied to this function call, for safety. (So
/// the API is a little wonky --- but how many heaps were you planning on
/// creating?)
pub fn with_heap<F, O>(f: F) -> O
    where F: for<'a> FnOnce(&mut Heap<'a>) -> O
{
    f(&mut Heap::new())
}

/// Trait implemented by all types that can be stored directly in the GC heap:
/// the `Storage` types associated with any `HeapInline` or `HeapRef` type.
///
/// XXX maybe this should not be its own trait - fold into HeapInline?
///
unsafe trait Mark {
    unsafe fn mark(ptr: *mut Self);
}

unsafe trait HeapInline {
    type Heap;
    type Storage;
    unsafe fn from_heap(heap: &Self::Heap, ptr: &Self::Storage) -> Self;
    fn to_heap(self) -> Self::Storage;
}

impl<'a> Heap<'a> {
    fn new() -> Heap<'a> {
        // Allocate with the full capacity so that allocated Pairs never move
        let mut h = Heap {
            id: PhantomData,
            storage: Vec::with_capacity(HEAP_SIZE),
            freelist: std::ptr::null_mut(),
            pins: RefCell::new(HashMap::new())
        };
        for i in 0 .. HEAP_SIZE {
            h.storage.push(PairStorage {
                marked: false,
                head: ValueStorage::Null,
                tail: ValueStorage::Null
            });
            let p = &mut h.storage[i] as *mut PairStorage<'a>;
            unsafe {
                h.add_to_free_list(p);
            }
        }
        h
    }

    fn pin(&self, p: *mut PairStorage<'a>) {
        let mut pins = self.pins.borrow_mut();
        let entry = pins.entry(p).or_insert(0);
        *entry += 1;
    }

    fn unpin(&self, p: *mut PairStorage<'a>) {
        let mut pins = self.pins.borrow_mut();
        if {
            let entry = pins.entry(p).or_insert(0);
            assert!(*entry != 0);
            *entry -= 1;
            *entry == 0
        } {
            pins.remove(&p);
        }
    }

    unsafe fn add_to_free_list(&mut self, p: *mut PairStorage<'a>) {
        let listp: *mut *mut PairStorage<'a> = std::mem::transmute(p);
        *listp = self.freelist;
        assert_eq!(*listp, self.freelist);
        self.freelist = p;
    }

    pub fn try_alloc(&mut self, pair: (Value<'a>, Value<'a>)) -> Option<Pair<'a>> {
        if self.freelist.is_null() {
            unsafe {
                self.gc();
            }
            if self.freelist.is_null() {
                return None;
            }
        }

        let p = self.freelist;
        unsafe {
            let listp: *mut *mut PairStorage<'a> = std::mem::transmute(p);
            self.freelist = *listp;

            let (h, t) = pair;
            *p = PairStorage {
                marked: false,
                head: h.to_heap(),
                tail: t.to_heap()
            };
            Some(Pair::new(self, p))
        }
    }

    pub fn alloc(&mut self, pair: (Value<'a>, Value<'a>)) -> Pair<'a> {
        self.try_alloc(pair).expect("out of memory (gc did not collect anything)")
    }

    pub fn alloc_null(&mut self) -> Pair<'a> {
        self.alloc((Value::Null, Value::Null))
    }

    unsafe fn gc(&mut self) {
        // clear mark bits
        for p in &mut self.storage {
            p.marked = false;
        }

        // mark phase
        for (&p, _) in self.pins.borrow().iter() {
            Mark::mark(p);
        }

        // sweep phase
        self.freelist = std::ptr::null_mut();
        for i in 0 .. HEAP_SIZE {
            let p = &mut self.storage[i] as *mut PairStorage<'a>;
            if !(*p).marked {
                self.add_to_free_list(p);
            }
        }
    }

    #[cfg(test)]
    pub fn force_gc(&mut self) {
        unsafe { self.gc(); }
    }
}

// === Pair, the reference type

// PairStorage is the only type that is actually allocated inside the heap (private)
struct PairStorage<'a> {
    marked: bool,
    head: ValueStorage<'a>,
    tail: ValueStorage<'a>
}

unsafe impl<'a> Mark for PairStorage<'a> {
    unsafe fn mark(ptr: *mut PairStorage<'a>) {
        if !ptr.is_null() && !(*ptr).marked {
            (*ptr).marked = true;
            Mark::mark(&mut (*ptr).head as *mut ValueStorage<'a>);
            Mark::mark(&mut (*ptr).tail as *mut ValueStorage<'a>);
        }
    }
}

// Handle to a PairStorage that lives in the heap.
#[allow(raw_pointer_derive)]
#[derive(Debug, PartialEq)]
pub struct Pair<'a> {
    ptr: *mut PairStorage<'a>,
    heap: *const Heap<'a>,
    heap_id: HeapId<'a>
}

impl<'a> Drop for Pair<'a> {
    fn drop(&mut self) {
        unsafe {
            (*self.heap).unpin(self.ptr);
        }
    }
}

impl<'a> Clone for Pair<'a> {
    fn clone(&self) -> Pair<'a> {
        let &Pair { ptr, heap, heap_id } = self;
        unsafe {
            (*heap).pin(ptr);
        }
        Pair {
            ptr: ptr,
            heap: heap,
            heap_id: heap_id
        }
    }
}

impl<'a> Pair<'a> {
    unsafe fn new(heap: &Heap<'a>, p: *mut PairStorage<'a>) -> Pair<'a> {
        heap.pin(p);
        Pair {
            ptr: p,
            heap: heap as *const Heap<'a>,
            heap_id: heap.id
        }
    }

    pub fn head(&self) -> Value<'a> {
        let ptr = self.ptr;
        unsafe { Value::from_heap(&*self.heap, &(*ptr).head) }
    }

    pub fn tail(&self) -> Value<'a> {
        let ptr = self.ptr;
        unsafe { Value::from_heap(&*self.heap, &(*ptr).tail) }
    }

    pub fn set_head(&self, v: Value<'a>) {
        let ptr = self.ptr;
        unsafe { (*ptr).head = v.to_heap(); }
    }

    pub fn set_tail(&self, v: Value<'a>) {
        let ptr = self.ptr;
        unsafe { (*ptr).tail = v.to_heap(); }
    }

    #[cfg(test)]
    pub fn address(&self) -> usize {
        unsafe { std::mem::transmute(self.ptr) }
    }
}

// === Values (a heap-inline enum)

// Values inside the heap (GC heap-to-heap cross-references) (private)
enum ValueStorage<'a> {
    Null,
    Int(i32),
    Str(Rc<String>),
    Pair(*mut PairStorage<'a>, HeapId<'a>)
}

unsafe impl<'a> Mark for ValueStorage<'a> {
    unsafe fn mark(ptr: *mut ValueStorage<'a>) {
        match *ptr {
            ValueStorage::Pair(p, _) => Mark::mark(p),
            _ => {}
        }
    }
}

#[derive(Debug, Clone, PartialEq)]
pub enum Value<'a> {
    Null,
    Int(i32),
    Str(Rc<String>),  // <-- equality is by value
    Pair(Pair<'a>)  // <-- equality is by pointer
}

unsafe impl<'a> HeapInline for Value<'a> {
    type Heap = Heap<'a>;
    type Storage = ValueStorage<'a>;

    fn to_heap(self) -> ValueStorage<'a> {
        match self {
            Value::Null => ValueStorage::Null,
            Value::Int(n) => ValueStorage::Int(n),
            Value::Str(rcstr) => ValueStorage::Str(rcstr),
            Value::Pair(Pair{ptr, heap_id, ..}) => ValueStorage::Pair(ptr, heap_id)
        }
    }

    unsafe fn from_heap(heap: &Heap<'a>, v: &ValueStorage<'a>) -> Value<'a> {
        match v {
            &ValueStorage::Null => Value::Null,
            &ValueStorage::Int(n) => Value::Int(n),
            &ValueStorage::Str(ref rcstr) => Value::Str(rcstr.clone()),
            &ValueStorage::Pair(ptr, _) => Value::Pair(Pair::new(heap, ptr))
        }
    }
}

#[cfg(test)]
mod test;
<|endoftext|>


<commit_before>// Inspired by http://python-gitlab.readthedocs.io/en/stable/

extern crate hyper;
extern crate rustc_serialize;

pub mod gitlab;
pub mod projects;

pub use gitlab::Pagination;
pub use gitlab::GitLab;
pub use projects::{Project,Projects};

#[cfg(test)]
mod tests {
    use std::env;
    use gitlab::GitLab;
    use hyper;

    #[test]
    fn it_works() {

        let token = match env::var("GITLAB_TOKEN") {
            Ok(val) => val,
            Err(_)  => panic!("Please set environment variable 'GITLAB_TOKEN'"),
        };

        let gl = GitLab::new("http", "gitlab.com", 80, "XXXXXXXXXXXXX");
        println!("gl: {:?}", gl);
        assert_eq!(gl.attempt_connection().unwrap().status, hyper::status::StatusCode::Unauthorized);

        // let gl = GitLab::new("http", "gitlab.com", 80, &token);
        // println!("gl: {:?}", gl);
        // assert_eq!(gl.attempt_connection().unwrap().status, hyper::Ok);
        //
        // let gl = GitLab::new_http("gitlab.com", &token);
        // println!("gl: {:?}", gl);
        // assert_eq!(gl.attempt_connection().unwrap().status, hyper::Ok);

        let gl = GitLab::new_https("gitlab.com", &token);
        println!("gl: {:?}", gl);
        assert_eq!(gl.attempt_connection().unwrap().status, hyper::Ok);

        // Example from GitLab: https://docs.gitlab.com/ce/api/#basic-usage
        let expected_url = "https://gitlab.example.com:443/api/v3/projects?private_token=XXXXXXXXXXXXX";
        let gl = GitLab::new_https("gitlab.example.com", "XXXXXXXXXXXXX");
        assert_eq!(gl.build_url("projects"), expected_url);
    }
}
<commit_msg>Fix expected_url<commit_after>// Inspired by http://python-gitlab.readthedocs.io/en/stable/

extern crate hyper;
extern crate rustc_serialize;

pub mod gitlab;
pub mod projects;

pub use gitlab::Pagination;
pub use gitlab::GitLab;
pub use projects::{Project,Projects};

#[cfg(test)]
mod tests {
    use std::env;
    use gitlab::GitLab;
    use hyper;

    #[test]
    fn it_works() {

        let token = match env::var("GITLAB_TOKEN") {
            Ok(val) => val,
            Err(_)  => panic!("Please set environment variable 'GITLAB_TOKEN'"),
        };

        let gl = GitLab::new("http", "gitlab.com", 80, "XXXXXXXXXXXXX");
        println!("gl: {:?}", gl);
        assert_eq!(gl.attempt_connection().unwrap().status, hyper::status::StatusCode::Unauthorized);

        // let gl = GitLab::new("http", "gitlab.com", 80, &token);
        // println!("gl: {:?}", gl);
        // assert_eq!(gl.attempt_connection().unwrap().status, hyper::Ok);
        //
        // let gl = GitLab::new_http("gitlab.com", &token);
        // println!("gl: {:?}", gl);
        // assert_eq!(gl.attempt_connection().unwrap().status, hyper::Ok);

        let gl = GitLab::new_https("gitlab.com", &token);
        println!("gl: {:?}", gl);
        assert_eq!(gl.attempt_connection().unwrap().status, hyper::Ok);

        // Example from GitLab: https://docs.gitlab.com/ce/api/#basic-usage
        let expected_url = "https://gitlab.example.com:443/api/v3/projects?private_token=XXXXXXXXXXXXX&page=1&per_page=20";
        let gl = GitLab::new_https("gitlab.example.com", "XXXXXXXXXXXXX");
        assert_eq!(gl.build_url("projects"), expected_url);
    }
}
<|endoftext|>


<commit_before>use std::io::{Read,Write, Result};

/// Returns a Tee which can be used as Read whose
/// reads delegate ready bytes read to the provided reader and write to the provided
/// writer. This write must complete before the read completes.
///
/// Errors reported by the read will be interpreted as Errors for the read
pub fn tee<R: Read,W: Write>(reader: R, writer: W) -> Tee<R,W>  {
    Tee { reader: reader, writer: writer }
}

pub struct Tee<R,W> {
    reader: R,
    writer: W
}

impl<R: Read, W: Write> Read for Tee<R,W> {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        let n = try!(self.reader.read(buf));
        try!(self.writer.write_all(&buf[..n]));
        Ok(n)
    }
}

#[test]
fn it_works() {
}
<commit_msg>use new fn<commit_after>use std::io::{Read, Result, Write};

pub struct Tee<R,W> {
    reader: R,
    writer: W
}

impl<R: Read, W: Write> Tee<R,W> {
    /// Returns a Tee which can be used as Read whose
    /// reads delegate ready bytes read to the provided reader and write to the provided
    /// writer. This write must complete before the read completes.
    ///
    /// Errors reported by the read will be interpreted as Errors for the read
    pub fn new(reader: R, writer: W) -> Tee<R,W>  {
        Tee { reader: reader, writer: writer }
    }
}

impl<R: Read, W: Write> Read for Tee<R,W> {
    fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
        let n = try!(self.reader.read(buf));
        try!(self.writer.write_all(&buf[..n]));
        Ok(n)
    }
}

#[test]
fn it_works() {
}
<|endoftext|>


<commit_before>//! This crate only provides the `MaybeOwned` enum
//!
//! Take a look at it's documentation for more information.
//!
#![warn(missing_docs)]
use std::ops::Deref;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::fmt;
use std::borrow::Cow;

use self::MaybeOwned::*;

/// This type provides a way to store data to which you either have a
/// reference to or which you do own.
///
/// It provides `From<T>`, `From<&'a T>` implementations and, in difference
/// to `Cow` does _not_ require `ToOwned` to be implemented which makes it
/// compatible with non cloneable data, as a draw back of this it does not
/// know about `ToOwned`. As a consequence of it can't know that `&str` should
/// be the borrowed version of `String` and not `&String` this is especially
/// bad wrt. `Box` as the borrowed version of `Box<T>` would be `&Box<T>`.
///
/// While this crate has some drawbacks compared to `Cow` is has the benefit,
/// that it works with Types which neither implement `Clone` nor `ToOwned`.
/// Another benefit lies in the ability to write API functions which accept
/// a generic parameter `E: Into<MaybeOwned<'a, T>>` as the API consumer can
/// pass `T`, `&'a T` and `MaybeOwned<'a, T>` as argument, without requiring
/// a explicit `Cow::Onwed` or a split into two functions one accepting
/// owed and the other borrowed values.
///
/// # Alternatives
///
/// If you mainly have values implementing `ToOwned` like `&str`/`String`, `Path`/`PathBuf` or
/// `&[T]`/`Vec<T>` using `std::borrow::Cow` might be preferable.
///
/// If you want to be able to treat `&T`, `&mut T`, `Box<T>` and `Arc<T>` the same
/// consider using [`reffers::rbma::RBMA`](https://docs.rs/reffers)
/// (through not all types/platforms are supported because
/// as it relies on the fact that for many pointers the lowest two bits are 0, and stores
/// the discriminant in them, nevertheless this is can only be used with 32bit-aligned data,
/// e.g. using a &u8 _might_ fail). RBMA also allows you to recover a `&mut T` if it was created
/// from `Box<T>`, `&mut T` or a unique `Arc`.
///
///
/// # Examples
///
/// ```
/// # use maybe_owned::MaybeOwned;
/// struct PseudoBigData(u8);
/// fn pseudo_register_fn<'a, E>(_val: E) where E: Into<MaybeOwned<'a, PseudoBigData>> { }
///
/// let data = PseudoBigData(12);
/// let data2 = PseudoBigData(13);
///
/// pseudo_register_fn(&data);
/// pseudo_register_fn(&data);
/// pseudo_register_fn(data2);
/// pseudo_register_fn(MaybeOwned::Owned(PseudoBigData(111)));
/// ```
///
/// ```
/// # use maybe_owned::MaybeOwned;
/// #[repr(C)]
/// struct OpaqueFFI {
///     ref1:  * const u8
///     //we also might want to have PhantomData etc.
/// }
///
/// // does not work as it does not implement `ToOwned`
/// // let _ = Cow::Owned(OpaqueFFI { ref1: 0 as *const u8});
///
/// // ok, MaybeOwned can do this (but can't do &str<->String as tread of)
/// let _ = MaybeOwned::Owned(OpaqueFFI { ref1: 0 as *const u8 });
/// ```
#[derive(Debug)]
pub enum MaybeOwned<'a, T: 'a> {
    /// owns T
    Owned(T),
    /// has a reference to T
    Borrowed(&'a T)
}

impl<'a, T> MaybeOwned<'a, T> {

    /// returns true if the data is owned else false
    pub fn is_owned(&self) -> bool {
        match *self {
            Owned(_) => true,
            Borrowed(_) => false
        }
    }
}

impl<'a, T> Deref for MaybeOwned<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        match *self {
            Owned(ref v) => v,
            Borrowed(v) => v
        }
    }
}

impl<'a, T> AsRef<T> for MaybeOwned<'a, T> {
    fn as_ref(&self) -> &T {
        self
    }
}

impl<'a, T> From<&'a T> for MaybeOwned<'a, T> {
    fn from(v: &'a T) -> MaybeOwned<'a, T> {
        Borrowed(v)
    }
}

impl<'a, T> From<T> for MaybeOwned<'a, T> {
    fn from(v: T) -> MaybeOwned<'a, T> {
        Owned(v)
    }
}

impl<'a, T> From<Cow<'a, T>> for MaybeOwned<'a, T>
    where T: ToOwned<Owned=T>,
{
    fn from(cow: Cow<'a, T>) -> MaybeOwned<'a, T> {
        match cow {
            Cow::Owned(v) => MaybeOwned::Owned(v),
            Cow::Borrowed(v) => MaybeOwned::Borrowed(v),
        }
    }
}

impl<'a, T> Into<Cow<'a, T>> for MaybeOwned<'a, T>
    where T: ToOwned<Owned=T>,
{
    fn into(self) -> Cow<'a, T> {
        match self {
            MaybeOwned::Owned(v) => Cow::Owned(v),
            MaybeOwned::Borrowed(v) => Cow::Borrowed(v),
        }
    }
}

impl<'a, T> Default for MaybeOwned<'a, T> where T: Default {
    fn default() -> Self {
        Owned(T::default())
    }
}

impl<'a, T> Clone for MaybeOwned<'a, T> where T: Clone {
    fn clone(&self) -> MaybeOwned<'a, T> {
        match *self {
            Owned(ref v) => Owned(v.clone()),
            Borrowed(v) => Borrowed(v)
        }
    }
}

impl<'a, 'b, A, B> PartialEq<MaybeOwned<'b, B>> for MaybeOwned<'a, A>
    where A: PartialEq<B>
{
    #[inline]
    fn eq(&self, other: &MaybeOwned<'b, B>) -> bool {
        PartialEq::eq(self.deref(), other.deref())
    }
}

impl<'a, T> Eq for MaybeOwned<'a, T> where T: Eq {}

impl<'a, T> PartialOrd for MaybeOwned<'a, T>
    where T: PartialOrd
{
    #[inline]
    fn partial_cmp(&self, other: &MaybeOwned<'a, T>) -> Option<Ordering> {
        PartialOrd::partial_cmp(self.deref(), other.deref())
    }
}

impl<'a, T> Ord for MaybeOwned<'a, T>
    where T: Ord
{
    #[inline]
    fn cmp(&self, other: &MaybeOwned<'a, T>) -> Ordering {
        Ord::cmp(self.deref(), other.deref())
    }
}

impl<'a, T> Hash for MaybeOwned<'a, T>
    where T: Hash
{
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(self.deref(), state)
    }
}

impl<'a, T> fmt::Display for MaybeOwned<'a, T>
    where T: fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Owned(ref o) => fmt::Display::fmt(o, f),
            Borrowed(b) => fmt::Display::fmt(b, f),
        }
    }
}

impl<'a, T> MaybeOwned<'a, T> where T: Clone {

    /// Aquires a mutable reference to owned data.
    ///
    /// Clones data if it is not already owned.
    ///
    /// ## Example
    ///
    /// ```
    /// use maybe_owned::MaybeOwned;
    ///
    /// #[derive(Clone, Debug, PartialEq, Eq)]
    /// struct PseudoBigData(u8);
    ///
    /// let data = PseudoBigData(12);
    ///
    /// let mut maybe: MaybeOwned<PseudoBigData> = (&data).into();
    /// assert_eq!(false, maybe.is_owned());
    ///
    /// {
    ///     let reference = maybe.to_mut();
    ///     assert_eq!(&mut PseudoBigData(12), reference);
    /// }
    /// assert!(maybe.is_owned());
    /// ```
    ///
    pub fn to_mut(&mut self) -> &mut T {
        match *self {
            Owned(ref mut v) => v,
            Borrowed(v) => {
                *self = Owned(v.clone());
                match *self {
                    Owned(ref mut v) => v,
                    Borrowed(..) => unreachable!()
                }
            }

        }
    }

    /// Extracts the owned data.
    ///
    /// If the data is borrowed it is cloned before being extracted.
    pub fn into_owned(self) -> T {
        match self {
            Owned(v) => v,
            Borrowed(v) => v.clone()
        }
    }
}

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

    type TestType = Vec<()>;

    fn with_into<'a, I: Into<MaybeOwned<'a, TestType>>>(v: I) -> MaybeOwned<'a, TestType> {
        v.into()
    }

    #[test]
    fn is_owned() {
        let data = TestType::default();
        assert!(MaybeOwned::Owned(data).is_owned());
    }

    #[test]
    fn into_with_owned() {
        //ty check if it accepts references
        let data = TestType::default();
        assert!(with_into(data).is_owned())

    }
    #[test]
    fn into_with_borrow() {
        //ty check if it accepts references
        let data = TestType::default();
        assert!(!with_into(&data).is_owned());
    }

    #[test]
    fn clone_owned() {
        let maybe = MaybeOwned::<TestType>::default();
        assert!(maybe.clone().is_owned());
    }

    #[test]
    fn clone_borrow() {
        let data = TestType::default();
        let maybe: MaybeOwned<TestType> = (&data).into();
        assert!(!maybe.clone().is_owned());
    }

    #[test]
    fn to_mut() {
        let data = TestType::default();
        let mut maybe: MaybeOwned<TestType> = (&data).into();
        assert!(!maybe.is_owned());
        {
            let _mut_ref = maybe.to_mut();
        }
        assert!(maybe.is_owned());
    }

    #[test]
    fn into_inner() {
        let data = vec![1u32,2];
        let maybe: MaybeOwned<Vec<u32>> = (&data).into();
        assert_eq!(data, maybe.into_owned());
    }

    #[test]
    fn has_default() {
        #[derive(Default)]
        struct TestType(u8);
        let _x: MaybeOwned<TestType> = Default::default();
    }

    #[test]
    fn has_clone() {
        #[derive(Clone)]
        struct TestType(u8);
        let _x  = TestType(12).clone();
    }

    #[test]
    fn has_partial_eq() {
        #[derive(PartialEq)]
        struct TestType(f32);

        let n = TestType(33.0);
        let a = MaybeOwned::Owned(TestType(42.0));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33.0));

        assert_eq!(a == b, false);
        assert_eq!(b == c, true);
        assert_eq!(c == a, false);
    }

    #[test]
    fn has_eq() {
        #[derive(PartialEq, Eq)]
        struct TestType(i32);

        let n = TestType(33);
        let a = MaybeOwned::Owned(TestType(42));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33));

        assert_eq!(a == b, false);
        assert_eq!(b == c, true);
        assert_eq!(c == a, false);
    }

    #[test]
    fn has_partial_ord() {
        #[derive(PartialEq, PartialOrd)]
        struct TestType(f32);

        let n = TestType(33.0);
        let a = MaybeOwned::Owned(TestType(42.0));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33.0));

        assert_eq!(a > b, true);
        assert_eq!(b > c, false);
        assert_eq!(a < c, false);
    }

    #[test]
    fn has_ord() {
        #[derive(PartialEq, Eq, PartialOrd, Ord)]
        struct TestType(i32);

        let n = TestType(33);
        let a = MaybeOwned::Owned(TestType(42));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33));

        assert_eq!(a > b, true);
        assert_eq!(b > c, false);
        assert_eq!(a < c, false);
    }

    #[test]
    fn has_hash() {
        use std::collections::HashMap;

        let mut map = HashMap::new();
        map.insert(MaybeOwned::Owned(42), 33);

        assert_eq!(map.get(&MaybeOwned::Borrowed(&42)), Some(&33));
    }

    #[test]
    fn has_display() {
        let n = 33;
        let a = MaybeOwned::Owned(42);
        let b = MaybeOwned::Borrowed(&n);

        let s = format!("{} {}", a, b);

        assert_eq!(s, "42 33");
    }

    #[test]
    fn from_cow() {
        use std::borrow::Cow;

        fn test<'a, V: Into<MaybeOwned<'a, i32>>>(v: V, n: i32) { assert_eq!(*v.into(), n) }

        let n = 33;
        test(Cow::Owned(42), 42);
        test(Cow::Borrowed(&n), n);
    }

    #[test]
    fn into_cow() {
        use std::borrow::Cow;

        fn test<'a, V: Into<Cow<'a, i32>>>(v: V, n: i32) { assert_eq!(*v.into(), n) }

        let n = 33;
        test(MaybeOwned::Owned(42), 42);
        test(MaybeOwned::Borrowed(&n), n);
    }

    #[test]
    fn as_ref() {
        let data  = TestType::default();
        let maybe_owned = MaybeOwned::Borrowed(&data);
        let _ref: &TestType = maybe_owned.as_ref();
        assert_eq!(
            &data as *const _ as usize,
            _ref as *const _ as usize
        );
    }
}
<commit_msg>chore(Borrow): impl (std) Borrow for MaybeOwned<commit_after>//! This crate only provides the `MaybeOwned` enum
//!
//! Take a look at it's documentation for more information.
//!
#![warn(missing_docs)]
use std::ops::Deref;
use std::cmp::Ordering;
use std::hash::{Hash, Hasher};
use std::fmt;
use std::borrow::{Cow, Borrow};

use self::MaybeOwned::*;

/// This type provides a way to store data to which you either have a
/// reference to or which you do own.
///
/// It provides `From<T>`, `From<&'a T>` implementations and, in difference
/// to `Cow` does _not_ require `ToOwned` to be implemented which makes it
/// compatible with non cloneable data, as a draw back of this it does not
/// know about `ToOwned`. As a consequence of it can't know that `&str` should
/// be the borrowed version of `String` and not `&String` this is especially
/// bad wrt. `Box` as the borrowed version of `Box<T>` would be `&Box<T>`.
///
/// While this crate has some drawbacks compared to `Cow` is has the benefit,
/// that it works with Types which neither implement `Clone` nor `ToOwned`.
/// Another benefit lies in the ability to write API functions which accept
/// a generic parameter `E: Into<MaybeOwned<'a, T>>` as the API consumer can
/// pass `T`, `&'a T` and `MaybeOwned<'a, T>` as argument, without requiring
/// a explicit `Cow::Onwed` or a split into two functions one accepting
/// owed and the other borrowed values.
///
/// # Alternatives
///
/// If you mainly have values implementing `ToOwned` like `&str`/`String`, `Path`/`PathBuf` or
/// `&[T]`/`Vec<T>` using `std::borrow::Cow` might be preferable.
///
/// If you want to be able to treat `&T`, `&mut T`, `Box<T>` and `Arc<T>` the same
/// consider using [`reffers::rbma::RBMA`](https://docs.rs/reffers)
/// (through not all types/platforms are supported because
/// as it relies on the fact that for many pointers the lowest two bits are 0, and stores
/// the discriminant in them, nevertheless this is can only be used with 32bit-aligned data,
/// e.g. using a &u8 _might_ fail). RBMA also allows you to recover a `&mut T` if it was created
/// from `Box<T>`, `&mut T` or a unique `Arc`.
///
///
/// # Examples
///
/// ```
/// # use maybe_owned::MaybeOwned;
/// struct PseudoBigData(u8);
/// fn pseudo_register_fn<'a, E>(_val: E) where E: Into<MaybeOwned<'a, PseudoBigData>> { }
///
/// let data = PseudoBigData(12);
/// let data2 = PseudoBigData(13);
///
/// pseudo_register_fn(&data);
/// pseudo_register_fn(&data);
/// pseudo_register_fn(data2);
/// pseudo_register_fn(MaybeOwned::Owned(PseudoBigData(111)));
/// ```
///
/// ```
/// # use maybe_owned::MaybeOwned;
/// #[repr(C)]
/// struct OpaqueFFI {
///     ref1:  * const u8
///     //we also might want to have PhantomData etc.
/// }
///
/// // does not work as it does not implement `ToOwned`
/// // let _ = Cow::Owned(OpaqueFFI { ref1: 0 as *const u8});
///
/// // ok, MaybeOwned can do this (but can't do &str<->String as tread of)
/// let _ = MaybeOwned::Owned(OpaqueFFI { ref1: 0 as *const u8 });
/// ```
#[derive(Debug)]
pub enum MaybeOwned<'a, T: 'a> {
    /// owns T
    Owned(T),
    /// has a reference to T
    Borrowed(&'a T)
}

impl<'a, T> MaybeOwned<'a, T> {

    /// returns true if the data is owned else false
    pub fn is_owned(&self) -> bool {
        match *self {
            Owned(_) => true,
            Borrowed(_) => false
        }
    }
}

impl<'a, T> Deref for MaybeOwned<'a, T> {
    type Target = T;

    fn deref(&self) -> &T {
        match *self {
            Owned(ref v) => v,
            Borrowed(v) => v
        }
    }
}

impl<'a, T> AsRef<T> for MaybeOwned<'a, T> {
    fn as_ref(&self) -> &T {
        self
    }
}

impl<'a, T> Borrow<T> for MaybeOwned<'a, T> {
    fn borrow(&self) -> &T {
        self
    }
}

impl<'a, T> From<&'a T> for MaybeOwned<'a, T> {
    fn from(v: &'a T) -> MaybeOwned<'a, T> {
        Borrowed(v)
    }
}

impl<'a, T> From<T> for MaybeOwned<'a, T> {
    fn from(v: T) -> MaybeOwned<'a, T> {
        Owned(v)
    }
}

impl<'a, T> From<Cow<'a, T>> for MaybeOwned<'a, T>
    where T: ToOwned<Owned=T>,
{
    fn from(cow: Cow<'a, T>) -> MaybeOwned<'a, T> {
        match cow {
            Cow::Owned(v) => MaybeOwned::Owned(v),
            Cow::Borrowed(v) => MaybeOwned::Borrowed(v),
        }
    }
}

impl<'a, T> Into<Cow<'a, T>> for MaybeOwned<'a, T>
    where T: ToOwned<Owned=T>,
{
    fn into(self) -> Cow<'a, T> {
        match self {
            MaybeOwned::Owned(v) => Cow::Owned(v),
            MaybeOwned::Borrowed(v) => Cow::Borrowed(v),
        }
    }
}

impl<'a, T> Default for MaybeOwned<'a, T> where T: Default {
    fn default() -> Self {
        Owned(T::default())
    }
}

impl<'a, T> Clone for MaybeOwned<'a, T> where T: Clone {
    fn clone(&self) -> MaybeOwned<'a, T> {
        match *self {
            Owned(ref v) => Owned(v.clone()),
            Borrowed(v) => Borrowed(v)
        }
    }
}

impl<'a, 'b, A, B> PartialEq<MaybeOwned<'b, B>> for MaybeOwned<'a, A>
    where A: PartialEq<B>
{
    #[inline]
    fn eq(&self, other: &MaybeOwned<'b, B>) -> bool {
        PartialEq::eq(self.deref(), other.deref())
    }
}

impl<'a, T> Eq for MaybeOwned<'a, T> where T: Eq {}

impl<'a, T> PartialOrd for MaybeOwned<'a, T>
    where T: PartialOrd
{
    #[inline]
    fn partial_cmp(&self, other: &MaybeOwned<'a, T>) -> Option<Ordering> {
        PartialOrd::partial_cmp(self.deref(), other.deref())
    }
}

impl<'a, T> Ord for MaybeOwned<'a, T>
    where T: Ord
{
    #[inline]
    fn cmp(&self, other: &MaybeOwned<'a, T>) -> Ordering {
        Ord::cmp(self.deref(), other.deref())
    }
}

impl<'a, T> Hash for MaybeOwned<'a, T>
    where T: Hash
{
    #[inline]
    fn hash<H: Hasher>(&self, state: &mut H) {
        Hash::hash(self.deref(), state)
    }
}

impl<'a, T> fmt::Display for MaybeOwned<'a, T>
    where T: fmt::Display
{
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Owned(ref o) => fmt::Display::fmt(o, f),
            Borrowed(b) => fmt::Display::fmt(b, f),
        }
    }
}

impl<'a, T> MaybeOwned<'a, T> where T: Clone {

    /// Aquires a mutable reference to owned data.
    ///
    /// Clones data if it is not already owned.
    ///
    /// ## Example
    ///
    /// ```
    /// use maybe_owned::MaybeOwned;
    ///
    /// #[derive(Clone, Debug, PartialEq, Eq)]
    /// struct PseudoBigData(u8);
    ///
    /// let data = PseudoBigData(12);
    ///
    /// let mut maybe: MaybeOwned<PseudoBigData> = (&data).into();
    /// assert_eq!(false, maybe.is_owned());
    ///
    /// {
    ///     let reference = maybe.to_mut();
    ///     assert_eq!(&mut PseudoBigData(12), reference);
    /// }
    /// assert!(maybe.is_owned());
    /// ```
    ///
    pub fn to_mut(&mut self) -> &mut T {
        match *self {
            Owned(ref mut v) => v,
            Borrowed(v) => {
                *self = Owned(v.clone());
                match *self {
                    Owned(ref mut v) => v,
                    Borrowed(..) => unreachable!()
                }
            }

        }
    }

    /// Extracts the owned data.
    ///
    /// If the data is borrowed it is cloned before being extracted.
    pub fn into_owned(self) -> T {
        match self {
            Owned(v) => v,
            Borrowed(v) => v.clone()
        }
    }
}

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

    type TestType = Vec<()>;

    fn with_into<'a, I: Into<MaybeOwned<'a, TestType>>>(v: I) -> MaybeOwned<'a, TestType> {
        v.into()
    }

    #[test]
    fn is_owned() {
        let data = TestType::default();
        assert!(MaybeOwned::Owned(data).is_owned());
    }

    #[test]
    fn into_with_owned() {
        //ty check if it accepts references
        let data = TestType::default();
        assert!(with_into(data).is_owned())

    }
    #[test]
    fn into_with_borrow() {
        //ty check if it accepts references
        let data = TestType::default();
        assert!(!with_into(&data).is_owned());
    }

    #[test]
    fn clone_owned() {
        let maybe = MaybeOwned::<TestType>::default();
        assert!(maybe.clone().is_owned());
    }

    #[test]
    fn clone_borrow() {
        let data = TestType::default();
        let maybe: MaybeOwned<TestType> = (&data).into();
        assert!(!maybe.clone().is_owned());
    }

    #[test]
    fn to_mut() {
        let data = TestType::default();
        let mut maybe: MaybeOwned<TestType> = (&data).into();
        assert!(!maybe.is_owned());
        {
            let _mut_ref = maybe.to_mut();
        }
        assert!(maybe.is_owned());
    }

    #[test]
    fn into_inner() {
        let data = vec![1u32,2];
        let maybe: MaybeOwned<Vec<u32>> = (&data).into();
        assert_eq!(data, maybe.into_owned());
    }

    #[test]
    fn has_default() {
        #[derive(Default)]
        struct TestType(u8);
        let _x: MaybeOwned<TestType> = Default::default();
    }

    #[test]
    fn has_clone() {
        #[derive(Clone)]
        struct TestType(u8);
        let _x  = TestType(12).clone();
    }

    #[test]
    fn has_partial_eq() {
        #[derive(PartialEq)]
        struct TestType(f32);

        let n = TestType(33.0);
        let a = MaybeOwned::Owned(TestType(42.0));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33.0));

        assert_eq!(a == b, false);
        assert_eq!(b == c, true);
        assert_eq!(c == a, false);
    }

    #[test]
    fn has_eq() {
        #[derive(PartialEq, Eq)]
        struct TestType(i32);

        let n = TestType(33);
        let a = MaybeOwned::Owned(TestType(42));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33));

        assert_eq!(a == b, false);
        assert_eq!(b == c, true);
        assert_eq!(c == a, false);
    }

    #[test]
    fn has_partial_ord() {
        #[derive(PartialEq, PartialOrd)]
        struct TestType(f32);

        let n = TestType(33.0);
        let a = MaybeOwned::Owned(TestType(42.0));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33.0));

        assert_eq!(a > b, true);
        assert_eq!(b > c, false);
        assert_eq!(a < c, false);
    }

    #[test]
    fn has_ord() {
        #[derive(PartialEq, Eq, PartialOrd, Ord)]
        struct TestType(i32);

        let n = TestType(33);
        let a = MaybeOwned::Owned(TestType(42));
        let b = MaybeOwned::Borrowed(&n);
        let c = MaybeOwned::Owned(TestType(33));

        assert_eq!(a > b, true);
        assert_eq!(b > c, false);
        assert_eq!(a < c, false);
    }

    #[test]
    fn has_hash() {
        use std::collections::HashMap;

        let mut map = HashMap::new();
        map.insert(MaybeOwned::Owned(42), 33);

        assert_eq!(map.get(&MaybeOwned::Borrowed(&42)), Some(&33));
    }

    #[test]
    fn has_display() {
        let n = 33;
        let a = MaybeOwned::Owned(42);
        let b = MaybeOwned::Borrowed(&n);

        let s = format!("{} {}", a, b);

        assert_eq!(s, "42 33");
    }

    #[test]
    fn from_cow() {
        use std::borrow::Cow;

        fn test<'a, V: Into<MaybeOwned<'a, i32>>>(v: V, n: i32) { assert_eq!(*v.into(), n) }

        let n = 33;
        test(Cow::Owned(42), 42);
        test(Cow::Borrowed(&n), n);
    }

    #[test]
    fn into_cow() {
        use std::borrow::Cow;

        fn test<'a, V: Into<Cow<'a, i32>>>(v: V, n: i32) { assert_eq!(*v.into(), n) }

        let n = 33;
        test(MaybeOwned::Owned(42), 42);
        test(MaybeOwned::Borrowed(&n), n);
    }

    #[test]
    fn as_ref() {
        let data  = TestType::default();
        let maybe_owned = MaybeOwned::Borrowed(&data);
        let _ref: &TestType = maybe_owned.as_ref();
        assert_eq!(
            &data as *const _ as usize,
            _ref as *const _ as usize
        );
    }

    #[test]
    fn borrow() {
        use std::borrow::Borrow;

        let data = TestType::default();
        let maybe_owned = MaybeOwned::Borrowed(&data);
        let _ref: &TestType = maybe_owned.borrow();
        assert_eq!(
            &data as *const _ as usize,
            _ref as *const _ as usize
        );
    }
}
<|endoftext|>


<commit_before>#![warn(missing_docs)]

//! A stream based HTML5 templating system with code side logic.
//!
//! Everything about this crate is **experimental**.
//!
//! This library allows transforming a HTML5 stream with an iterator-like interface. It was
//! inspired by [`HTML::Zoom`](https://metacpan.org/release/HTML-Zoom).
//!
//! Since this library is intended for templating, the HTML5 parser is rather simple and
//! certainly lacking in some areas. Verification of input and output markup structure only
//! happens when necessary for transformations.
//!
//! # Templates
//!
//! Templates are sequences of events stored in a vector. The `transform` method of a template
//! can be used to generate a newly transformed template. See the `Api` type below for
//! information on available transform mechanisms.
//!
//! # Example
//!
//! ```
//! # use std::error;
//! # fn example() -> Result<(), Box<error::Error>> {
//! use html5_fuser::{ Template, ParseOptions };
//!
//! let template = Template::from_str(r#"
//!     <html>
//!         <head><title>Template Title</title></head>
//!         <body>
//!             <ul id="items">
//!                 <li class="item"/>
//!             </ul>
//!         </body>
//!     </html>
//! "#, ParseOptions::default())?;
//!
//! let transformed = template.transform(|html| html
//!     .select("title", |html| html.replace_contents("New Title"))
//!     .select("#items", |html| html
//!         .repeat(2..5, |html, value| html
//!             .replace_contents(format!("Item {}", value))
//!         )
//!     )
//! )?;
//!
//! println!("{}", transformed);
//! # Ok(())
//! # }
//! # fn main() { example().unwrap() }
//! ```
//!
extern crate tendril;

#[cfg(test)]
macro_rules! test_group {
    ($name:ident: $( $title:expr => $test:expr ),* $(,)*) => {
        #[test]
        fn $name() {
            use std::panic;
            $(
                panic::catch_unwind(|| $test)
                .expect(&format!("Failed test case: {}", $title));
            )*
        }
    }
}

#[cfg(test)]
macro_rules! transform_test {
    ($input:expr, $expected:expr, $transform:expr $(,)*) => {
        {
            let template = ::Template::from_str($input, Default::default()).unwrap();
            let modified = template.transform($transform).unwrap();
            let rendered = format!("{}", &modified);
            assert_eq!(rendered, $expected);
        }
    }
}

#[cfg(test)]
macro_rules! transform_error_test {
    ($input:expr, $expected:pat, $transform:expr $(,)*) => {
        {
            let template = ::Template::from_str($input, Default::default()).unwrap();
            let result = template.transform($transform);
            if let Err($expected) = result {
                ()
            } else {
                panic!("invalid result: {:?}", result);
            }
        }
    }
}

#[cfg(test)]
macro_rules! test_transform {
    ($options:expr, $input:expr, $expected:expr, $transform:expr $(,)*) => {{
        let template = ::Template::from_str($input, $options).unwrap();
        let modified = template.transform($transform).unwrap();
        let rendered = format!("{}", &modified);
        assert_eq!(rendered, $expected);
        modified
    }}
}

#[cfg(test)]
macro_rules! test_stream_error {
    ($options:expr, $input:expr, $expected:pat, $transform:expr $(,)*) => {{
        let template = ::Template::from_str($input, $options).unwrap();
        let result = template.transform($transform);
        if let Err($expected) = result {
        } else {
            panic!("invalid result: {:?}", result);
        }
    }}
}

mod input;
pub mod content;
pub mod builder;
pub mod location;
pub mod template;
pub mod event;
pub mod text;
pub mod select;
pub mod transform;
pub mod modifier;
pub mod parse;

pub use event::{
    Stream,
    StreamError,
    ElementStream,
};

pub use template::{
    Template,
};

pub use parse::{
    Options as ParseOptions,
};

pub use transform::{
    Api,
    BoxedApi,
    BoxedElementApi,
};
<commit_msg>removed old test structure<commit_after>#![warn(missing_docs)]

//! A stream based HTML5 templating system with code side logic.
//!
//! Everything about this crate is **experimental**.
//!
//! This library allows transforming a HTML5 stream with an iterator-like interface. It was
//! inspired by [`HTML::Zoom`](https://metacpan.org/release/HTML-Zoom).
//!
//! Since this library is intended for templating, the HTML5 parser is rather simple and
//! certainly lacking in some areas. Verification of input and output markup structure only
//! happens when necessary for transformations.
//!
//! # Templates
//!
//! Templates are sequences of events stored in a vector. The `transform` method of a template
//! can be used to generate a newly transformed template. See the `Api` type below for
//! information on available transform mechanisms.
//!
//! # Example
//!
//! ```
//! # use std::error;
//! # fn example() -> Result<(), Box<error::Error>> {
//! use html5_fuser::{ Template, ParseOptions };
//!
//! let template = Template::from_str(r#"
//!     <html>
//!         <head><title>Template Title</title></head>
//!         <body>
//!             <ul id="items">
//!                 <li class="item"/>
//!             </ul>
//!         </body>
//!     </html>
//! "#, ParseOptions::default())?;
//!
//! let transformed = template.transform(|html| html
//!     .select("title", |html| html.replace_contents("New Title"))
//!     .select("#items", |html| html
//!         .repeat(2..5, |html, value| html
//!             .replace_contents(format!("Item {}", value))
//!         )
//!     )
//! )?;
//!
//! println!("{}", transformed);
//! # Ok(())
//! # }
//! # fn main() { example().unwrap() }
//! ```
//!
extern crate tendril;

#[cfg(test)]
macro_rules! test_group {
    ($name:ident: $( $title:expr => $test:expr ),* $(,)*) => {
        #[test]
        fn $name() {
            use std::panic;
            $(
                panic::catch_unwind(|| $test)
                .expect(&format!("Failed test case: {}", $title));
            )*
        }
    }
}

#[cfg(test)]
macro_rules! transform_test {
    ($input:expr, $expected:expr, $transform:expr $(,)*) => {
        {
            let template = ::Template::from_str($input, Default::default()).unwrap();
            let modified = template.transform($transform).unwrap();
            let rendered = format!("{}", &modified);
            assert_eq!(rendered, $expected);
        }
    }
}

#[cfg(test)]
macro_rules! transform_error_test {
    ($input:expr, $expected:pat, $transform:expr $(,)*) => {
        {
            let template = ::Template::from_str($input, Default::default()).unwrap();
            let result = template.transform($transform);
            if let Err($expected) = result {
                ()
            } else {
                panic!("invalid result: {:?}", result);
            }
        }
    }
}

mod input;
pub mod content;
pub mod builder;
pub mod location;
pub mod template;
pub mod event;
pub mod text;
pub mod select;
pub mod transform;
pub mod modifier;
pub mod parse;

pub use event::{
    Stream,
    StreamError,
    ElementStream,
};

pub use template::{
    Template,
};

pub use parse::{
    Options as ParseOptions,
};

pub use transform::{
    Api,
    BoxedApi,
    BoxedElementApi,
};
<|endoftext|>


<commit_before>#![feature(collections)]
#![feature(asm)]
#![feature(const_fn)]
#![feature(lang_items)]
#![no_std]

#![allow(unknown_lints)]

extern crate allocator;
extern crate collections;

pub mod dispatch_table;
pub mod runtime;

pub mod vmx;

pub type CChar = u8;

macro_rules! cstring {
    ($e:expr) => (concat!($e, "\0").as_ptr() as *const CChar)
}

extern "C" {
    fn printk(format: *const CChar, ...);
}

#[no_mangle]
pub extern "C" fn entry(heap: *mut CChar, heap_size: u64, _: *mut CChar, _: u64) -> u32 {
    unsafe {
        printk(cstring!("Hello Linux!\n"));
    }
    allocator::init_global_allocator(heap_size, heap);
    0
}
<commit_msg>Use allocator<commit_after>#![feature(collections)]
#![feature(asm)]
#![feature(const_fn)]
#![feature(lang_items)]

#![feature(alloc, collections)]
#![allow(unknown_lints)]
#![no_std]

extern crate alloc;
#[cfg(not(test))]
extern crate allocator;
extern crate spin;
#[macro_use]
extern crate collections;

pub mod dispatch_table;
pub mod runtime;

pub mod vmx;

pub type CChar = u8;

macro_rules! cstring {
    ($e:expr) => (concat!($e, "\0").as_ptr() as *const CChar)
}

extern "C" {
    fn printk(format: *const CChar, ...);
}

#[no_mangle]
pub extern "C" fn entry(_heap: *mut CChar, _heap_size: u64, _: *mut CChar, _: u64) -> u32 {
    unsafe {
        printk(cstring!("Hello Linux!\n"));
    }

    #[cfg(not(test))]
    allocator::init_global_allocator(_heap_size, _heap);
    0
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod test;

use std::fmt::{self, Debug, Formatter};

/// A data-structure for storing a sequence of 4-bit values.
///
/// Values are stored in a `Vec<u8>`, with two values per byte.
///
/// Values at even indices are stored in the most-significant half of their byte,
/// while values at odd indices are stored in the least-significant half.
///
/// Imagine a vector of [MSB][msb-wiki] first bytes, and you'll be right.
///
/// n = [_ _ | _ _ | _ _]
///
/// [msb-wiki]: http://en.wikipedia.org/wiki/Most_significant_bit
#[derive(Clone)]
pub struct NibbleVec {
    length: usize,
    data: Vec<u8>
}

impl NibbleVec {
    /// Create an empty nibble vector.
    pub fn new() -> NibbleVec {
        NibbleVec {
            length: 0,
            data: Vec::new()
        }
    }

    /// Create a nibble vector from a vector of bytes.
    ///
    /// Each byte is split into two 4-bit entries (MSB, LSB).
    pub fn from_byte_vec(vec: Vec<u8>) -> NibbleVec {
        let length = 2 * vec.len();
        NibbleVec {
            length: length,
            data: vec
        }
    }

    /// Get the number of elements stored in the vector.
    pub fn len(&self) -> usize {
        self.length
    }

    /// Fetch a single entry from the vector.
    ///
    /// Guaranteed to be a value in the interval [0, 15].
    ///
    /// **Panics** if `idx >= self.len()`.
    pub fn get(&self, idx: usize) -> u8 {
        if idx >= self.length {
            panic!("attempted access beyond vector end. len is {}, index is {}", self.length, idx);
        }
        let vec_idx = idx / 2;
        match idx % 2 {
            // If the index is even, take the first (most significant) half of the stored byte.
            0 => self.data[vec_idx] >> 4,
            // If the index is odd, take the second (least significant) half.
            _ => self.data[vec_idx] & 0x0F
        }
    }

    /// Add a single nibble to the vector.
    ///
    /// Only the 4 least-significant bits of the value are used.
    pub fn push(&mut self, val: u8) {
        if self.length % 2 == 0 {
            self.data.push(val << 4);
        } else {
            let vec_len = self.data.len();

            // Zero the second half of the last byte just to be safe.
            self.data[vec_len - 1] &= 0xF0;

            // Write the new value.
            self.data[vec_len - 1] |= val & 0x0F;
        }
        self.length += 1;
    }

    /// Split the vector into two parts.
    ///
    /// All elements at or following the given index are returned in a new `NibbleVec`,
    /// with exactly `idx` elements remaining in this vector.
    ///
    /// **Panics** if `idx > self.len()`.
    pub fn split(&mut self, idx: usize) -> NibbleVec {
        if idx > self.length {
            panic!("attempted to split past vector end. len is {}, index is {}", self.length, idx);
        } else if idx == self.length {
            NibbleVec::new()
        } else if idx % 2 == 0 {
            self.split_even(idx)
        } else {
            self.split_odd(idx)
        }
    }

    /// Split function for odd *indices*.
    #[inline(always)]
    fn split_odd(&mut self, idx: usize) -> NibbleVec {
        let tail_vec_size = (self.length - idx) / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Perform an overlap copy, copying the last nibble of the original vector only if
        // the length of the new tail is *odd*.
        let tail_length = self.length - idx;
        let take_last = tail_length % 2 == 1;
        self.overlap_copy(idx / 2, self.data.len(), &mut tail.data, &mut tail.length, take_last);

        // Remove the copied bytes, being careful to skip the idx byte.
        for _ in (idx / 2 + 1) .. self.data.len() {
            self.data.pop();
        }

        // Zero the second half of the index byte so as to maintain the last-nibble invariant.
        self.data[idx / 2] &= 0xF0;

        // Update the length of the first NibbleVec.
        self.length = idx;

        tail
    }

    /// Split function for even *indices*.
    #[inline(always)]
    fn split_even(&mut self, idx: usize) -> NibbleVec {
        // Avoid allocating a temporary vector by copying all the bytes in order, then popping them.

        // Possible to prove: l_d - ⌊i / 2⌋ = ⌊(l_v - i + 1) / 2⌋
        //  where l_d = self.data.len()
        //        l_v = self.length
        let tail_vec_size = (self.length - idx + 1) / 2;
        let half_idx = idx / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Copy the bytes.
        for i in half_idx .. self.data.len() {
            tail.data.push(self.data[i]);
        }

        // Pop the same bytes.
        for _ in half_idx .. self.data.len() {
            self.data.pop();
        }

        // Update lengths.
        tail.length = self.length - idx;
        self.length = idx;

        tail
    }

    /// Copy data between the second half of self.data[start] and
    /// self.data[end - 1]. The second half of the last entry is included
    /// if include_last is true.
    #[inline(always)]
    fn overlap_copy(&self, start: usize, end: usize, vec: &mut Vec<u8>, length: &mut usize, include_last: bool) {
        // Copy up to the first half of the last byte.
        for i in start .. (end - 1) {
            // The first half is the second half of the old entry.
            let first_half = self.data[i] & 0x0f;

            // The second half is the first half of the next entry.
            let second_half = self.data[i + 1] >> 4;

            vec.push((first_half << 4) | second_half);
            *length += 2;
        }

        if include_last {
            let last = self.data[end - 1] & 0x0f;
            vec.push(last << 4);
            *length += 1;
        }
    }

    /// Append another nibble vector whilst consuming this vector.
    pub fn join(mut self, other: &NibbleVec) -> NibbleVec {
        // If the length is even, we can append directly.
        if self.length % 2 == 0 {
            self.length += other.length;
            self.data.extend(other.data.clone());
            return self;
        }

        // If the other vector is empty, bail out.
        if other.len() == 0 {
            return self;
        }

        // If the length is odd, we have to perform an overlap copy.
        // Copy the first half of the first element, to make the vector an even length.
        self.push(other.get(0));

        // Copy the rest of the vector using an overlap copy.
        let take_last = other.len() % 2 == 0;
        other.overlap_copy(0, other.data.len(), &mut self.data, &mut self.length, take_last);

        self
    }
}

impl PartialEq<NibbleVec> for NibbleVec {
    fn eq(&self, other: &NibbleVec) -> bool {
        self.length == other.length &&
        self.data == other.data
    }
}

impl Eq for NibbleVec {}

/// Compare a NibbleVec and a slice of bytes *element-by-element*.
/// Bytes are **not** interpreted as two NibbleVec entries.
impl PartialEq<[u8]> for NibbleVec {
    fn eq(&self, other: &[u8]) -> bool {
        if other.len() != self.len() {
            return false;
        }

        for (i, x) in other.iter().enumerate() {
            if self.get(i) != *x {
                return false;
            }
        }
        true
    }
}

impl Debug for NibbleVec {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "NibbleVec ["));

        if self.len() > 0 {
            try!(write!(fmt, "{}", self.get(0)));
        }

        for i in 1 .. self.len() {
            try!(write!(fmt, ", {}", self.get(i)));
        }
        write!(fmt, "]")
    }
}
<commit_msg>Fix clippy warnings<commit_after>#[cfg(test)]
mod test;

use std::fmt::{self, Debug, Formatter};

/// A data-structure for storing a sequence of 4-bit values.
///
/// Values are stored in a `Vec<u8>`, with two values per byte.
///
/// Values at even indices are stored in the most-significant half of their byte,
/// while values at odd indices are stored in the least-significant half.
///
/// Imagine a vector of [MSB][msb-wiki] first bytes, and you'll be right.
///
/// n = [_ _ | _ _ | _ _]
///
/// [msb-wiki]: http://en.wikipedia.org/wiki/Most_significant_bit
#[derive(Clone, Default)]
pub struct NibbleVec {
    length: usize,
    data: Vec<u8>
}

impl NibbleVec {
    /// Create an empty nibble vector.
    pub fn new() -> NibbleVec {
        NibbleVec {
            length: 0,
            data: Vec::new()
        }
    }

    /// Create a nibble vector from a vector of bytes.
    ///
    /// Each byte is split into two 4-bit entries (MSB, LSB).
    pub fn from_byte_vec(vec: Vec<u8>) -> NibbleVec {
        let length = 2 * vec.len();
        NibbleVec {
            length: length,
            data: vec
        }
    }

    /// Get the number of elements stored in the vector.
    pub fn len(&self) -> usize {
        self.length
    }

    /// Returns `true` if the nibble vector has a length of 0.
    pub fn is_empty(&self) -> bool {
        self.data.is_empty()
    }

    /// Fetch a single entry from the vector.
    ///
    /// Guaranteed to be a value in the interval [0, 15].
    ///
    /// **Panics** if `idx >= self.len()`.
    pub fn get(&self, idx: usize) -> u8 {
        if idx >= self.length {
            panic!("attempted access beyond vector end. len is {}, index is {}", self.length, idx);
        }
        let vec_idx = idx / 2;
        match idx % 2 {
            // If the index is even, take the first (most significant) half of the stored byte.
            0 => self.data[vec_idx] >> 4,
            // If the index is odd, take the second (least significant) half.
            _ => self.data[vec_idx] & 0x0F
        }
    }

    /// Add a single nibble to the vector.
    ///
    /// Only the 4 least-significant bits of the value are used.
    pub fn push(&mut self, val: u8) {
        if self.length % 2 == 0 {
            self.data.push(val << 4);
        } else {
            let vec_len = self.data.len();

            // Zero the second half of the last byte just to be safe.
            self.data[vec_len - 1] &= 0xF0;

            // Write the new value.
            self.data[vec_len - 1] |= val & 0x0F;
        }
        self.length += 1;
    }

    /// Split the vector into two parts.
    ///
    /// All elements at or following the given index are returned in a new `NibbleVec`,
    /// with exactly `idx` elements remaining in this vector.
    ///
    /// **Panics** if `idx > self.len()`.
    pub fn split(&mut self, idx: usize) -> NibbleVec {
        if idx > self.length {
            panic!("attempted to split past vector end. len is {}, index is {}", self.length, idx);
        } else if idx == self.length {
            NibbleVec::new()
        } else if idx % 2 == 0 {
            self.split_even(idx)
        } else {
            self.split_odd(idx)
        }
    }

    /// Split function for odd *indices*.
    #[inline(always)]
    fn split_odd(&mut self, idx: usize) -> NibbleVec {
        let tail_vec_size = (self.length - idx) / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Perform an overlap copy, copying the last nibble of the original vector only if
        // the length of the new tail is *odd*.
        let tail_length = self.length - idx;
        let take_last = tail_length % 2 == 1;
        self.overlap_copy(idx / 2, self.data.len(), &mut tail.data, &mut tail.length, take_last);

        // Remove the copied bytes, being careful to skip the idx byte.
        for _ in (idx / 2 + 1) .. self.data.len() {
            self.data.pop();
        }

        // Zero the second half of the index byte so as to maintain the last-nibble invariant.
        self.data[idx / 2] &= 0xF0;

        // Update the length of the first NibbleVec.
        self.length = idx;

        tail
    }

    /// Split function for even *indices*.
    #[inline(always)]
    fn split_even(&mut self, idx: usize) -> NibbleVec {
        // Avoid allocating a temporary vector by copying all the bytes in order, then popping them.

        // Possible to prove: l_d - ⌊i / 2⌋ = ⌊(l_v - i + 1) / 2⌋
        //  where l_d = self.data.len()
        //        l_v = self.length
        let tail_vec_size = (self.length - idx + 1) / 2;
        let half_idx = idx / 2;
        let mut tail = NibbleVec::from_byte_vec(Vec::with_capacity(tail_vec_size));

        // Copy the bytes.
        for i in half_idx .. self.data.len() {
            tail.data.push(self.data[i]);
        }

        // Pop the same bytes.
        for _ in half_idx .. self.data.len() {
            self.data.pop();
        }

        // Update lengths.
        tail.length = self.length - idx;
        self.length = idx;

        tail
    }

    /// Copy data between the second half of self.data[start] and
    /// self.data[end - 1]. The second half of the last entry is included
    /// if include_last is true.
    #[inline(always)]
    fn overlap_copy(&self, start: usize, end: usize, vec: &mut Vec<u8>, length: &mut usize, include_last: bool) {
        // Copy up to the first half of the last byte.
        for i in start .. (end - 1) {
            // The first half is the second half of the old entry.
            let first_half = self.data[i] & 0x0f;

            // The second half is the first half of the next entry.
            let second_half = self.data[i + 1] >> 4;

            vec.push((first_half << 4) | second_half);
            *length += 2;
        }

        if include_last {
            let last = self.data[end - 1] & 0x0f;
            vec.push(last << 4);
            *length += 1;
        }
    }

    /// Append another nibble vector whilst consuming this vector.
    pub fn join(mut self, other: &NibbleVec) -> NibbleVec {
        // If the length is even, we can append directly.
        if self.length % 2 == 0 {
            self.length += other.length;
            self.data.extend(other.data.clone());
            return self;
        }

        // If the other vector is empty, bail out.
        if other.is_empty() {
            return self;
        }

        // If the length is odd, we have to perform an overlap copy.
        // Copy the first half of the first element, to make the vector an even length.
        self.push(other.get(0));

        // Copy the rest of the vector using an overlap copy.
        let take_last = other.len() % 2 == 0;
        other.overlap_copy(0, other.data.len(), &mut self.data, &mut self.length, take_last);

        self
    }
}

impl PartialEq<NibbleVec> for NibbleVec {
    fn eq(&self, other: &NibbleVec) -> bool {
        self.length == other.length &&
        self.data == other.data
    }
}

impl Eq for NibbleVec {}

/// Compare a `NibbleVec` and a slice of bytes *element-by-element*.
/// Bytes are **not** interpreted as two `NibbleVec` entries.
impl PartialEq<[u8]> for NibbleVec {
    fn eq(&self, other: &[u8]) -> bool {
        if other.len() != self.len() {
            return false;
        }

        for (i, x) in other.iter().enumerate() {
            if self.get(i) != *x {
                return false;
            }
        }
        true
    }
}

impl Debug for NibbleVec {
    fn fmt(&self, fmt: &mut Formatter) -> fmt::Result {
        try!(write!(fmt, "NibbleVec ["));

        if !self.is_empty() {
            try!(write!(fmt, "{}", self.get(0)));
        }

        for i in 1 .. self.len() {
            try!(write!(fmt, ", {}", self.get(i)));
        }
        write!(fmt, "]")
    }
}
<|endoftext|>


<commit_before>//! Algorithmia client library
//!
//! # Examples
//!
//! ```no_run
//! use algorithmia::Algorithmia;
//! use algorithmia::algo::{Algorithm, Version};
//!
//! // Initialize with an API key
//! let client = Algorithmia::client("111112222233333444445555566");
//! let moving_avg = client.algo(("timeseries/SimpleMovingAverage", "0.1"));
//!
//! // Run the algorithm using a type safe decoding of the output to Vec<int>
//! //   since this algorithm outputs results as a JSON array of integers
//! let input = (vec![0,1,2,3,15,4,5,6,7], 3);
//! let result: Vec<f64> = moving_avg.pipe(&input, None).unwrap().result().unwrap();
//! println!("Completed with result: {:?}", result);
//! ```

#![doc(html_logo_url = "https://algorithmia.com/assets/images/apple-touch-icon.png")]

#[macro_use]
extern crate hyper;
extern crate rustc_serialize;

use algo::{Algorithm, AlgoRef};
use data::{DataDir, DataFile, DataPath, HasDataPath};
use client::HttpClient;

use std::clone;

pub mod algo;
pub mod data;
pub mod error;
pub mod client;
pub mod json_helpers;
pub use hyper::{mime, Url};

static DEFAULT_API_BASE_URL: &'static str = "https://api.algorithmia.com";

/// The top-level struct for instantiating Algorithmia client endpoints
pub struct Algorithmia {
    http_client: HttpClient,
}

impl<'a, 'c> Algorithmia {
    /// Instantiate a new client
    pub fn client(api_key: &str) -> Algorithmia {
        Algorithmia {
            http_client: HttpClient::new(api_key.to_string(), DEFAULT_API_BASE_URL.to_string()),
        }
    }

    /// Instantiate a new client against alternate API servers
    pub fn alt_client(base_url: Url, api_key: &str) -> Algorithmia {
        Algorithmia {
            http_client: HttpClient::new(api_key.to_string(), base_url.serialize()),
        }
    }

    /// Instantiate an `Algorithm` from this client
    ///
    /// By using In
    /// # Examples
    ///
    /// ```
    /// use algorithmia::Algorithmia;
    /// use algorithmia::algo::Version;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let factor = client.algo("anowell/Dijkstra/0.1");
    /// let factor = client.algo(("anowell/Dijkstra", Version::Latest));
    /// ```
    pub fn algo<A: Into<AlgoRef>>(&self, algorithm: A) -> Algorithm {
        Algorithm::new(self.http_client.clone(), algorithm.into())
    }

    /// Instantiate a `DataDirectory` from this client
    ///
    /// # Examples
    ///
    /// ```
    /// use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let rustfoo = client.dir("data://.my/rustfoo");
    /// ```
    pub fn dir(&self, path: &'a str) -> DataDir {
        DataDir::new(self.http_client.clone(), path)
    }

    /// Instantiate a `DataDirectory` from this client
    ///
    /// # Examples
    ///
    /// ```
    /// use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let rustfoo = client.file("data://.my/rustfoo");
    /// ```
    pub fn file(&self, path: &'a str) -> DataFile {
        DataFile::new(self.http_client.clone(), path)
    }

    /// Instantiate a `DataPath` from this client
    ///
    /// Use this if you don't explicitly know if a Data URI is to a directory or file
    ///
    /// # Examples
    ///
    /// ```
    /// use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let rustfoo = client.data("data://.my/rustfoo/what_am_i");
    /// ```
    pub fn data(&self, path: &'a str) -> DataPath {
        DataPath::new(self.http_client.clone(), path)
    }

}

/// Allow cloning in order to reuse http client (and API key) for multiple connections
impl clone::Clone for Algorithmia {
    fn clone(&self) -> Algorithmia {
        Algorithmia {
            http_client: self.http_client.clone(),
        }
    }
}
<commit_msg>Minor doc update<commit_after>//! Algorithmia client library
//!
//! # Examples
//!
//! ```no_run
//! use algorithmia::Algorithmia;
//! use algorithmia::algo::{Algorithm, Version};
//!
//! // Initialize with an API key
//! let client = Algorithmia::client("111112222233333444445555566");
//! let moving_avg = client.algo(("timeseries/SimpleMovingAverage", "0.1"));
//!
//! // Run the algorithm using a type safe decoding of the output to Vec<int>
//! //   since this algorithm outputs results as a JSON array of integers
//! let input = (vec![0,1,2,3,15,4,5,6,7], 3);
//! let result: Vec<f64> = moving_avg.pipe(&input, None).unwrap().result().unwrap();
//! println!("Completed with result: {:?}", result);
//! ```

#![doc(html_logo_url = "https://algorithmia.com/assets/images/apple-touch-icon.png")]

#[macro_use]
extern crate hyper;
extern crate rustc_serialize;

use algo::{Algorithm, AlgoRef};
use data::{DataDir, DataFile, DataPath, HasDataPath};
use client::HttpClient;

use std::clone;

/// Interact with Algorithmia algorithms
pub mod algo;
/// Manage data for algorithms
pub mod data;
/// Error types
pub mod error;
/// Internal client (do not use directly) - use [Algorithmia struct](struct.Algorithmia.html) instead
pub mod client;
pub mod json_helpers;
pub use hyper::{mime, Url};

static DEFAULT_API_BASE_URL: &'static str = "https://api.algorithmia.com";

/// The top-level struct for instantiating Algorithmia client endpoints
pub struct Algorithmia {
    http_client: HttpClient,
}

impl<'a, 'c> Algorithmia {
    /// Instantiate a new client
    pub fn client(api_key: &str) -> Algorithmia {
        Algorithmia {
            http_client: HttpClient::new(api_key.to_string(), DEFAULT_API_BASE_URL.to_string()),
        }
    }

    /// Instantiate a new client against alternate API servers
    pub fn alt_client(base_url: Url, api_key: &str) -> Algorithmia {
        Algorithmia {
            http_client: HttpClient::new(api_key.to_string(), base_url.serialize()),
        }
    }

    /// Instantiate an `Algorithm` from this client
    ///
    /// By using In
    /// # Examples
    ///
    /// ```
    /// use algorithmia::Algorithmia;
    /// use algorithmia::algo::Version;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let factor = client.algo("anowell/Dijkstra/0.1");
    /// let factor = client.algo(("anowell/Dijkstra", Version::Latest));
    /// ```
    pub fn algo<A: Into<AlgoRef>>(&self, algorithm: A) -> Algorithm {
        Algorithm::new(self.http_client.clone(), algorithm.into())
    }

    /// Instantiate a `DataDirectory` from this client
    ///
    /// # Examples
    ///
    /// ```
    /// use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let rustfoo = client.dir("data://.my/rustfoo");
    /// ```
    pub fn dir(&self, path: &'a str) -> DataDir {
        DataDir::new(self.http_client.clone(), path)
    }

    /// Instantiate a `DataDirectory` from this client
    ///
    /// # Examples
    ///
    /// ```
    /// use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let rustfoo = client.file("data://.my/rustfoo");
    /// ```
    pub fn file(&self, path: &'a str) -> DataFile {
        DataFile::new(self.http_client.clone(), path)
    }

    /// Instantiate a `DataPath` from this client
    ///
    /// Use this if you don't explicitly know if a Data URI is to a directory or file
    ///
    /// # Examples
    ///
    /// ```
    /// use algorithmia::Algorithmia;
    /// let client = Algorithmia::client("111112222233333444445555566");
    /// let rustfoo = client.data("data://.my/rustfoo/what_am_i");
    /// ```
    pub fn data(&self, path: &'a str) -> DataPath {
        DataPath::new(self.http_client.clone(), path)
    }

}

/// Allow cloning in order to reuse http client (and API key) for multiple connections
impl clone::Clone for Algorithmia {
    fn clone(&self) -> Algorithmia {
        Algorithmia {
            http_client: self.http_client.clone(),
        }
    }
}
<|endoftext|>