<commit_before>use name::*;
use art::*;
use std::hash;
use std::hash::Hash;

/// Nominal, artful lists: Lists with names and articulation points
#[deriving(Show,Hash,PartialEq,Eq)]
pub enum List<'x,T> {
    Nil,
    Cons(T, Box<List<'x,T>>),
    Name(Name, Box<List<'x,T>>),
    Art(Art<'x, Box<List<'x,T>>>)
}

pub fn copy<'x,T:'x>(list:List<'x,T>) -> List<'x,T> {
    match list {
        List::Nil         => List::Nil,
        List::Cons(hd,tl) => List::Cons(hd, box copy(*tl)),
        List::Art(art)    => copy(*force(art)),
        List::Name(nm,tl) => {
            let (nm1,nm2) = fork(nm) ;
            let art = nart!(nm1, box copy(*tl)) ;
            List::Name(nm2, box List::Art(art))
        }
    }
}

pub fn map<'x, T:'x, S:'x>
(f:UAr<'x,T,S>, list:List<'x,T>) -> List<'x,S>
{
    match list {
        List::Nil         => List::Nil,
        List::Cons(hd,tl) => List::Cons((*f).call(hd), box map(f,*tl)),
        // - - - - - boilerplate cases - - - - - -
        List::Art(art)    => map(f,*force(art)),
        List::Name(nm,tl) => {
            let (nm1,nm2) = fork(nm) ;
            let art = nart!(nm1, box map(f,*tl));
            List::Name(nm2, box List::Art(art))
        }
    }
}

pub fn contract<'x,F,G,T:'x>
(f:&'x F, g:&'x G, list:List<'x,T>) -> List<'x,T>
where F:Fn(&T,&T) -> bool + 'x,
      G:Fn(T,T) -> T + 'x
{
    match list {
        List::Nil => List::Nil,
        List::Cons(hd1, box list) => {
            match list {
                List::Nil => List::Cons(hd1, box List::Nil),
                List::Cons(hd2, tl) => {
                    if (*f)(&hd1,&hd2) {
                        List::Cons((*g)(hd1,hd2), box contract(f,g,*tl))
                    } else {
                        List::Cons(hd1, box contract(f, g, List::Cons(hd2, tl)))
                    } },
                // - - - - - boilerplate cases - - - - - -
                List::Art(art) => contract(f,g,List::Cons(hd1,force(art))),
                List::Name(nm, tl) => {
                    let (nm1,nm2) = fork(nm) ;
                    let art = nart!(nm1, box contract(f,g,List::Cons(hd1,tl))) ;
                    List::Name(nm2, box List::Art(art))
                }
            }
        },
        // - - - - - boilerplate cases - - - - - -
        List::Art(art)    => contract(f,g,*force(art)),
        List::Name(nm,tl) => {
            let (nm1,nm2) = fork(nm) ;
            let art = nart!(nm1, box contract(f,g,*tl)) ;
            List::Name(nm2, box List::Art(art))
        },
    }
}

pub fn reduce<'x,F:'x,G:'x,T:'x>
(f:&'x F, g:&'x G, list:List<'x,T>) -> Option<T>
where F: Fn(&T,&T) -> bool,
      G: Fn(T, T) -> T,
{
    match list {
        List::Nil => None,
        List::Cons(hd, box list) => {
            match list {
                List::Nil => Some(hd),
                List::Cons(hd2, tl) => {
                    let hd3 = (*g)(hd,hd2) ;
                    let list = contract(f, g, List::Cons(hd3, tl)) ;
                    reduce (f, g, list)
                },
                // - - - - - boilerplate cases - - - - - -
                List::Name(_,tl) => reduce (f, g, *tl),
                List::Art(art)   => reduce (f, g, *force(art)),
            }},
        // - - - - - boilerplate cases - - - - - -
        List::Name(_,tl) => reduce(f, g, *tl),
        List::Art(art)   => reduce(f, g, *force(art)),
    }
}

pub fn merge<'x,T:'x,Ord:'x>
(ord:&'x Ord, list1:List<'x,T>, list2:List<'x,T>) -> List<'x,T>
where Ord: Fn(&T,&T) -> bool
{
    match (list1, list2) {
        (List::Nil, list2) => list2,
        (list1, List::Nil) => list1,
        (List::Cons(hd1,tl1),
         List::Cons(hd2,tl2)) =>
            if (*ord)(&hd1,&hd2) {
                List::Cons(hd1, box merge(ord, *tl1, List::Cons(hd2,tl2)))
            } else {
                List::Cons(hd2, box merge(ord, List::Cons(hd1,tl1), *tl2))
            },
        // - - - - - boilerplate cases - - - - -
        (List::Name(nm,tl), list2) => {
            let (nm1,nm2) = fork(nm) ;
            let art = nart!(nm1, box merge(ord, *tl, list2)) ;
            List::Name(nm2, box List::Art(art))
        },
        (list1, List::Name(nm,tl)) => {
            let (nm1,nm2) = fork(nm) ;
            let art = nart!(nm1, box merge(ord, list1, *tl)) ;
            List::Name(nm2, box List::Art(art))
        },
        (List::Art(art), list2) => merge(ord, *force(art), list2),
        (list1, List::Art(art)) => merge(ord, list1, *force(art)),
    }
}

pub fn singletons<'x,T:'x>
(list:List<'x,T>) -> List<'x,List<'x,T>>
{
    match list {
        List::Nil => List::Nil,
        List::Cons(hd, tl) => {
            List::Cons( List::Cons(hd, box List::Nil),
                        box singletons(*tl) )
        },
        List::Art(art) => singletons(*force(art)),
        List::Name(nm, tl) => {
            let (nm1, nm2) = fork(nm) ;
            let art = nart!(nm2, box singletons(*tl)) ;
            List::Name(nm1, box List::Art(art))
        }
    }
}

pub fn mergesort<'x,T:'x,Ord:'x>
(ord:&'x Ord, list:List<'x,T>) -> List<'x,T>
where Ord: Fn(&T,&T) -> bool, T:Hash
{
    let c = move |&: list1:&List<'x,T>,list2:&List<'x,T>| hash::hash(list1) < hash::hash(list2) ;
    let m = move |&: list1:List<'x,T>,list2:List<'x,T>| merge(ord,list1,list2) ;

    match reduce(&c, &m, singletons(list)) {
        None => List::Nil,
        Some(list) => list
    }
}

#[test]
pub fn construct_list () {
    let z : List<int> = List::Nil;
    let y : List<int> = List::Cons(1, box z);
    let x : List<int> = List::Art(cell(symbol(format!("two")), box y));
    let l : List<int> = List::Name(symbol(format!("one")), box x);
    println!("constructed list: {}", l);
}

// impl<T> List<T> {
//     /// Construct a new, empty list.
//     #[inline]
//     pub fn new() -> List<T> { Nil }
// }

// impl<T: Send + Sync> List<T> {
//     /// Create a list with one element in it.
//     #[inline]
//     pub fn singleton(n:Name,val: T) -> List<T> { Cons(val, Art::new(Nil)) }

//     /// Get the head of a list.
//     pub fn head(&self) -> Option<&T> {
//         match *self {
//             Nil => None,
//             Cons(ref head, _) => Some(head)
//         }
//     }

//     /// Get the tail of a list.
//     pub fn tail(&self) -> Option<Art<List<T>>> {
//         match *self {
//             Nil => None,
//             Cons(_, ref tail) => Some(tail.clone())
//         }
//     }

//     /// Get an iterator over the items in a list.
//     pub fn iter<'a>(&'a self) -> ListItems<'a, T> {
//         ListItems {
//             list: self
//         }
//     }
// }

// /// An iterator over the items in a list.
// pub struct ListItems<'a, T: 'a> {
//     list: &'a List<T>
// }

// impl<'a, T: Send + Sync> Iterator<&'a T> for ListItems<'a, T> {
//     fn next(&mut self) -> Option<&'a T> {
//         match *self.list {
//             Cons(ref head, ref tail) => {
//                 self.list = &**tail;
//                 Some(head)
//             },
//             Nil => None
//         }
//     }
// }

<commit_msg>shorter lines<commit_after>use name::*;
use art::*;
use std::hash;
use std::hash::Hash;

/// Nominal, artful lists: Lists with names and articulation points
#[deriving(Show,Hash,PartialEq,Eq)]
pub enum List<'x,T> {
    Nil,
    Cons(T, Box<List<'x,T>>),
    Name(Name, Box<List<'x,T>>),
    Art(Art<'x, Box<List<'x,T>>>)
}

pub fn copy<'x,T:'x>(list:List<'x,T>) -> List<'x,T> {
    match list {
        List::Nil         => List::Nil,
        List::Cons(hd,tl) => List::Cons(hd, box copy(*tl)),
        List::Art(art)    => copy(*force(art)),
        List::Name(nm,tl) => {
            let (nm1,nm2) = fork(nm) ;
            let art = nart!(nm1, box copy(*tl)) ;
            List::Name(nm2, box List::Art(art))
        }
    }
}

pub fn map<'x, T:'x, S:'x>
(f:UAr<'x,T,S>, list:List<'x,T>) -> List<'x,S>
{
    match list {
        List::Nil         => List::Nil,
        List::Cons(hd,tl) => List::Cons((*f).call(hd), box map(f,*tl)),
        // - - - - - boilerplate cases - - - - - -
        List::Art(art)    => map(f,*force(art)),
        List::Name(nm,tl) => {
            let (nm1,nm2) = fork(nm) ;
            let art = nart!(nm1, box map(f,*tl));
            List::Name(nm2, box List::Art(art))
        }
    }
}

pub fn contract<'x,F,G,T:'x>
(f:&'x F, g:&'x G, list:List<'x,T>) -> List<'x,T>
where F:Fn(&T,&T) -> bool + 'x,
      G:Fn(T,T) -> T + 'x
{
    match list {
        List::Nil => List::Nil,
        List::Cons(hd1, box list) => {
            match list {
                List::Nil => List::Cons(hd1, box List::Nil),
                List::Cons(hd2, tl) => {
                    if (*f)(&hd1,&hd2) {
                        List::Cons((*g)(hd1,hd2), box contract(f,g,*tl))
                    } else {
                        List::Cons(hd1, box contract(f, g, List::Cons(hd2, tl)))
                    } },
                // - - - - - boilerplate cases - - - - - -
                List::Art(art) => contract(f,g,List::Cons(hd1,force(art))),
                List::Name(nm, tl) => {
                    let (nm1,nm2) = fork(nm) ;
                    let art = nart!(nm1, box contract(f,g,List::Cons(hd1,tl))) ;
                    List::Name(nm2, box List::Art(art))
                }
            }
        },
        // - - - - - boilerplate cases - - - - - -
        List::Art(art)    => contract(f,g,*force(art)),
        List::Name(nm,tl) => {
            let (nm1,nm2) = fork(nm) ;
            let art = nart!(nm1, box contract(f,g,*tl)) ;
            List::Name(nm2, box List::Art(art))
        },
    }
}

pub fn reduce<'x,F:'x,G:'x,T:'x>
(f:&'x F, g:&'x G, list:List<'x,T>) -> Option<T>
where F: Fn(&T,&T) -> bool,
      G: Fn(T, T) -> T,
{
    match list {
        List::Nil => None,
        List::Cons(hd, box list) => {
            match list {
                List::Nil => Some(hd),
                List::Cons(hd2, tl) => {
                    let hd3 = (*g)(hd,hd2) ;
                    let list = contract(f, g, List::Cons(hd3, tl)) ;
                    reduce (f, g, list)
                },
                // - - - - - boilerplate cases - - - - - -
                List::Name(_,tl) => reduce (f, g, *tl),
                List::Art(art)   => reduce (f, g, *force(art)),
            }},
        // - - - - - boilerplate cases - - - - - -
        List::Name(_,tl) => reduce(f, g, *tl),
        List::Art(art)   => reduce(f, g, *force(art)),
    }
}

pub fn merge<'x,T:'x,Ord:'x>
(ord:&'x Ord, list1:List<'x,T>, list2:List<'x,T>) -> List<'x,T>
where Ord: Fn(&T,&T) -> bool
{
    match (list1, list2) {
        (List::Nil, list2) => list2,
        (list1, List::Nil) => list1,
        (List::Cons(hd1,tl1),
         List::Cons(hd2,tl2)) =>
            if (*ord)(&hd1,&hd2) {
                List::Cons(hd1, box merge(ord, *tl1, List::Cons(hd2,tl2)))
            } else {
                List::Cons(hd2, box merge(ord, List::Cons(hd1,tl1), *tl2))
            },
        // - - - - - boilerplate cases - - - - -
        (List::Name(nm,tl), list2) => {
            let (nm1,nm2) = fork(nm) ;
            let art = nart!(nm1, box merge(ord, *tl, list2)) ;
            List::Name(nm2, box List::Art(art))
        },
        (list1, List::Name(nm,tl)) => {
            let (nm1,nm2) = fork(nm) ;
            let art = nart!(nm1, box merge(ord, list1, *tl)) ;
            List::Name(nm2, box List::Art(art))
        },
        (List::Art(art), list2) => merge(ord, *force(art), list2),
        (list1, List::Art(art)) => merge(ord, list1, *force(art)),
    }
}

pub fn singletons<'x,T:'x>
(list:List<'x,T>) -> List<'x,List<'x,T>>
{
    match list {
        List::Nil => List::Nil,
        List::Cons(hd, tl) => {
            List::Cons( List::Cons(hd, box List::Nil),
                        box singletons(*tl) )
        },
        List::Art(art) => singletons(*force(art)),
        List::Name(nm, tl) => {
            let (nm1, nm2) = fork(nm) ;
            let art = nart!(nm2, box singletons(*tl)) ;
            List::Name(nm1, box List::Art(art))
        }
    }
}

pub fn mergesort<'x,T:'x,Ord:'x>
(ord:&'x Ord, list:List<'x,T>) -> List<'x,T>
where Ord: Fn(&T,&T) -> bool, T:Hash
{
    let c = move |&: list1:&List<'x,T>,list2:&List<'x,T>|
    hash::hash(list1) < hash::hash(list2);

    let m = move |&: list1:List<'x,T>,list2:List<'x,T>|
    merge(ord,list1,list2);

    match reduce(&c, &m, singletons(list)) {
        None => List::Nil,
        Some(list) => list
    }
}

#[test]
pub fn construct_list () {
    let z : List<int> = List::Nil;
    let y : List<int> = List::Cons(1, box z);
    let x : List<int> = List::Art(cell(symbol(format!("two")), box y));
    let l : List<int> = List::Name(symbol(format!("one")), box x);
    println!("constructed list: {}", l);
}

// impl<T> List<T> {
//     /// Construct a new, empty list.
//     #[inline]
//     pub fn new() -> List<T> { Nil }
// }

// impl<T: Send + Sync> List<T> {
//     /// Create a list with one element in it.
//     #[inline]
//     pub fn singleton(n:Name,val: T) -> List<T> { Cons(val, Art::new(Nil)) }

//     /// Get the head of a list.
//     pub fn head(&self) -> Option<&T> {
//         match *self {
//             Nil => None,
//             Cons(ref head, _) => Some(head)
//         }
//     }

//     /// Get the tail of a list.
//     pub fn tail(&self) -> Option<Art<List<T>>> {
//         match *self {
//             Nil => None,
//             Cons(_, ref tail) => Some(tail.clone())
//         }
//     }

//     /// Get an iterator over the items in a list.
//     pub fn iter<'a>(&'a self) -> ListItems<'a, T> {
//         ListItems {
//             list: self
//         }
//     }
// }

// /// An iterator over the items in a list.
// pub struct ListItems<'a, T: 'a> {
//     list: &'a List<T>
// }

// impl<'a, T: Send + Sync> Iterator<&'a T> for ListItems<'a, T> {
//     fn next(&mut self) -> Option<&'a T> {
//         match *self.list {
//             Cons(ref head, ref tail) => {
//                 self.list = &**tail;
//                 Some(head)
//             },
//             Nil => None
//         }
//     }
// }

<|endoftext|>


<commit_before>#![feature(slicing_syntax)]
#![feature(core, env, fs, os, path, io)]

extern crate cargo;
extern crate hyper;
extern crate puppetfile;
extern crate semver;
extern crate toml;
extern crate "rustc-serialize" as rustc_serialize;

use std::fs::File;
use std::env;
use std::io::Read;
use std::path::Path;
use std::old_path::Path as OldPath;
use std::sync::Future;
use dependency::{CargoDependency, ComposerDependency, Dependency, NpmDependency, PuppetDependency};
use semver::Version;

mod dependency;

fn get_published_versions<Dep: Dependency>(dependencies_to_check: &Vec<Dep>)
    -> Vec<(String, Version)> {

    let mut version_ftrs = dependencies_to_check.iter().map(|d| {
        let dependency = d.clone();

        Future::spawn(move || {
            (dependency.name().clone(), dependency.registry_version())
        })
    }).collect::<Vec<_>>();

    version_ftrs.iter_mut().map(|ftr| ftr.get()).filter_map(|tpl| match tpl {
        (name, Some(version)) => Some((name, version)),
        _ => None
    }).collect()
}

fn filter_dependencies<Dep: Dependency>(dependencies_to_check: &Vec<Dep>,
                                        published_versions: Vec<(String, Version)>)
    -> (Vec<(&Dep, Version)>, Vec<(&Dep, Version)>)
{
    let mut outdated_dependencies = dependencies_to_check.iter()
        .filter_map(|d| match published_versions.iter().find(|&&(ref name, _)| d.name() == name) {
            Some(&(_, ref version)) if !d.version_req().matches(version) => Some((d, version.clone())),
            _ => None
        })
        .collect::<Vec<_>>();

    let mut up_to_date_dependencies = dependencies_to_check.iter()
        .filter_map(|d| match published_versions.iter().find(|&&(ref name, _)| d.name() == name) {
            Some(&(_, ref version)) if d.version_req().matches(version) => Some((d, version.clone())),
            _ => None
        })
        .collect::<Vec<_>>();

    outdated_dependencies.sort_by(|&(ref d1, _), &(ref d2, _)| d1.name().cmp(d2.name()));
    up_to_date_dependencies.sort_by(|&(ref d1, _), &(ref d2, _)| d1.name().cmp(d2.name()));

    (outdated_dependencies, up_to_date_dependencies)
}

fn out<Dep>((outdated_dependencies, up_to_date_dependencies): (Vec<(&Dep, Version)>, Vec<(&Dep, Version)>))
    where Dep: Dependency
{
    println!("");

    for (dependency, version) in up_to_date_dependencies {
        println!("{}: {} matches {}", dependency.name(), version, dependency.version_req());
    }

    println!("");

    for (dependency, version) in outdated_dependencies {
        println!("{}: {} doesn't match {}", dependency.name(), version, dependency.version_req());
    }
}

fn check<Dep: Dependency>(dependencies: &Vec<Dep>) {
    out(filter_dependencies(dependencies, get_published_versions(dependencies)))
}

fn main() {
    let args = env::args().collect::<Vec<_>>();
    let new_path = Path::new(&args[1]);
    let path = &OldPath::new(&args[1]);
    let mut dependency_file_contents = String::new();
    if let Err(err) = File::open(path).map(|mut f|
       if let Err(err) = f.read_to_string(&mut dependency_file_contents) {
           println!("{}", err); return;
       }
    ) {
        println!("{}", err); return;
    };

    match new_path.file_name() {
        Some(name) if name.to_str() == Some("Cargo.toml") => {
            check(&<CargoDependency as Dependency>::to_check(&dependency_file_contents, path));
        }
        Some(name) if name.to_str() == Some("composer.json") => {
            check(&<ComposerDependency as Dependency>::to_check(&dependency_file_contents, path));
        }
        Some(name) if name.to_str() == Some("Puppetfile") => {
            check(&<PuppetDependency as Dependency>::to_check(&dependency_file_contents, path));
        }
        Some(name) if name.to_str() == Some("package.json") => {
            check(&<NpmDependency as Dependency>::to_check(&dependency_file_contents, path));
        }
        _ => {
            println!("File type not recognized");
        }
    };
}
<commit_msg>allow checking of multiple files<commit_after>#![feature(slicing_syntax)]
#![feature(core, env, fs, os, path, io)]

extern crate cargo;
extern crate hyper;
extern crate puppetfile;
extern crate semver;
extern crate toml;
extern crate "rustc-serialize" as rustc_serialize;

use std::fs::File;
use std::env;
use std::io::Read;
use std::path::Path;
use std::old_path::Path as OldPath;
use std::sync::Future;
use dependency::{CargoDependency, ComposerDependency, Dependency, NpmDependency, PuppetDependency};
use semver::Version;

mod dependency;

fn get_published_versions<Dep: Dependency>(dependencies_to_check: &Vec<Dep>)
    -> Vec<(String, Version)> {

    let mut version_ftrs = dependencies_to_check.iter().map(|d| {
        let dependency = d.clone();

        Future::spawn(move || {
            (dependency.name().clone(), dependency.registry_version())
        })
    }).collect::<Vec<_>>();

    version_ftrs.iter_mut().map(|ftr| ftr.get()).filter_map(|tpl| match tpl {
        (name, Some(version)) => Some((name, version)),
        _ => None
    }).collect()
}

fn filter_dependencies<Dep: Dependency>(dependencies_to_check: &Vec<Dep>,
                                        published_versions: Vec<(String, Version)>)
    -> (Vec<(&Dep, Version)>, Vec<(&Dep, Version)>)
{
    let mut outdated_dependencies = dependencies_to_check.iter()
        .filter_map(|d| match published_versions.iter().find(|&&(ref name, _)| d.name() == name) {
            Some(&(_, ref version)) if !d.version_req().matches(version) => Some((d, version.clone())),
            _ => None
        })
        .collect::<Vec<_>>();

    let mut up_to_date_dependencies = dependencies_to_check.iter()
        .filter_map(|d| match published_versions.iter().find(|&&(ref name, _)| d.name() == name) {
            Some(&(_, ref version)) if d.version_req().matches(version) => Some((d, version.clone())),
            _ => None
        })
        .collect::<Vec<_>>();

    outdated_dependencies.sort_by(|&(ref d1, _), &(ref d2, _)| d1.name().cmp(d2.name()));
    up_to_date_dependencies.sort_by(|&(ref d1, _), &(ref d2, _)| d1.name().cmp(d2.name()));

    (outdated_dependencies, up_to_date_dependencies)
}

fn out<Dep>((outdated_dependencies, up_to_date_dependencies): (Vec<(&Dep, Version)>, Vec<(&Dep, Version)>))
    where Dep: Dependency
{
    if up_to_date_dependencies.len() != 0 {
        println!("");

        for (dependency, version) in up_to_date_dependencies {
            println!("{}: {} matches {}", dependency.name(), version, dependency.version_req());
        }
    }

    if outdated_dependencies.len() != 0 {
        println!("");

        for (dependency, version) in outdated_dependencies {
            println!("{}: {} doesn't match {}", dependency.name(), version, dependency.version_req());
        }
    }
}

fn check<Dep: Dependency>(dependencies: &Vec<Dep>) {
    out(filter_dependencies(dependencies, get_published_versions(dependencies)))
}

fn main() {
    env::args().skip(1).map(|arg| {
        let new_path = Path::new(&arg);
        let path = &OldPath::new(&arg);
        let mut dependency_file_contents = String::new();
        if let Err(err) = File::open(path).map(|mut f|
           if let Err(err) = f.read_to_string(&mut dependency_file_contents) {
               println!("{}", err); return;
           }
        ) {
            println!("{}", err); return;
        };

        println!("File to check: {}", new_path.display());
        match new_path.file_name() {
            Some(name) if name.to_str() == Some("Cargo.toml") => {
                check(&<CargoDependency as Dependency>::to_check(&dependency_file_contents, path));
            }
            Some(name) if name.to_str() == Some("composer.json") => {
                check(&<ComposerDependency as Dependency>::to_check(&dependency_file_contents, path));
            }
            Some(name) if name.to_str() == Some("Puppetfile") => {
                check(&<PuppetDependency as Dependency>::to_check(&dependency_file_contents, path));
            }
            Some(name) if name.to_str() == Some("package.json") => {
                check(&<NpmDependency as Dependency>::to_check(&dependency_file_contents, path));
            }
            _ => {
                println!("File type not recognized");
            }
        };
        println!("\n");
    }).collect::<Vec<_>>();
}
<|endoftext|>


<commit_before>extern crate csv;
#[macro_use]
extern crate lazy_static;
extern crate prettytable;
extern crate regex;
extern crate rusqlite;
extern crate rustyline;

use std::env;
use std::error::Error;

fn _normalize_col(col: &str) -> String {
    lazy_static! {
        static ref RE: regex::Regex = regex::Regex::new(r"\(.*?\)").unwrap();
    }
    return RE
        .replace_all(col, "")
        .to_lowercase()
        .trim()
        .replace(" ", "_")
        .replace(".", "_")
        .replace("?", "");
}

fn _create_table(db: &mut rusqlite::Connection, table_name: &str, cols: &Vec<String>) {
    let create_columns = cols
        .iter()
        .map(|c| format!("{} varchar", c))
        .collect::<Vec<String>>()
        .join(", ");
    db.execute(
        &format!("CREATE TABLE {} ({})", table_name, create_columns),
        &[] as &[&rusqlite::types::ToSql],
    )
    .unwrap();
}

fn _insert_row(db: &mut rusqlite::Connection, row: csv::StringRecord, insert_query: &str) {
    let mut stmt = db.prepare(insert_query).unwrap();

    let res = stmt.execute(&row);
    assert!(res.is_ok());
}

fn _load_table_from_path(
    db: &mut rusqlite::Connection,
    table_name: &str,
    path: String,
) -> Vec<String> {
    let mut num_rows = 0;
    let mut reader = csv::Reader::from_path(path).unwrap();

    let normalized_cols =
        reader
            .headers()
            .unwrap()
            .iter()
            .map(_normalize_col)
            .fold(vec![], |mut v, orig_col| {
                let mut col = orig_col.clone();
                let mut i = 1;
                while v.contains(&col) {
                    col = format!("{}_{}", orig_col, i);
                    i += 1
                }
                v.push(col);
                return v;
            });
    _create_table(db, table_name, &normalized_cols);

    let insert_query = format!(
        "INSERT INTO {} VALUES ({})",
        table_name,
        normalized_cols
            .iter()
            .map(|_| "?")
            .collect::<Vec<_>>()
            .join(", ")
    );
    for row in reader.records() {
        _insert_row(db, row.unwrap(), &insert_query);
        num_rows += 1;
    }

    println!(
        "Loaded {} rows into {}({})",
        num_rows,
        table_name,
        normalized_cols.join(", "),
    );
    return normalized_cols;
}

struct FromAnySqlType {
    value: String,
}

impl rusqlite::types::FromSql for FromAnySqlType {
    fn column_result(
        value: rusqlite::types::ValueRef,
    ) -> Result<FromAnySqlType, rusqlite::types::FromSqlError> {
        let result = match value {
            rusqlite::types::ValueRef::Null => "null".to_string(),
            rusqlite::types::ValueRef::Integer(v) => v.to_string(),
            rusqlite::types::ValueRef::Real(v) => v.to_string(),
            rusqlite::types::ValueRef::Text(v) => v.to_string(),
            rusqlite::types::ValueRef::Blob(v) => String::from_utf8(v.to_vec()).unwrap(),
        };
        Ok(FromAnySqlType { value: result })
    }
}

fn _print_table(conn: &mut rusqlite::Connection, line: &str) {
    let mut table = prettytable::Table::new();
    table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE);
    let mut stmt = match conn.prepare(&line) {
        Ok(stmt) => stmt,
        Err(e) => {
            println!("{}", e.description());
            return;
        }
    };
    let mut results = stmt.query(&[] as &[&rusqlite::types::ToSql]).unwrap();
    while let Ok(Some(r)) = results.next() {
        let mut row = prettytable::Row::new(vec![]);
        for i in 0..r.column_count() {
            let cell: FromAnySqlType = r.get(i).unwrap();
            row.add_cell(prettytable::Cell::new(&cell.value));
        }
        table.add_row(row);
    }
    table.printstd();
}

struct SimpleWordCompleter {
    words: Vec<String>,
}

static BREAK_CHARS: [u8; 4] = [b' ', b'(', b')', b','];
impl SimpleWordCompleter {
    fn new(words: Vec<String>) -> SimpleWordCompleter {
        return SimpleWordCompleter { words: words };
    }
}

impl rustyline::Helper for SimpleWordCompleter {}

impl rustyline::hint::Hinter for SimpleWordCompleter {
    fn hint(&self, _line: &str, _pos: usize) -> Option<String> {
        return None;
    }
}

impl rustyline::highlight::Highlighter for SimpleWordCompleter {}

impl rustyline::completion::Completer for SimpleWordCompleter {
    type Candidate = String;

    fn complete(&self, line: &str, pos: usize) -> rustyline::Result<(usize, Vec<String>)> {
        let (start, word) = rustyline::completion::extract_word(line, pos, None, &BREAK_CHARS);

        let matches = self
            .words
            .iter()
            .filter(|w| w.starts_with(word))
            .cloned()
            .collect();
        return Ok((start, matches));
    }
}

fn main() {
    let mut paths = env::args().skip(1);

    let mut conn = rusqlite::Connection::open_in_memory().unwrap();

    let mut base_words = vec![
        "distinct", "select", "from", "group", "by", "order", "where", "count", "limit", "offset",
    ]
    .iter()
    .map(|s| s.to_string())
    .collect::<Vec<String>>();

    if paths.len() == 1 {
        let mut col_names = _load_table_from_path(&mut conn, "t", paths.next().unwrap());
        base_words.append(&mut col_names);
    } else {
        for (idx, path) in paths.enumerate() {
            let mut col_names = _load_table_from_path(&mut conn, &format!("t{}", idx + 1), path);
            base_words.append(&mut col_names);
        }
    }

    let completer = SimpleWordCompleter::new(base_words);
    let mut rl = rustyline::Editor::new();
    rl.set_helper(Some(completer));
    loop {
        match rl.readline("> ") {
            Ok(line) => {
                if line.trim().is_empty() {
                    continue;
                }
                rl.add_history_entry(line.clone());
                _print_table(&mut conn, &line);
            }
            Err(rustyline::error::ReadlineError::Interrupted) => {
                println!("Interrupted");
                continue;
            }
            Err(rustyline::error::ReadlineError::Eof) => {
                break;
            }
            Err(err) => {
                println!("Error: {}", err);
                break;
            }
        }
    }
}
<commit_msg>clippy<commit_after>extern crate csv;
#[macro_use]
extern crate lazy_static;
extern crate prettytable;
extern crate regex;
extern crate rusqlite;
extern crate rustyline;

use std::env;
use std::error::Error;

fn _normalize_col(col: &str) -> String {
    lazy_static! {
        static ref RE: regex::Regex = regex::Regex::new(r"\(.*?\)").unwrap();
    }
    RE.replace_all(col, "")
        .to_lowercase()
        .trim()
        .replace(" ", "_")
        .replace(".", "_")
        .replace("?", "")
}

fn _create_table(db: &mut rusqlite::Connection, table_name: &str, cols: &[String]) {
    let create_columns = cols
        .iter()
        .map(|c| format!("{} varchar", c))
        .collect::<Vec<String>>()
        .join(", ");
    db.execute(
        &format!("CREATE TABLE {} ({})", table_name, create_columns),
        &[] as &[&rusqlite::types::ToSql],
    )
    .unwrap();
}

fn _insert_row(db: &mut rusqlite::Connection, row: csv::StringRecord, insert_query: &str) {
    let mut stmt = db.prepare(insert_query).unwrap();

    let res = stmt.execute(&row);
    assert!(res.is_ok());
}

fn _load_table_from_path(
    db: &mut rusqlite::Connection,
    table_name: &str,
    path: String,
) -> Vec<String> {
    let mut num_rows = 0;
    let mut reader = csv::Reader::from_path(path).unwrap();

    let normalized_cols =
        reader
            .headers()
            .unwrap()
            .iter()
            .map(_normalize_col)
            .fold(vec![], |mut v, orig_col| {
                let mut col = orig_col.clone();
                let mut i = 1;
                while v.contains(&col) {
                    col = format!("{}_{}", orig_col, i);
                    i += 1
                }
                v.push(col);
                v
            });
    _create_table(db, table_name, &normalized_cols);

    let insert_query = format!(
        "INSERT INTO {} VALUES ({})",
        table_name,
        normalized_cols
            .iter()
            .map(|_| "?")
            .collect::<Vec<_>>()
            .join(", ")
    );
    for row in reader.records() {
        _insert_row(db, row.unwrap(), &insert_query);
        num_rows += 1;
    }

    println!(
        "Loaded {} rows into {}({})",
        num_rows,
        table_name,
        normalized_cols.join(", "),
    );
    normalized_cols
}

struct FromAnySqlType {
    value: String,
}

impl rusqlite::types::FromSql for FromAnySqlType {
    fn column_result(
        value: rusqlite::types::ValueRef,
    ) -> Result<FromAnySqlType, rusqlite::types::FromSqlError> {
        let result = match value {
            rusqlite::types::ValueRef::Null => "null".to_string(),
            rusqlite::types::ValueRef::Integer(v) => v.to_string(),
            rusqlite::types::ValueRef::Real(v) => v.to_string(),
            rusqlite::types::ValueRef::Text(v) => v.to_string(),
            rusqlite::types::ValueRef::Blob(v) => String::from_utf8(v.to_vec()).unwrap(),
        };
        Ok(FromAnySqlType { value: result })
    }
}

fn _print_table(conn: &mut rusqlite::Connection, line: &str) {
    let mut table = prettytable::Table::new();
    table.set_format(*prettytable::format::consts::FORMAT_NO_LINESEP_WITH_TITLE);
    let mut stmt = match conn.prepare(&line) {
        Ok(stmt) => stmt,
        Err(e) => {
            println!("{}", e.description());
            return;
        }
    };
    let mut results = stmt.query(&[] as &[&rusqlite::types::ToSql]).unwrap();
    while let Ok(Some(r)) = results.next() {
        let mut row = prettytable::Row::new(vec![]);
        for i in 0..r.column_count() {
            let cell: FromAnySqlType = r.get(i).unwrap();
            row.add_cell(prettytable::Cell::new(&cell.value));
        }
        table.add_row(row);
    }
    table.printstd();
}

struct SimpleWordCompleter {
    words: Vec<String>,
}

static BREAK_CHARS: [u8; 4] = [b' ', b'(', b')', b','];
impl SimpleWordCompleter {
    fn new(words: Vec<String>) -> SimpleWordCompleter {
        SimpleWordCompleter { words }
    }
}

impl rustyline::Helper for SimpleWordCompleter {}

impl rustyline::hint::Hinter for SimpleWordCompleter {
    fn hint(&self, _line: &str, _pos: usize) -> Option<String> {
        None
    }
}

impl rustyline::highlight::Highlighter for SimpleWordCompleter {}

impl rustyline::completion::Completer for SimpleWordCompleter {
    type Candidate = String;

    fn complete(&self, line: &str, pos: usize) -> rustyline::Result<(usize, Vec<String>)> {
        let (start, word) = rustyline::completion::extract_word(line, pos, None, &BREAK_CHARS);

        let matches = self
            .words
            .iter()
            .filter(|w| w.starts_with(word))
            .cloned()
            .collect();
        Ok((start, matches))
    }
}

fn main() {
    let mut paths = env::args().skip(1);

    let mut conn = rusqlite::Connection::open_in_memory().unwrap();

    let mut base_words = vec![
        "distinct", "select", "from", "group", "by", "order", "where", "count", "limit", "offset",
    ]
    .iter()
    .map(|s| s.to_string())
    .collect::<Vec<String>>();

    if paths.len() == 1 {
        let mut col_names = _load_table_from_path(&mut conn, "t", paths.next().unwrap());
        base_words.append(&mut col_names);
    } else {
        for (idx, path) in paths.enumerate() {
            let mut col_names = _load_table_from_path(&mut conn, &format!("t{}", idx + 1), path);
            base_words.append(&mut col_names);
        }
    }

    let completer = SimpleWordCompleter::new(base_words);
    let mut rl = rustyline::Editor::new();
    rl.set_helper(Some(completer));
    loop {
        match rl.readline("> ") {
            Ok(line) => {
                if line.trim().is_empty() {
                    continue;
                }
                rl.add_history_entry(line.clone());
                _print_table(&mut conn, &line);
            }
            Err(rustyline::error::ReadlineError::Interrupted) => {
                println!("Interrupted");
                continue;
            }
            Err(rustyline::error::ReadlineError::Eof) => {
                break;
            }
            Err(err) => {
                println!("Error: {}", err);
                break;
            }
        }
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io;
use std::io::{Read, BufRead, BufReader};
use std::env;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Instruction {
    Right,
    Left,
    Increment,
    Decrement,
    Output,
    Input,
    JumpOpen(usize),
    JumpClose(usize),
    Comment(char),
    End,
}

impl From<char> for Instruction {
    fn from(c: char) -> Instruction {
        match c {
            '>' => Instruction::Right,
            '<' => Instruction::Left,
            '+' => Instruction::Increment,
            '-' => Instruction::Decrement,
            '.' => Instruction::Output,
            ',' => Instruction::Input,
            '[' => Instruction::JumpOpen(0),
            ']' => Instruction::JumpClose(0),
            c => Instruction::Comment(c),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
struct Programme {
    instructions: Vec<Instruction>,
    index: usize,
}

impl Programme {

    fn parse<R>(r: R) -> Result<Programme, io::Error>
        where R: BufRead
    {

        let mut instructions = Vec::new();
        let mut braces = Vec::new();

        let mut instr_id = 0;
        for b in r.bytes() {

            let c = try!(b);

            let mut instr = Instruction::from(c as char);

            match instr {
                Instruction::Comment(_) => continue,
                Instruction::JumpOpen(_) => braces.push(instr_id),
                Instruction::JumpClose(_) => {
                    let i_open = braces.pop().unwrap();
                    instructions[i_open] = Instruction::JumpOpen(instr_id - i_open);
                    instr = Instruction::JumpClose(instr_id - i_open);
                },
                _ => {},
            }
            instructions.push(instr);
            instr_id += 1;

        }

        instructions.push(Instruction::End);

        Ok(Programme{instructions: instructions, index: 0})

    }

    fn step(&mut self, ms: &mut MachineState) {
        match self.instructions[self.index] {
            Instruction::Right => {
                ms.index += 1;
                let len = ms.tape.len();
                if ms.index >= len {
                    ms.tape.extend(vec![0u8; len]);
                }
            },
            Instruction::Left => ms.index -= 1,
            Instruction::Increment => ms.tape[ms.index] = ms.tape[ms.index].wrapping_add(1),
            Instruction::Decrement => ms.tape[ms.index] = ms.tape[ms.index].wrapping_sub(1),
            Instruction::Output => print!("{}", ms.tape[ms.index] as char),
            Instruction::Input => ms.tape[ms.index] = match io::stdin().bytes().next() {
                Some(r) => r.unwrap_or(0),
                None => 0,
            },
            Instruction::JumpOpen(offset) => if ms.tape[ms.index] == 0 {
                self.index += offset;
            },
            Instruction::JumpClose(offset) => if ms.tape[ms.index] != 0 {
                self.index -= offset + 1;
            },
            Instruction::Comment(_) => {},
            Instruction::End => return,
        }
        self.index += 1;
    }

    fn execute(&mut self, mut ms: &mut MachineState) {
        while self.instructions[self.index] != Instruction::End {
            self.step(&mut ms);
        }
    }

}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
struct MachineState {
    tape: Vec<u8>,
    index: usize,
}

fn main() {

    let argv: Vec<String> = env::args().collect();

    let file = File::open(&argv[1]).unwrap();
    let mut buffer = BufReader::new(file);

    let mut prgm = Programme::parse(&mut buffer).unwrap();

    let mut state = MachineState{
        tape: vec![0u8; 8192],
        .. MachineState::default()
    };

    prgm.execute(&mut state);

}
<commit_msg>rename variable to satisfy pedantic nature<commit_after>use std::fs::File;
use std::io;
use std::io::{Read, BufRead, BufReader};
use std::env;

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
enum Instruction {
    Right,
    Left,
    Increment,
    Decrement,
    Output,
    Input,
    JumpOpen(usize),
    JumpClose(usize),
    Comment(char),
    End,
}

impl From<char> for Instruction {
    fn from(c: char) -> Instruction {
        match c {
            '>' => Instruction::Right,
            '<' => Instruction::Left,
            '+' => Instruction::Increment,
            '-' => Instruction::Decrement,
            '.' => Instruction::Output,
            ',' => Instruction::Input,
            '[' => Instruction::JumpOpen(0),
            ']' => Instruction::JumpClose(0),
            c => Instruction::Comment(c),
        }
    }
}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
struct Programme {
    instructions: Vec<Instruction>,
    index: usize,
}

impl Programme {

    fn parse<R>(r: R) -> Result<Programme, io::Error>
        where R: BufRead
    {

        let mut instructions = Vec::new();
        let mut sq_brackets = Vec::new();

        let mut instr_id = 0;
        for b in r.bytes() {

            let c = try!(b);

            let mut instr = Instruction::from(c as char);

            match instr {
                Instruction::Comment(_) => continue,
                Instruction::JumpOpen(_) => sq_brackets.push(instr_id),
                Instruction::JumpClose(_) => {
                    let i_open = sq_brackets.pop().unwrap();
                    instructions[i_open] = Instruction::JumpOpen(instr_id - i_open);
                    instr = Instruction::JumpClose(instr_id - i_open);
                },
                _ => {},
            }
            instructions.push(instr);
            instr_id += 1;

        }

        instructions.push(Instruction::End);

        Ok(Programme{instructions: instructions, index: 0})

    }

    fn step(&mut self, ms: &mut MachineState) {
        match self.instructions[self.index] {
            Instruction::Right => {
                ms.index += 1;
                let len = ms.tape.len();
                if ms.index >= len {
                    ms.tape.extend(vec![0u8; len]);
                }
            },
            Instruction::Left => ms.index -= 1,
            Instruction::Increment => ms.tape[ms.index] = ms.tape[ms.index].wrapping_add(1),
            Instruction::Decrement => ms.tape[ms.index] = ms.tape[ms.index].wrapping_sub(1),
            Instruction::Output => print!("{}", ms.tape[ms.index] as char),
            Instruction::Input => ms.tape[ms.index] = match io::stdin().bytes().next() {
                Some(r) => r.unwrap_or(0),
                None => 0,
            },
            Instruction::JumpOpen(offset) => if ms.tape[ms.index] == 0 {
                self.index += offset;
            },
            Instruction::JumpClose(offset) => if ms.tape[ms.index] != 0 {
                self.index -= offset + 1;
            },
            Instruction::Comment(_) => {},
            Instruction::End => return,
        }
        self.index += 1;
    }

    fn execute(&mut self, mut ms: &mut MachineState) {
        while self.instructions[self.index] != Instruction::End {
            self.step(&mut ms);
        }
    }

}

#[derive(Debug, Clone, PartialEq, Eq, Default)]
struct MachineState {
    tape: Vec<u8>,
    index: usize,
}

fn main() {

    let argv: Vec<String> = env::args().collect();

    let file = File::open(&argv[1]).unwrap();
    let mut buffer = BufReader::new(file);

    let mut prgm = Programme::parse(&mut buffer).unwrap();

    let mut state = MachineState{
        tape: vec![0u8; 8192],
        .. MachineState::default()
    };

    prgm.execute(&mut state);

}
<|endoftext|>


<commit_before>extern crate r2d2;
extern crate r2d2_postgres;
extern crate openssl;
#[macro_use] extern crate nickel;
extern crate nickel_postgres;
extern crate uuid;
extern crate serde_json;
extern crate cas;
extern crate crypto;
extern crate time;
extern crate hyper;
extern crate rustc_serialize;
extern crate cookie;
extern crate core;

use std::env;
use std::io::Read;
use r2d2::{NopErrorHandler, PooledConnection};
use r2d2_postgres::{SslMode, PostgresConnectionManager};
use nickel::{Nickel, HttpRouter, QueryString};
use nickel_postgres::{PostgresMiddleware, PostgresRequestExtensions};
use uuid::Uuid;
use nickel::status::StatusCode;
use nickel::extensions::response::Redirect;
use serde_json::Value;
use cas::{CasClient, ServiceResponse, VerifyError};
use crypto::hmac::Hmac;
use crypto::sha2::Sha512Trunc224;
use crypto::mac::{Mac, MacResult};
use hyper::header::Headers;
use hyper::header::{Cookie, SetCookie};
use time::{now, Tm, strptime, Duration};
use rustc_serialize::base64::{ToBase64, FromBase64, URL_SAFE, FromBase64Error };
use cookie::Cookie as CookiePair;
use std::string::ToString;
use std::str::FromStr;
use std::str::from_utf8;
use std::str::Utf8Error;
use std::fmt;
use core::fmt::Debug;

macro_rules! try_or_return {
    ( $op:expr, $error:expr ) => {
        match $op {
            Some(v) => v,
            None => return $error
        }
    }
}

macro_rules! try_or {
    ( $op:expr, $error:expr ) => {
        match $op {
            Ok(v) => v,
            Err(e) => {
                println!("error: {:?}", e);
                return $error;
            }
        }
    }
}

fn create_tables(conn: PooledConnection<PostgresConnectionManager>) {
    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS services (
                key UUID PRIMARY KEY,
                name VARCHAR NOT NULL
                )",
            &[]
        );

    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS users (
                key SERIAL PRIMARY KEY,
                caseid VARCHAR UNIQUE NOT NULL,
                slackid VARCHAR UNIQUE
                )",
            &[]
        );

    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS permissions (
                key UUID REFERENCES services,
                username integer REFERENCES users,
                permissions JSONB,
                PRIMARY KEY (key, username)
                )",
            &[]
        );
}

fn main() {
    let mut app = Nickel::new();

    let hmac_secret = env::var("SECRET").expect("No SECRET found");

    let postgres_url = env::var("DATABASE_URL")
        .expect("Failed to get DATABASE_URL");

    let dbpool = PostgresMiddleware::new(&*postgres_url,
                                         SslMode::None,
                                         5,
                                         Box::new(NopErrorHandler)).unwrap();

    create_tables(dbpool.pool.clone().get().unwrap());
    app.utilize(dbpool);
    app.get("/register", middleware! { |request, response|
        let conn = request.db_conn();

        let name = try_or_return!(request.query().get("service_name"),
            response.error(
                StatusCode::BadRequest, "No service_name specified"));

        let key = Uuid::new_v4();

        let r = conn.execute(
            "INSERT INTO services (key, name) VALUES ($1, $2)",
            &[&key, &name]
            );
        println!("{:?}", r);

        key.to_hyphenated_string()
    });

    app.post("/adduser", middleware! { |request, response|
        let conn = request.db_conn();

        let mut body = vec![];
        try_or!(request.origin.read_to_end(&mut body),
                       response.error(StatusCode::InternalServerError,
                                      "Failed"));

        let permissions = try_or!(String::from_utf8(body),
            response.error(StatusCode::InternalServerError, "Failed"));

        let data: Value = try_or_return!(
            serde_json::from_str(&permissions).ok(),
            response.error(StatusCode::InternalServerError, "Failed"));

        let q = request.query();

        let caseid = try_or_return!(q.get("caseid"),
            response.error(StatusCode::BadRequest, "No username specified"));
        let key = try_or_return!(q.get("key").map(|s| Uuid::parse_str(s).ok()),
            response.error(StatusCode::BadRequest, "No key specified"));

        let user_rows = try_or!(conn.query(
                "INSERT INTO users (caseid) VALUES ($1)
                    ON CONFLICT (caseid) DO UPDATE SET caseid=users.caseid
                    RETURNING key",
                &[&caseid]
                ), response.error(StatusCode::InternalServerError,
                                  "Server Error")
            );
        if user_rows.len() != 1 {
            return response.error(StatusCode::InternalServerError,
                                  "Server Error");
        }

        let user = user_rows.get(0);
        let user_key: i32 = user.get(0);

        let r = try_or!(conn.execute(
            "INSERT INTO permissions (key, username, permissions)
                VALUES ($1, $2, $3)
                ON CONFLICT (key, username) DO UPDATE SET
                permissions=excluded.permissions",
                &[&key, &user_key, &data]
            ),
            response.error(StatusCode::InternalServerError, "Server error"));
        println!("{:?}", r);
        format!("You posted {}", permissions)
    });

    app.get("/getperms", middleware! { |request, response|
        let conn = request.db_conn();
        let q = request.query();
        let key = try_or_return!(q.get("key").map(|s| Uuid::parse_str(s).ok()),
            response.error(StatusCode::BadRequest, "No key specified"));

        let caseid = q.get("caseid").unwrap_or("");
        let slackid = q.get("slackid").unwrap_or("");

        let r = try_or!(conn.query(
                "SELECT permissions FROM permissions
                    INNER JOIN users
                    ON (permissions.username = users.key)
                    WHERE (caseid=$1 or slackid=$2) and permissions.key=$3",
                &[&caseid, &slackid, &key]
                ), response.error(StatusCode::InternalServerError,
                                  "Server Error")
            );
        println!("{:?}", r);

        if r.len() < 1 {
            return response.error(StatusCode::NotFound, "User not found");
        }
        let row = r.get(0);
        let s: Value = row.get(0);

        format!("{:?}", s)
    });

    let secret = hmac_secret.clone();
    app.get("/login", middleware! { |request, mut response|
        let base_url = env::var("BASE_URL")
            .unwrap_or("https://login.case.edu".to_string());
        let login_path = env::var("LOGIN_PATH")
            .unwrap_or("/cas/login".to_string());
        let logout_path = env::var("LOGOUT_PATH")
            .unwrap_or("/cas/logout".to_string());
        let verify_path = env::var("VERIFY_PATH")
            .unwrap_or("/cas/serviceValidate".to_string());
        let service_url = env::var("URL")
            .unwrap_or("http://hacsoc-auth.case.edu/login".to_string());

        let cas = try_or!(CasClient::new(&base_url, &login_path, &logout_path,
                                         &verify_path, &service_url),
                          response.error(StatusCode::InternalServerError,
                                         "Server Error"));
        match cas.verify_from_request(&request.origin) {
            Ok(ServiceResponse::Success(v)) => {
                set_auth_cookie(&secret, &v, response.headers_mut());
                return response.redirect("/setslackid");
            }
            Ok(ServiceResponse::Failure(e)) => format!("error: {:?}", e),
            Err(VerifyError::NoTicketFound) =>
                return response.redirect(cas.get_login_url()),
            Err(_) => return response.error(StatusCode::InternalServerError,
                                            "Server Error"),
        }
    });

    let secret = hmac_secret.clone();
    app.get("/setslackid", middleware! { |request, response|
        if verify_auth_cookie(&secret, &request.origin.headers) {
            "You logged in! A form will be here later"
        } else {
            return response.redirect("/login");
        }
    });

    let listen = match env::var("LISTEN") {
        Ok(s) => s,
        Err(_) => "127.0.0.1:8080".to_string()
    };

    app.listen(&listen[..]);
}

struct AuthToken {
    time: Tm,
    username: String,
    hmac: MacResult,
}

impl Debug for AuthToken {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "AuthToken {{ time: {:?}, username: {}, hmac: {:?} }}",
               self.time, self.username, self.hmac.code().to_base64(URL_SAFE))
    }
}

impl AuthToken {
    fn new(hmac_secret: &str, username: &str) -> AuthToken {
        AuthToken::new_with_time(hmac_secret, username, now().to_utc())
    }

    fn new_with_time(hmac_secret: &str, username: &str, t: Tm) -> AuthToken {
        let mut hmac = Hmac::new(Sha512Trunc224::new(), hmac_secret.as_bytes());
        let text = format!("{}.{}", username, t.rfc3339());
        hmac.input(text.as_bytes());

        AuthToken {
            time: t,
            username: username.to_string(),
            hmac: hmac.result(),
        }

    }

    fn verify_token(good: &AuthToken, unknown: &AuthToken) -> bool {
        let mut is_good = true;

        is_good = is_good && (good.hmac == unknown.hmac);

        let timeout = Duration::minutes(5);

        is_good = is_good && (unknown.time >= (now().to_utc() - timeout));

        is_good
    }

}

impl ToString for AuthToken {
    fn to_string(&self) -> String {
        let text = format!("{}.{}", self.username, self.time.to_timespec().sec)
            .as_bytes()
            .to_base64(URL_SAFE);

        format!("{}.{}", text, self.hmac.code().to_base64(URL_SAFE))
    }
}

#[derive(Debug)]
enum TokenError {
    Base64(FromBase64Error),
    FirstDotNotFound,
    Utf8(Utf8Error),
    SecondDotNotFound,
}

impl From<FromBase64Error> for TokenError {
    fn from(e: FromBase64Error) -> TokenError {
        TokenError::Base64(e)
    }
}

impl From<Utf8Error> for TokenError {
    fn from(e: Utf8Error) -> TokenError {
        TokenError::Utf8(e)
    }
}

impl FromStr for AuthToken {
    type Err = TokenError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let parts: Vec<&str> = s.split('.').collect();
        if parts.len() != 2 {
            return Err(TokenError::FirstDotNotFound);
        }

        let hmacpart = try!(parts.get(1).unwrap().from_base64());
        let hmac = MacResult::new_from_owned(hmacpart);

        let user = try!(parts.get(0).unwrap().from_base64());
        let userparts: Vec<&str> = try!(from_utf8(&user)).split('.').collect();
        if userparts.len() != 2 {
            return Err(TokenError::SecondDotNotFound);
        }

        let username = userparts.get(0).unwrap();
        let t = strptime(userparts.get(1).unwrap(), "%s").unwrap().to_utc();

        Ok(AuthToken {
            time: t,
            username: username.to_string(),
            hmac: hmac,
        })
    }
}

fn set_auth_cookie(hmac_secret: &str, username: &str, headers: &mut Headers) {
    let token = AuthToken::new(hmac_secret, username);
    let c_pair = CookiePair::new("auth_token".to_string(), token.to_string());

    match headers.get_mut::<SetCookie>() {
        Some(c) => {
            c.push(c_pair);
            return;
        },
        None => {}
    };
    headers.set::<SetCookie>(SetCookie(vec![c_pair]));
}

fn verify_auth_cookie(hmac_secret: &str, headers: &Headers) -> bool {
    let cookies = match headers.get::<Cookie>() {
        Some(c) => c,
        None => return false,
    };

    let mut auth_string = "".to_string();

    for c in cookies.as_slice() {
        if c.name == "auth_token" {
            auth_string = c.value.clone();
            break;
        }
    }

    let to_verify = match AuthToken::from_str(&auth_string) {
        Ok(v) => v,
        Err(_) => {
            return false;
        }
    };
    let good = AuthToken::new_with_time(hmac_secret, &to_verify.username,
                                        to_verify.time);

    AuthToken::verify_token(&good, &to_verify)
}
<commit_msg>Fix iterator on old versions of rust<commit_after>extern crate r2d2;
extern crate r2d2_postgres;
extern crate openssl;
#[macro_use] extern crate nickel;
extern crate nickel_postgres;
extern crate uuid;
extern crate serde_json;
extern crate cas;
extern crate crypto;
extern crate time;
extern crate hyper;
extern crate rustc_serialize;
extern crate cookie;
extern crate core;

use std::env;
use std::io::Read;
use r2d2::{NopErrorHandler, PooledConnection};
use r2d2_postgres::{SslMode, PostgresConnectionManager};
use nickel::{Nickel, HttpRouter, QueryString};
use nickel_postgres::{PostgresMiddleware, PostgresRequestExtensions};
use uuid::Uuid;
use nickel::status::StatusCode;
use nickel::extensions::response::Redirect;
use serde_json::Value;
use cas::{CasClient, ServiceResponse, VerifyError};
use crypto::hmac::Hmac;
use crypto::sha2::Sha512Trunc224;
use crypto::mac::{Mac, MacResult};
use hyper::header::Headers;
use hyper::header::{Cookie, SetCookie};
use time::{now, Tm, strptime, Duration};
use rustc_serialize::base64::{ToBase64, FromBase64, URL_SAFE, FromBase64Error };
use cookie::Cookie as CookiePair;
use std::string::ToString;
use std::str::FromStr;
use std::str::from_utf8;
use std::str::Utf8Error;
use std::fmt;
use core::fmt::Debug;

macro_rules! try_or_return {
    ( $op:expr, $error:expr ) => {
        match $op {
            Some(v) => v,
            None => return $error
        }
    }
}

macro_rules! try_or {
    ( $op:expr, $error:expr ) => {
        match $op {
            Ok(v) => v,
            Err(e) => {
                println!("error: {:?}", e);
                return $error;
            }
        }
    }
}

fn create_tables(conn: PooledConnection<PostgresConnectionManager>) {
    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS services (
                key UUID PRIMARY KEY,
                name VARCHAR NOT NULL
                )",
            &[]
        );

    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS users (
                key SERIAL PRIMARY KEY,
                caseid VARCHAR UNIQUE NOT NULL,
                slackid VARCHAR UNIQUE
                )",
            &[]
        );

    let _r = conn.execute(
            "CREATE TABLE IF NOT EXISTS permissions (
                key UUID REFERENCES services,
                username integer REFERENCES users,
                permissions JSONB,
                PRIMARY KEY (key, username)
                )",
            &[]
        );
}

fn main() {
    let mut app = Nickel::new();

    let hmac_secret = env::var("SECRET").expect("No SECRET found");

    let postgres_url = env::var("DATABASE_URL")
        .expect("Failed to get DATABASE_URL");

    let dbpool = PostgresMiddleware::new(&*postgres_url,
                                         SslMode::None,
                                         5,
                                         Box::new(NopErrorHandler)).unwrap();

    create_tables(dbpool.pool.clone().get().unwrap());
    app.utilize(dbpool);
    app.get("/register", middleware! { |request, response|
        let conn = request.db_conn();

        let name = try_or_return!(request.query().get("service_name"),
            response.error(
                StatusCode::BadRequest, "No service_name specified"));

        let key = Uuid::new_v4();

        let r = conn.execute(
            "INSERT INTO services (key, name) VALUES ($1, $2)",
            &[&key, &name]
            );
        println!("{:?}", r);

        key.to_hyphenated_string()
    });

    app.post("/adduser", middleware! { |request, response|
        let conn = request.db_conn();

        let mut body = vec![];
        try_or!(request.origin.read_to_end(&mut body),
                       response.error(StatusCode::InternalServerError,
                                      "Failed"));

        let permissions = try_or!(String::from_utf8(body),
            response.error(StatusCode::InternalServerError, "Failed"));

        let data: Value = try_or_return!(
            serde_json::from_str(&permissions).ok(),
            response.error(StatusCode::InternalServerError, "Failed"));

        let q = request.query();

        let caseid = try_or_return!(q.get("caseid"),
            response.error(StatusCode::BadRequest, "No username specified"));
        let key = try_or_return!(q.get("key").map(|s| Uuid::parse_str(s).ok()),
            response.error(StatusCode::BadRequest, "No key specified"));

        let user_rows = try_or!(conn.query(
                "INSERT INTO users (caseid) VALUES ($1)
                    ON CONFLICT (caseid) DO UPDATE SET caseid=users.caseid
                    RETURNING key",
                &[&caseid]
                ), response.error(StatusCode::InternalServerError,
                                  "Server Error")
            );
        if user_rows.len() != 1 {
            return response.error(StatusCode::InternalServerError,
                                  "Server Error");
        }

        let user = user_rows.get(0);
        let user_key: i32 = user.get(0);

        let r = try_or!(conn.execute(
            "INSERT INTO permissions (key, username, permissions)
                VALUES ($1, $2, $3)
                ON CONFLICT (key, username) DO UPDATE SET
                permissions=excluded.permissions",
                &[&key, &user_key, &data]
            ),
            response.error(StatusCode::InternalServerError, "Server error"));
        println!("{:?}", r);
        format!("You posted {}", permissions)
    });

    app.get("/getperms", middleware! { |request, response|
        let conn = request.db_conn();
        let q = request.query();
        let key = try_or_return!(q.get("key").map(|s| Uuid::parse_str(s).ok()),
            response.error(StatusCode::BadRequest, "No key specified"));

        let caseid = q.get("caseid").unwrap_or("");
        let slackid = q.get("slackid").unwrap_or("");

        let r = try_or!(conn.query(
                "SELECT permissions FROM permissions
                    INNER JOIN users
                    ON (permissions.username = users.key)
                    WHERE (caseid=$1 or slackid=$2) and permissions.key=$3",
                &[&caseid, &slackid, &key]
                ), response.error(StatusCode::InternalServerError,
                                  "Server Error")
            );
        println!("{:?}", r);

        if r.len() < 1 {
            return response.error(StatusCode::NotFound, "User not found");
        }
        let row = r.get(0);
        let s: Value = row.get(0);

        format!("{:?}", s)
    });

    let secret = hmac_secret.clone();
    app.get("/login", middleware! { |request, mut response|
        let base_url = env::var("BASE_URL")
            .unwrap_or("https://login.case.edu".to_string());
        let login_path = env::var("LOGIN_PATH")
            .unwrap_or("/cas/login".to_string());
        let logout_path = env::var("LOGOUT_PATH")
            .unwrap_or("/cas/logout".to_string());
        let verify_path = env::var("VERIFY_PATH")
            .unwrap_or("/cas/serviceValidate".to_string());
        let service_url = env::var("URL")
            .unwrap_or("http://hacsoc-auth.case.edu/login".to_string());

        let cas = try_or!(CasClient::new(&base_url, &login_path, &logout_path,
                                         &verify_path, &service_url),
                          response.error(StatusCode::InternalServerError,
                                         "Server Error"));
        match cas.verify_from_request(&request.origin) {
            Ok(ServiceResponse::Success(v)) => {
                set_auth_cookie(&secret, &v, response.headers_mut());
                return response.redirect("/setslackid");
            }
            Ok(ServiceResponse::Failure(e)) => format!("error: {:?}", e),
            Err(VerifyError::NoTicketFound) =>
                return response.redirect(cas.get_login_url()),
            Err(_) => return response.error(StatusCode::InternalServerError,
                                            "Server Error"),
        }
    });

    let secret = hmac_secret.clone();
    app.get("/setslackid", middleware! { |request, response|
        if verify_auth_cookie(&secret, &request.origin.headers) {
            "You logged in! A form will be here later"
        } else {
            return response.redirect("/login");
        }
    });

    let listen = match env::var("LISTEN") {
        Ok(s) => s,
        Err(_) => "127.0.0.1:8080".to_string()
    };

    app.listen(&listen[..]);
}

struct AuthToken {
    time: Tm,
    username: String,
    hmac: MacResult,
}

impl Debug for AuthToken {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        write!(f, "AuthToken {{ time: {:?}, username: {}, hmac: {:?} }}",
               self.time, self.username, self.hmac.code().to_base64(URL_SAFE))
    }
}

impl AuthToken {
    fn new(hmac_secret: &str, username: &str) -> AuthToken {
        AuthToken::new_with_time(hmac_secret, username, now().to_utc())
    }

    fn new_with_time(hmac_secret: &str, username: &str, t: Tm) -> AuthToken {
        let mut hmac = Hmac::new(Sha512Trunc224::new(), hmac_secret.as_bytes());
        let text = format!("{}.{}", username, t.rfc3339());
        hmac.input(text.as_bytes());

        AuthToken {
            time: t,
            username: username.to_string(),
            hmac: hmac.result(),
        }

    }

    fn verify_token(good: &AuthToken, unknown: &AuthToken) -> bool {
        let mut is_good = true;

        is_good = is_good && (good.hmac == unknown.hmac);

        let timeout = Duration::minutes(5);

        is_good = is_good && (unknown.time >= (now().to_utc() - timeout));

        is_good
    }

}

impl ToString for AuthToken {
    fn to_string(&self) -> String {
        let text = format!("{}.{}", self.username, self.time.to_timespec().sec)
            .as_bytes()
            .to_base64(URL_SAFE);

        format!("{}.{}", text, self.hmac.code().to_base64(URL_SAFE))
    }
}

#[derive(Debug)]
enum TokenError {
    Base64(FromBase64Error),
    FirstDotNotFound,
    Utf8(Utf8Error),
    SecondDotNotFound,
}

impl From<FromBase64Error> for TokenError {
    fn from(e: FromBase64Error) -> TokenError {
        TokenError::Base64(e)
    }
}

impl From<Utf8Error> for TokenError {
    fn from(e: Utf8Error) -> TokenError {
        TokenError::Utf8(e)
    }
}

impl FromStr for AuthToken {
    type Err = TokenError;

    fn from_str(s: &str) -> Result<Self, Self::Err> {
        let parts: Vec<&str> = s.split('.').collect();
        if parts.len() != 2 {
            return Err(TokenError::FirstDotNotFound);
        }

        let hmacpart = try!(parts.get(1).unwrap().from_base64());
        let hmac = MacResult::new_from_owned(hmacpart);

        let user = try!(parts.get(0).unwrap().from_base64());
        let userparts: Vec<&str> = try!(from_utf8(&user)).split('.').collect();
        if userparts.len() != 2 {
            return Err(TokenError::SecondDotNotFound);
        }

        let username = userparts.get(0).unwrap();
        let t = strptime(userparts.get(1).unwrap(), "%s").unwrap().to_utc();

        Ok(AuthToken {
            time: t,
            username: username.to_string(),
            hmac: hmac,
        })
    }
}

fn set_auth_cookie(hmac_secret: &str, username: &str, headers: &mut Headers) {
    let token = AuthToken::new(hmac_secret, username);
    let c_pair = CookiePair::new("auth_token".to_string(), token.to_string());

    match headers.get_mut::<SetCookie>() {
        Some(c) => {
            c.push(c_pair);
            return;
        },
        None => {}
    };
    headers.set::<SetCookie>(SetCookie(vec![c_pair]));
}

fn verify_auth_cookie(hmac_secret: &str, headers: &Headers) -> bool {
    let cookies = match headers.get::<Cookie>() {
        Some(c) => c,
        None => return false,
    };

    let mut auth_string = "".to_string();

    for c in cookies.iter() {
        if c.name == "auth_token" {
            auth_string = c.value.clone();
            break;
        }
    }

    let to_verify = match AuthToken::from_str(&auth_string) {
        Ok(v) => v,
        Err(_) => {
            return false;
        }
    };
    let good = AuthToken::new_with_time(hmac_secret, &to_verify.username,
                                        to_verify.time);

    AuthToken::verify_token(&good, &to_verify)
}
<|endoftext|>


<commit_before>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

#[macro_use]
extern crate clap;
extern crate requests;
extern crate serde;
extern crate serde_json;

use clap::{App, SubCommand, AppSettings, ArgMatches};
mod crates;

const CARGO: &'static str = "cargo";

#[derive(Debug, PartialEq)]
enum Flag {
    Repository,
    Documentation,
    Downloads,
    Homepage,
    Json,
    Default,
}

#[derive(Debug)]
struct Report {
    flags: Vec<Flag>,
    verbose: bool,
}

impl Report {
    pub fn new(info: &ArgMatches) -> Self {

        let mut flags: Vec<Flag> = vec![];
        if info.is_present("repository") {
            flags.push(Flag::Repository);
        }
        if info.is_present("documentation") {
            flags.push(Flag::Documentation);
        }
        if info.is_present("downloads") {
            flags.push(Flag::Downloads);
        }
        if info.is_present("homepage") {
            flags.push(Flag::Homepage);
        }

        if info.is_present("json") {
            flags.push(Flag::Json);
        }

        if flags.is_empty() {
            flags.push(Flag::Default);
        }

        Report {
            flags: flags,
            verbose: info.is_present("verbose"),
        }
    }

    pub fn report(&self, name: &str) {
        if let Some(krate) = query(name).map(|r| r.krate) {
            for flag in &self.flags {
                match *flag {
                    Flag::Repository => krate.print_repository(self.verbose),
                    Flag::Documentation => krate.print_documentation(self.verbose),
                    Flag::Downloads => krate.print_downloads(self.verbose),
                    Flag::Homepage => krate.print_homepage(self.verbose),
                    Flag::Json => {},
                    Flag::Default => reportv(&krate, self.verbose),
                }
            }
        }
    }
}

fn reportv(krate: &crates::Crate, verbose: bool) {
    if verbose {
        println!("{:#}", krate);
    } else {
        println!("{}", krate);
    }
}

fn query(krate: &str) -> Option<crates::Reply> {
    let response = requests::get(&format!("http://crates.io/api/v1/crates/{}", krate)).unwrap();
    // println!("{:?}", response.json().unwrap());
    response.from_json::<crates::Reply>()
}

// use std::fmt;
// fn debug<T>(item: &T)
//     where T: fmt::Debug
// {
//     println!("{:#?}", item);
// }

fn main() {

    let matches = App::new(CARGO)
        .bin_name(CARGO)
        .author(crate_authors!())
        .version(crate_version!())
        .about("Query crates.io registry for crates details")
        .setting(AppSettings::GlobalVersion)
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(SubCommand::with_name("info")
            .setting(AppSettings::ArgRequiredElseHelp)
            .setting(AppSettings::TrailingVarArg)
            .arg_from_usage("-d, --documentation 'Report documentation URL'")
            .arg_from_usage("-D, --downloads 'Report number of crate downloads'")
            .arg_from_usage("-H, --homepage 'Report home page URL'")
            .arg_from_usage("-r, --repository 'Report crate repository URL'")
            .arg_from_usage("-v, --verbose 'Report more details'")
            .arg_from_usage("<crate>... 'crate to query'"))
        .get_matches();

    if let Some(info) = matches.subcommand_matches("info") {
        if let Some(crates) = info.values_of("crate") {
            let rep = Report::new(info);
            for krate in crates {
                // debug(&krate);
                rep.report(krate);
            }
        }
    }
}
<commit_msg>Implement -j for raw JSON resporting<commit_after>#![cfg_attr(feature="clippy", feature(plugin))]
#![cfg_attr(feature="clippy", plugin(clippy))]
#![feature(custom_derive, plugin)]
#![plugin(serde_macros)]

#[macro_use]
extern crate clap;
extern crate requests;
extern crate serde;
extern crate serde_json;

mod crates;

use clap::{App, SubCommand, Arg, AppSettings, ArgMatches};
use serde_json::ser::to_string_pretty;

const CARGO: &'static str = "cargo";

#[derive(Debug, PartialEq)]
enum Flag {
    Repository,
    Documentation,
    Downloads,
    Homepage,
    Default,
}

#[derive(Debug)]
struct Report {
    flags: Vec<Flag>,
    verbose: bool,
    json: bool,
}

impl Report {
    pub fn new(info: &ArgMatches) -> Self {

        let mut flags: Vec<Flag> = vec![];
        if info.is_present("repository") {
            flags.push(Flag::Repository);
        }
        if info.is_present("documentation") {
            flags.push(Flag::Documentation);
        }
        if info.is_present("downloads") {
            flags.push(Flag::Downloads);
        }
        if info.is_present("homepage") {
            flags.push(Flag::Homepage);
        }

        if flags.is_empty() {
            flags.push(Flag::Default);
        }

        Report {
            flags: flags,
            verbose: info.is_present("verbose"),
            json: info.is_present("json"),
        }
    }

    pub fn report(&self, name: &str) {
        let response = query(name);
        if self.json {
            self.report_json(&response);
        } else {
            if let Some(krate) = get_crate(&response) {
                self.report_crate(&krate);
            }
        }
    }

    pub fn report_json(&self, response: &requests::Response) {
        if self.verbose {
            if let Some(json) = response.text() {
                println!("{}", json);
            }
        } else {
            if let Some(Ok(json)) = response.from_json::<crates::Reply>()
                                            .as_ref()
                                            .map(to_string_pretty::<crates::Reply>) {
                println!("{}", json);
            }
        }
    }

    pub fn report_crate(&self, krate: &crates::Crate) {
        for flag in &self.flags {
            match *flag {
                Flag::Repository => krate.print_repository(self.verbose),
                Flag::Documentation => krate.print_documentation(self.verbose),
                Flag::Downloads => krate.print_downloads(self.verbose),
                Flag::Homepage => krate.print_homepage(self.verbose),
                Flag::Default => reportv(&krate, self.verbose),
            }
        }
    }
}

fn reportv(krate: &crates::Crate, verbose: bool) {
    if verbose {
        println!("{:#}", krate);
    } else {
        println!("{}", krate);
    }
}

fn query(krate: &str) -> requests::Response {
    requests::get(&format!("http://crates.io/api/v1/crates/{}", krate)).unwrap()
    // println!("{:?}", response.json().unwrap());
    // response.from_json::<crates::Reply>()
}

fn get_crate(response: &requests::Response) -> Option<crates::Crate> {
    response.from_json::<crates::Reply>().map(|r| r.krate)
}

// use std::fmt;
// fn debug<T>(item: &T)
//     where T: fmt::Debug
// {
//     println!("{:#?}", item);
// }

fn main() {

    let matches = App::new(CARGO)
        .bin_name(CARGO)
        .author(crate_authors!())
        .version(crate_version!())
        .about("Query crates.io registry for crates details")
        .setting(AppSettings::GlobalVersion)
        .setting(AppSettings::VersionlessSubcommands)
        .setting(AppSettings::SubcommandRequiredElseHelp)
        .subcommand(SubCommand::with_name("info")
            .setting(AppSettings::ArgRequiredElseHelp)
            .setting(AppSettings::TrailingVarArg)
            .arg(Arg::with_name("documentation")
                .short("d")
                .long("documentation")
                .help("Report documentation URL"))
            // .arg_from_usage("-d, --documentation 'Report documentation URL'")
            .arg_from_usage("-D, --downloads 'Report number of crate downloads'")
            .arg_from_usage("-H, --homepage 'Report home page URL'")
            .arg_from_usage("-r, --repository 'Report crate repository URL'")
            .arg(Arg::with_name("json")
                .short("j")
                .long("json")
                .help("Report raw JSON data from crates.io")
                .conflicts_with_all(&["documentation", "downloads", "homepage", "repository"]))
            // .arg_from_usage("-j, --json 'Report raw json data from crates.io'")
            .arg_from_usage("-v, --verbose 'Report more details'")
            .arg_from_usage("<crate>... 'crate to query'"))
        .get_matches();

    if let Some(info) = matches.subcommand_matches("info") {
        if let Some(crates) = info.values_of("crate") {
            let rep = Report::new(info);
            for krate in crates {
                // debug(&krate);
                rep.report(krate);
            }
        }
    }
}
<|endoftext|>


<commit_before>#[macro_use] extern crate clap;
#[macro_use] extern crate log;
extern crate env_logger;

extern crate hyper;
extern crate rustc_serialize;
extern crate scoped_threadpool;
extern crate csv;

mod format;
mod geometry;
mod tfl;
mod gtfs;
mod cmd;

use clap::{Arg, App, SubCommand};
use format::{OutputFormat};

fn main() {
    env_logger::init().unwrap();

    let matches = App::new("tfl")
                      .version(env!("CARGO_PKG_VERSION"))
                      .about("Tfl consumer")
                      .subcommand(SubCommand::with_name("fetch-lines")
                                             .about("Fetch lines from Tfl")
                                             .arg(Arg::with_name("format")
                                                      .help("Output format")
                                                      .long("format")
                                                      .value_name("format")
                                                      .possible_values(&["gtfs"]))
                                             .arg(Arg::with_name("threads")
                                                      .help("Number of threads. Defaults to 5")
                                                      .long("threads")
                                                      .value_name("number")))
                      .subcommand(SubCommand::with_name("transform")
                                             .about("Transform cached data to the given format")
                                             .arg(Arg::with_name("format")
                                                      .help("Output format")
                                                      .index(1)
                                                      .possible_values(&["gtfs"])
                                                      .required(true))
                                             .arg(Arg::with_name("threads")
                                                      .help("Number of threads. Defaults to 5")
                                                      .long("threads")
                                                      .value_name("number")))
                      .get_matches();

    if let Some(ref matches) = matches.subcommand_matches("fetch-lines") {
        let format = value_t!(matches, "format", OutputFormat).unwrap_or(OutputFormat::None);
        let thread_number = value_t!(matches, "threads", u32).unwrap_or(5);
        cmd::fetch_lines(format, thread_number);
    }

    if let Some(ref matches) = matches.subcommand_matches("transform") {
        let format = value_t!(matches, "format", OutputFormat).unwrap_or_else(|e| e.exit());
        let thread_number = value_t!(matches, "threads", u32).unwrap_or(5);
        cmd::transform(format, thread_number);
    }
}
<commit_msg>Dry format argument<commit_after>#[macro_use] extern crate clap;
#[macro_use] extern crate log;
extern crate env_logger;

extern crate hyper;
extern crate rustc_serialize;
extern crate scoped_threadpool;
extern crate csv;

mod format;
mod geometry;
mod tfl;
mod gtfs;
mod cmd;

use clap::{Arg, App, SubCommand};
use format::{OutputFormat};

fn arg_format<'a, 'b>() -> Arg<'a, 'b> {
    Arg::with_name("format")
        .help("Output format")
        .possible_values(&["gtfs"])
        .long("format")
        .value_name("format")
}

fn main() {
    env_logger::init().unwrap();

    let matches = App::new("tfl")
                      .version(env!("CARGO_PKG_VERSION"))
                      .about("Tfl consumer")
                      .subcommand(SubCommand::with_name("fetch-lines")
                                             .about("Fetch lines from Tfl")
                                             .arg(arg_format())
                                             .arg(Arg::with_name("threads")
                                                      .help("Number of threads. Defaults to 5")
                                                      .long("threads")
                                                      .value_name("number")))
                      .subcommand(SubCommand::with_name("transform")
                                             .about("Transform cached data to the given format")
                                             .arg(arg_format()
                                                      .index(1)
                                                      .required(true))
                                             .arg(Arg::with_name("threads")
                                                      .help("Number of threads. Defaults to 5")
                                                      .long("threads")
                                                      .value_name("number")))
                      .get_matches();

    if let Some(ref matches) = matches.subcommand_matches("fetch-lines") {
        let format = value_t!(matches, "format", OutputFormat).unwrap_or(OutputFormat::None);
        let thread_number = value_t!(matches, "threads", u32).unwrap_or(5);
        cmd::fetch_lines(format, thread_number);
    }

    if let Some(ref matches) = matches.subcommand_matches("transform") {
        let format = value_t!(matches, "format", OutputFormat).unwrap_or_else(|e| e.exit());
        let thread_number = value_t!(matches, "threads", u32).unwrap_or(5);
        cmd::transform(format, thread_number);
    }
}
<|endoftext|>


<commit_before>extern crate image;

use std::fs::File;
use std::path::Path;
use std::env;
use image::GenericImage;

//should be a trait.  I am not sure how to impliment one for only Vec <Vec <bool>> and not Vec <T>
fn boundless_insert(y: i64, x: i64, value: bool, img: &mut Vec<Vec <bool>>) {
	let mut tx = x;
	let mut ty = y;
	for i in 0..img.len(){
		let mut ttx = x;
		while ttx < 0 {
			img[i].insert(0, false);
			ttx += 1;
		}
		assert!(((x < 0) && (ttx == 0)) || (x == ttx), "Expected ttx = zero or ttx = x.  Found {}", ttx);
		while img[i].len() <= ttx as usize {
			img[i].push(false);
		}
		tx = ttx
	}
	let mut row:Vec <bool> = Vec::new();
	for i in 0..img[0].len() {
		row.push(false);
	}
	while ty < 0 {
		img.insert(0, row.clone());
		ty += 1;
	}
	assert!(((y < 0) && (ty == 0)) || (y == ty), "Expected ty = zero or ty = y.  Found {}", ty);
	while img.len() <= ty as usize {
		img.push(row.clone())
	}
	img[ty as usize][tx as usize] = value;
}

struct ImgBlob {
	blob_type: u8, //0: object, 1: line
	top_right: [usize; 2],
	middle: [usize; 2],
	bitmap: Vec <Vec <bool>>
}

impl ImgBlob {
	fn from_top_right(x: usize, y: usize, claim: &mut Vec <Vec <bool>>, img: &Vec <Vec <bool>>) -> Option<ImgBlob>{
		let mut right = x;
		let mut top = y; //pretty sure that this is not supposed to change and can be eliminated
		let mut bitmap: Vec <Vec <bool>> = Vec::new();
		let mut queue: Vec <[usize; 2]> = Vec::new();
		claim[y][x] = true;
		queue.push([y+1, x]);
		queue.push([y, x+1]);
		bitmap.push(vec![true]);
		while queue.len() > 0 {
			let tempx = queue[0][1];
			let tempy = queue[0][0];
			if (tempy < img.len()) && (tempx < img[0].len()) && (tempy > 0) && (tempx > 0) {
				if img[tempy][tempx] && !(claim[tempy][tempx]){
					boundless_insert(((tempy as i64)-(top as i64)), ((tempx as i64)-(right as i64)), true, &mut bitmap);
					if tempx < right {
						right = tempx;
					}
					if tempy < top {
						top = tempy;
					}
					claim[tempy][tempx] = true;
					if queue[0][1] > top {
						queue.push([tempy-1, tempx]);
					}
					queue.push([tempy, tempx-1]);
					queue.push([tempy+1, tempx]);
					queue.push([tempy, tempx+1]);
				}
			}
			queue.remove(0);
		}
		if (bitmap[0].len() + bitmap.len() > 6) && (bitmap.len() > 3) && (bitmap[0].len() > 3) {
			println!("Found: {} x {}", bitmap[0].len(), bitmap.len());
			Some(ImgBlob {
				blob_type: if (bitmap[0].len() / bitmap.len()) > 10 {1} else {0},
				top_right: [right, top],
				middle: [right+(bitmap[0].len()/2), top+(bitmap.len()/2)],
				bitmap: bitmap
			})
		} else {
			None
		}
	}
}

struct Chapter {
	heading: ImgBlob,
	blobs: Vec <ImgBlob>,
	subchapters: Vec <Chapter>
}

fn main() {
	let mut claimed: Vec <Vec <bool>> = Vec::new();
	let mut thresh: Vec <Vec <bool>> = Vec::new();
	let mut rblobs: Vec <ImgBlob> = Vec::new();
	let mut gblobs: Vec <ImgBlob> = Vec::new();
	let mut bblobs: Vec <ImgBlob> = Vec::new();
	let img = image::open(&Path::new("target.jpg")).unwrap();
	let mut row:Vec <bool> = Vec::new();
	for x in 0..img.width() {
		row.push(false);
	}
	for y in 0..img.height() {
		claimed.push(row.clone());
		thresh.push(row.clone());
	}
	let rgbimg = img.to_rgb();
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[0] > 140) && (pixel[1] <= 170) && (pixel[2] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => rblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished R");
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[1] > 140) && (pixel[0] <= 170) && (pixel[2] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => gblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished G");
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[2] > 140) && (pixel[1] <= 170) && (pixel[0] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => bblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished B");
}
<commit_msg>initial work on file selector<commit_after>extern crate image;

use std::fs;
use std::env;
use std::path::Path;
use std::path::PathBuf;
use std::io;
use std::io::BufReader;
use std::io::BufRead;
use std::fs::File;
use image::GenericImage;

const IMPORTED: &'static str = "./.imported";
const OUT_PATH: &'static str = "~/Documemts/Notebook";

//should be a trait.  I am not sure how to impliment one for only Vec <Vec <bool>> and not Vec <T>
fn boundless_insert(y: i64, x: i64, value: bool, img: &mut Vec<Vec <bool>>) {
	let mut tx = x;
	let mut ty = y;
	for i in 0..img.len(){
		let mut ttx = x;
		while ttx < 0 {
			img[i].insert(0, false);
			ttx += 1;
		}
		assert!(((x < 0) && (ttx == 0)) || (x == ttx), "Expected ttx = zero or ttx = x.  Found {}", ttx);
		while img[i].len() <= ttx as usize {
			img[i].push(false);
		}
		tx = ttx
	}
	let mut row:Vec <bool> = Vec::new();
	for i in 0..img[0].len() {
		row.push(false);
	}
	while ty < 0 {
		img.insert(0, row.clone());
		ty += 1;
	}
	assert!(((y < 0) && (ty == 0)) || (y == ty), "Expected ty = zero or ty = y.  Found {}", ty);
	while img.len() <= ty as usize {
		img.push(row.clone())
	}
	img[ty as usize][tx as usize] = value;
}

struct ImgBlob {
	blob_type: u8, //0: object, 1: line
	top_right: [usize; 2],
	middle: [usize; 2],
	bitmap: Vec <Vec <bool>>
}

impl ImgBlob {
	fn from_top_right(x: usize, y: usize, claim: &mut Vec <Vec <bool>>, img: &Vec <Vec <bool>>) -> Option<ImgBlob>{
		let mut right = x;
		let mut top = y; //pretty sure that this is not supposed to change and can be eliminated
		let mut bitmap: Vec <Vec <bool>> = Vec::new();
		let mut queue: Vec <[usize; 2]> = Vec::new();
		claim[y][x] = true;
		queue.push([y+1, x]);
		queue.push([y, x+1]);
		bitmap.push(vec![true]);
		while queue.len() > 0 {
			let tempx = queue[0][1];
			let tempy = queue[0][0];
			if (tempy < img.len()) && (tempx < img[0].len()) && (tempy > 0) && (tempx > 0) {
				if img[tempy][tempx] && !(claim[tempy][tempx]){
					boundless_insert(((tempy as i64)-(top as i64)), ((tempx as i64)-(right as i64)), true, &mut bitmap);
					if tempx < right {
						right = tempx;
					}
					if tempy < top {
						top = tempy;
					}
					claim[tempy][tempx] = true;
					if queue[0][1] > top {
						queue.push([tempy-1, tempx]);
					}
					queue.push([tempy, tempx-1]);
					queue.push([tempy+1, tempx]);
					queue.push([tempy, tempx+1]);
				}
			}
			queue.remove(0);
		}
		if (bitmap[0].len() + bitmap.len() > 6) && (bitmap.len() > 3) && (bitmap[0].len() > 3) {
			println!("Found: {} x {}", bitmap[0].len(), bitmap.len());
			Some(ImgBlob {
				blob_type: if (bitmap[0].len() / bitmap.len()) > 10 {1} else {0},
				top_right: [right, top],
				middle: [right+(bitmap[0].len()/2), top+(bitmap.len()/2)],
				bitmap: bitmap
			})
		} else {
			None
		}
	}
}

struct Page {
	blobs: Vec <ImgBlob>,
	dimensions: [u32; 2]
}

struct Chapter {
	heading: ImgBlob,
	blobs: Vec <ImgBlob>,
	subchapters: Vec <Chapter>
}

fn get_images() -> Vec <String> {
	fn get_imported_images() -> Vec <String> {
		println!("test");
		if Path::new(IMPORTED).exists() {
			println!("test");
			let mut list: Vec <String> = Vec::new();
			let f = (File::open(IMPORTED)).unwrap();
			let mut file = BufReader::new(&f);
			for line in file.lines() {
				println!("test");
				let templ = line.unwrap();
				println!("{}", &templ);
				list.push(templ);
			}
			list
		} else {
			Vec::new()
		}
	}
	fn parse_input(uin: String, mpaths: Vec <String>, new: &mut Vec <String>) -> Vec <String> {
		let mut selected: Vec <String> = Vec::new();
		let stringified: Vec <String> = uin.split(' ').map(|x| x.to_string()).collect();
		for sel in stringified {
			if sel == "+" {
				selected.append(new);
			} else if sel.to_string().contains("-") {

			}
		}
		selected
	}
	let paths = fs::read_dir("./").unwrap();
	let mut mpaths: Vec <String> = Vec::new();
	let mut new: Vec <String> = Vec::new();
	let mut imported: Vec <String> = get_imported_images();
	for p in paths {
		let path = p.unwrap().path();
		if !(path.extension() == None) {
			//The next line needs to be cleaned up.  It is written like this to appease the borrow checker
			if path.extension().unwrap() == "png" || path.extension().unwrap() == "jpg" || path.extension().unwrap() == "bpm" || path.extension().unwrap() == "gif" {
				mpaths.push(path.into_os_string().into_string().unwrap());//ugly hack but as_path().to_string() does not work
			}
		}
	}
	mpaths.sort();
	let mut fiter:usize = 0;
	for p in &mpaths {
		if !imported.contains(p) {
			print!("+");
			new.push(p.clone());//cannot pass borrowed var w/o cloning
		}
		println!("	{}:	{}", fiter, p);
		fiter += 1;
	}
	println!("Enter an number to select an image to import.  ");
	println!("Enter 5-6 to import images 5 through 6.  ");
	println!("Enter + to import the images you have not imported.  (These images are indicated in the list by + signs)");
	println!("Use spaces to seperate multiple selections.  ");
	print!("select: ");
	let mut uin = String::new();
	io::stdin().read_line(&mut uin).ok().expect("Error reading line");
	parse_input(uin, mpaths, &mut new)
}

fn main() {
	//iterate through images pulling out blobs
	//iterate through pages parsing blobs and creating chapters
	let selected = get_images();
	//need to run some kind of sort
	/*let mut claimed: Vec <Vec <bool>> = Vec::new();
	let mut thresh: Vec <Vec <bool>> = Vec::new();
	let mut rblobs: Vec <ImgBlob> = Vec::new();
	let mut gblobs: Vec <ImgBlob> = Vec::new();
	let mut bblobs: Vec <ImgBlob> = Vec::new();
	let img = image::open(&Path::new("target.jpg")).unwrap();
	let mut row:Vec <bool> = Vec::new();
	for x in 0..img.width() {
		row.push(false);
	}
	for y in 0..img.height() {
		claimed.push(row.clone());
		thresh.push(row.clone());
	}
	let rgbimg = img.to_rgb();
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[0] > 140) && (pixel[1] <= 170) && (pixel[2] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => rblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished R");
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[1] > 140) && (pixel[0] <= 170) && (pixel[2] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => gblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished G");
	for (x, y, pixel) in rgbimg.enumerate_pixels() {
		thresh[y as usize][x as usize] = if (pixel[2] > 140) && (pixel[1] <= 170) && (pixel[0] <= 170) {true} else {false};
	}
	for y in 0..thresh.len() {
		for x in 0..thresh[0].len() {
			if thresh[y][x] {
				match ImgBlob::from_top_right(x, y, &mut claimed, &thresh){
					Some(o) => bblobs.push(o),
					None => {},
				}
			}
		}
	}
	println!("Finished B");*/
}
<|endoftext|>


<commit_before>use std::io;
use std::io::prelude::*;

extern crate clap;
extern crate rand;
use clap::{Arg, App};

mod cat;

fn main() {
    let mut c = parse_cli_args();
    let stdin = io::stdin(); // For lifetime reasons

    for line in stdin.lock().lines() {
        cat::print_with_lolcat(line.unwrap(), &mut c);
    }
}

fn parse_cli_args() -> cat::Control {
    let matches = App::new("lolcat")
        .version("0.1.0")
        .author("Umang Raghuvanshi <u@umangis.me>")
        .about("The good ol' lolcat, now with fearless concurrency.")
        .arg(Arg::with_name("seed")
            .short("s")
            .long("seed")
            .help("A seed for your lolcat. Setting this to 0 randomizes the seed.")
            .takes_value(true))
        .arg(Arg::with_name("spread")
            .short("S")
            .long("spread")
            .help("How much should we spread dem colors? Defaults to 3.0")
            .takes_value(true))
        .arg(Arg::with_name("frequency")
            .short("f")
            .long("frequency")
            .help("Frequency - used in our math. Defaults to 0.1")
            .takes_value(true))
        .get_matches();
    let seed = matches.value_of("seed").unwrap_or("0.0");
    let spread = matches.value_of("spread").unwrap_or("3.0");
    let frequency = matches.value_of("frequency").unwrap_or("0.1");

    let mut seed: f64 = seed.parse().unwrap();
    let spread: f64 = spread.parse().unwrap();
    let frequency: f64 = frequency.parse().unwrap();

    if seed == 0.0 {
        seed = rand::random::<f64>();
    }

    cat::Control {
        seed: seed,
        spread: spread,
        frequency: frequency,
    }
}
<commit_msg>Better seeds for more colors :zap:<commit_after>use std::io;
use std::io::prelude::*;

extern crate clap;
extern crate rand;
use clap::{Arg, App};

mod cat;

fn main() {
    let mut c = parse_cli_args();
    let stdin = io::stdin(); // For lifetime reasons

    for line in stdin.lock().lines() {
        cat::print_with_lolcat(line.unwrap(), &mut c);
    }
}

fn parse_cli_args() -> cat::Control {
    let matches = App::new("lolcat")
        .version("0.1.0")
        .author("Umang Raghuvanshi <u@umangis.me>")
        .about("The good ol' lolcat, now with fearless concurrency.")
        .arg(Arg::with_name("seed")
            .short("s")
            .long("seed")
            .help("A seed for your lolcat. Setting this to 0 randomizes the seed.")
            .takes_value(true))
        .arg(Arg::with_name("spread")
            .short("S")
            .long("spread")
            .help("How much should we spread dem colors? Defaults to 3.0")
            .takes_value(true))
        .arg(Arg::with_name("frequency")
            .short("f")
            .long("frequency")
            .help("Frequency - used in our math. Defaults to 0.1")
            .takes_value(true))
        .get_matches();
    let seed = matches.value_of("seed").unwrap_or("0.0");
    let spread = matches.value_of("spread").unwrap_or("3.0");
    let frequency = matches.value_of("frequency").unwrap_or("0.1");

    let mut seed: f64 = seed.parse().unwrap();
    let spread: f64 = spread.parse().unwrap();
    let frequency: f64 = frequency.parse().unwrap();

    if seed == 0.0 {
        seed = rand::random::<f64>() * 10e9;
    }

    cat::Control {
        seed: seed,
        spread: spread,
        frequency: frequency,
    }
}
<|endoftext|>


<commit_before>extern crate "rustc-serialize" as serialize;
extern crate handlebars;

use handlebars::Handlebars;
use serialize::json::Json;
use std::old_io as io;
use std::os;

fn main() {
   let template = match os::args().as_slice() {
      [_, ref bars] =>
        io::File::open(&Path::new(&bars))
          .and_then(|mut f| f.read_to_string())
          .ok()
          .expect("invalid path"),
       _ =>
         "{{.}}".to_string()
   };
   let input = if io::stdio::stdin_raw().isatty() {
     "{}".to_string()
   } else {
     io::stdin()
       .read_line()
       .ok()
       .expect("json expected")
   };
   let json = Json::from_str(&input)
     .ok()
     .expect("malformed json");
   let mut handlebars = Handlebars::new();
   handlebars.register_template_string("t", template)
     .ok()
     .expect("expected template");
   println!("{}", handlebars.render("t", &json)
                  .ok().unwrap());
}
<commit_msg>monadic style<commit_after>extern crate "rustc-serialize" as serialize;
extern crate handlebars;

use handlebars::Handlebars;
use serialize::json::Json;
use std::old_io as io;
use std::os;

fn main() {
   let template = match os::args().as_slice() {
      [_, ref bars] =>
        io::File::open(&Path::new(&bars))
          .and_then(|mut f| f.read_to_string())
          .ok(),
       _ =>
         Some("{{.}}".to_string())
   };

   let json = if io::stdio::stdin_raw().isatty() {
     Some("{}".to_string())
   } else {
     io::stdin()
       .read_line()
       .ok()
   }.and_then(|input| Json::from_str(&input).ok());

   let mut handlebars = Handlebars::new();
   let rendered = template
      .and_then(|bars| handlebars.register_template_string("t", bars).ok())
      .and_then(|_| json)
      .and_then(|json| handlebars.render("t", &json).ok());

    match rendered {
      Some(r) => println!("{}", r),
      _ => println!("failed to render")
    }
}
<|endoftext|>