<commit_before>use std::rc::Rc;
use std::collections::BTreeSet;
use std::fmt::{Display, Formatter, Result};
use std::result::Result as StdResult;
use std::io;

use Arg;
use args::settings::{ArgFlags, ArgSettings};

#[allow(missing_debug_implementations)]
pub struct OptBuilder<'n> {
    pub name: &'n str,
    /// The short version (i.e. single character) of the argument, no preceding `-`
    pub short: Option<char>,
    /// The long version of the flag (i.e. word) without the preceding `--`
    pub long: Option<&'n str>,
    /// The string of text that will displayed to the user when the application's
    /// `help` text is displayed
    pub help: Option<&'n str>,
    /// A list of names for other arguments that *may not* be used with this flag
    pub blacklist: Option<Vec<&'n str>>,
    /// A list of possible values for this argument
    pub possible_vals: Option<Vec<&'n str>>,
    /// A list of names of other arguments that are *required* to be used when
    /// this flag is used
    pub requires: Option<Vec<&'n str>>,
    pub num_vals: Option<u8>,
    pub min_vals: Option<u8>,
    pub max_vals: Option<u8>,
    pub val_names: Option<BTreeSet<&'n str>>,
    pub validator: Option<Rc<Fn(String) -> StdResult<(), String>>>,
    /// A list of names for other arguments that *mutually override* this flag
    pub overrides: Option<Vec<&'n str>>,
    pub settings: ArgFlags,
}

impl<'n> OptBuilder<'n> {
    pub fn new(name: &'n str) -> Self {
        OptBuilder {
            name: name,
            short: None,
            long: None,
            help: None,
            blacklist: None,
            possible_vals: None,
            requires: None,
            num_vals: None,
            min_vals: None,
            max_vals: None,
            val_names: None,
            validator: None,
            overrides: None,
            settings: ArgFlags::new(),
        }
    }

    pub fn from_arg(a: &Arg<'n, 'n, 'n, 'n, 'n, 'n>, reqs: &mut Vec<&'n str>) -> Self {
        if a.short.is_none() && a.long.is_none() {
            panic!("Argument \"{}\" has takes_value(true), yet neither a short() or long() \
                was supplied",
                   a.name);
        }
        // No need to check for .index() as that is handled above
        let mut ob = OptBuilder {
            name: a.name,
            short: a.short,
            long: a.long,
            blacklist: None,
            help: a.help,
            possible_vals: None,
            num_vals: a.num_vals,
            min_vals: a.min_vals,
            max_vals: a.max_vals,
            val_names: a.val_names.clone(),
            requires: None,
            validator: None,
            overrides: None,
            settings: ArgFlags::new(),
        };
        if a.multiple {
            ob.settings.set(&ArgSettings::Multiple);
        }
        if a.required {
            ob.settings.set(&ArgSettings::Required);
        }
        if a.global {
            ob.settings.set(&ArgSettings::Global);
        }
        if !a.empty_vals {
            ob.settings.unset(&ArgSettings::Global);
        }
        if a.hidden {
            ob.settings.set(&ArgSettings::Hidden);
        }
        if let Some(ref vec) = ob.val_names {
            ob.num_vals = Some(vec.len() as u8);
        }
        // Check if there is anything in the blacklist (mutually excludes list) and add
        // any
        // values
        if let Some(ref bl) = a.blacklist {
            let mut bhs = vec![];
            // without derefing n = &&str
            for n in bl {
                bhs.push(*n);
            }
            ob.blacklist = Some(bhs);
        }
        if let Some(ref p) = a.validator {
            ob.validator = Some(p.clone());
        }
        // Check if there is anything in the requires list and add any values
        if let Some(ref r) = a.requires {
            let mut rhs = vec![];
            // without derefing n = &&str
            for n in r {
                rhs.push(*n);
                if a.required {
                    reqs.push(*n);
                }
            }
            ob.requires = Some(rhs);
        }
        if let Some(ref or) = a.overrides {
            let mut bhs = vec![];
            // without derefing n = &&str
            for n in or {
                bhs.push(*n);
            }
            ob.overrides = Some(bhs);
        }
        // Check if there is anything in the possible values and add those as well
        if let Some(ref p) = a.possible_vals {
            let mut phs = vec![];
            // without derefing n = &&str
            for n in p {
                phs.push(*n);
            }
            ob.possible_vals = Some(phs);
        }

        ob
    }

    pub fn write_help<W: io::Write>(&self, w: &mut W, tab: &str, longest: usize) -> io::Result<()> {
        // if it supports multiple we add '...' i.e. 3 to the name length
        try!(write!(w, "{}", tab));
        if let Some(s) = self.short {
            try!(write!(w, "-{}", s));
        } else {
            try!(write!(w, "{}", tab));
        }
        if let Some(l) = self.long {
            try!(write!(w,
                        "{}--{}",
                        if self.short.is_some() {
                            ", "
                        } else {
                            ""
                        },
                        l));
        }
        if let Some(ref vec) = self.val_names {
            for val in vec {
                try!(write!(w, " <{}>", val));
            }
        } else if let Some(num) = self.num_vals {
            for _ in 0..num {
                try!(write!(w, " <{}>", self.name));
            }
        } else {
            try!(write!(w,
                        " <{}>{}",
                        self.name,
                        if self.settings.is_set(&ArgSettings::Multiple) {
                            "..."
                        } else {
                            ""
                        }));
        }
        if self.long.is_some() {
            write_spaces!((longest + 4) - (self.to_string().len()), w);
        } else {
            // 8 = tab + '-a, '.len()
            write_spaces!((longest + 8) - (self.to_string().len()), w);
        }
        print_opt_help!(self, longest + 12, w);
        write!(w, "\n")
    }
}

impl<'n> Display for OptBuilder<'n> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        // Write the name such --long or -l
        if let Some(l) = self.long {
            try!(write!(f, "--{}", l));
        } else {
            try!(write!(f, "-{}", self.short.unwrap()));
        }

        // Write the values such as <name1> <name2>
        if let Some(ref vec) = self.val_names {
            for n in vec.iter() {
                try!(write!(f, " <{}>", n));
            }
        } else {
            let num = self.num_vals.unwrap_or(1);
            for _ in 0..num {
                try!(write!(f, " <{}>", self.name));
            }
            if self.settings.is_set(&ArgSettings::Multiple) && num == 1 {
                try!(write!(f, "..."));
            }
        }

        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::OptBuilder;
    use std::collections::BTreeSet;
    use args::settings::ArgSettings;

    #[test]
    fn optbuilder_display() {
        let mut o = OptBuilder::new("opt");
        o.long = Some("option");
        o.settings.set(&ArgSettings::Multiple);

        assert_eq!(&*format!("{}", o), "--option <opt>...");

        let mut v_names = BTreeSet::new();
        v_names.insert("file");
        v_names.insert("name");

        let mut o2 = OptBuilder::new("opt");
        o2.short = Some('o');
        o2.val_names = Some(v_names);

        assert_eq!(&*format!("{}", o2), "-o <file> <name>");
    }
}
<commit_msg>refactor: moves value validation out of App and into Option Args<commit_after>use std::rc::Rc;
use std::collections::BTreeSet;
use std::fmt::{Display, Formatter, Result};
use std::result::Result as StdResult;
use std::io;

use args::{ArgMatches, Arg};
use args::settings::{ArgFlags, ArgSettings};
use errors::{ClapResult, error_builder};
use app::App;

#[allow(missing_debug_implementations)]
pub struct OptBuilder<'n> {
    pub name: &'n str,
    /// The short version (i.e. single character) of the argument, no preceding `-`
    pub short: Option<char>,
    /// The long version of the flag (i.e. word) without the preceding `--`
    pub long: Option<&'n str>,
    /// The string of text that will displayed to the user when the application's
    /// `help` text is displayed
    pub help: Option<&'n str>,
    /// A list of names for other arguments that *may not* be used with this flag
    pub blacklist: Option<Vec<&'n str>>,
    /// A list of possible values for this argument
    pub possible_vals: Option<Vec<&'n str>>,
    /// A list of names of other arguments that are *required* to be used when
    /// this flag is used
    pub requires: Option<Vec<&'n str>>,
    pub num_vals: Option<u8>,
    pub min_vals: Option<u8>,
    pub max_vals: Option<u8>,
    pub val_names: Option<BTreeSet<&'n str>>,
    pub validator: Option<Rc<Fn(String) -> StdResult<(), String>>>,
    /// A list of names for other arguments that *mutually override* this flag
    pub overrides: Option<Vec<&'n str>>,
    pub settings: ArgFlags,
}

impl<'n> OptBuilder<'n> {
    pub fn new(name: &'n str) -> Self {
        OptBuilder {
            name: name,
            short: None,
            long: None,
            help: None,
            blacklist: None,
            possible_vals: None,
            requires: None,
            num_vals: None,
            min_vals: None,
            max_vals: None,
            val_names: None,
            validator: None,
            overrides: None,
            settings: ArgFlags::new(),
        }
    }

    pub fn from_arg(a: &Arg<'n, 'n, 'n, 'n, 'n, 'n>, reqs: &mut Vec<&'n str>) -> Self {
        if a.short.is_none() && a.long.is_none() {
            panic!("Argument \"{}\" has takes_value(true), yet neither a short() or long() \
                was supplied",
                   a.name);
        }
        // No need to check for .index() as that is handled above
        let mut ob = OptBuilder {
            name: a.name,
            short: a.short,
            long: a.long,
            blacklist: None,
            help: a.help,
            possible_vals: None,
            num_vals: a.num_vals,
            min_vals: a.min_vals,
            max_vals: a.max_vals,
            val_names: a.val_names.clone(),
            requires: None,
            validator: None,
            overrides: None,
            settings: ArgFlags::new(),
        };
        if a.multiple {
            ob.settings.set(&ArgSettings::Multiple);
        }
        if a.required {
            ob.settings.set(&ArgSettings::Required);
        }
        if a.global {
            ob.settings.set(&ArgSettings::Global);
        }
        if !a.empty_vals {
            ob.settings.unset(&ArgSettings::Global);
        }
        if a.hidden {
            ob.settings.set(&ArgSettings::Hidden);
        }
        if let Some(ref vec) = ob.val_names {
            ob.num_vals = Some(vec.len() as u8);
        }
        // Check if there is anything in the blacklist (mutually excludes list) and add
        // any
        // values
        if let Some(ref bl) = a.blacklist {
            let mut bhs = vec![];
            // without derefing n = &&str
            for n in bl {
                bhs.push(*n);
            }
            ob.blacklist = Some(bhs);
        }
        if let Some(ref p) = a.validator {
            ob.validator = Some(p.clone());
        }
        // Check if there is anything in the requires list and add any values
        if let Some(ref r) = a.requires {
            let mut rhs = vec![];
            // without derefing n = &&str
            for n in r {
                rhs.push(*n);
                if a.required {
                    reqs.push(*n);
                }
            }
            ob.requires = Some(rhs);
        }
        if let Some(ref or) = a.overrides {
            let mut bhs = vec![];
            // without derefing n = &&str
            for n in or {
                bhs.push(*n);
            }
            ob.overrides = Some(bhs);
        }
        // Check if there is anything in the possible values and add those as well
        if let Some(ref p) = a.possible_vals {
            let mut phs = vec![];
            // without derefing n = &&str
            for n in p {
                phs.push(*n);
            }
            ob.possible_vals = Some(phs);
        }

        ob
    }

    pub fn write_help<W: io::Write>(&self, w: &mut W, tab: &str, longest: usize) -> io::Result<()> {
        // if it supports multiple we add '...' i.e. 3 to the name length
        try!(write!(w, "{}", tab));
        if let Some(s) = self.short {
            try!(write!(w, "-{}", s));
        } else {
            try!(write!(w, "{}", tab));
        }
        if let Some(l) = self.long {
            try!(write!(w,
                        "{}--{}",
                        if self.short.is_some() {
                            ", "
                        } else {
                            ""
                        },
                        l));
        }
        if let Some(ref vec) = self.val_names {
            for val in vec {
                try!(write!(w, " <{}>", val));
            }
        } else if let Some(num) = self.num_vals {
            for _ in 0..num {
                try!(write!(w, " <{}>", self.name));
            }
        } else {
            try!(write!(w,
                        " <{}>{}",
                        self.name,
                        if self.settings.is_set(&ArgSettings::Multiple) {
                            "..."
                        } else {
                            ""
                        }));
        }
        if self.long.is_some() {
            write_spaces!((longest + 4) - (self.to_string().len()), w);
        } else {
            // 8 = tab + '-a, '.len()
            write_spaces!((longest + 8) - (self.to_string().len()), w);
        }
        print_opt_help!(self, longest + 12, w);
        write!(w, "\n")
    }

    pub fn validate_value(&self,
                       val: &str,
                       matches: &ArgMatches,
                       app: &App)
                       -> ClapResult<()> {
        // Check the possible values
        if let Some(ref p_vals) = self.possible_vals {
            if !p_vals.contains(&val) {
                let usage = try!(app.create_current_usage(matches));
                return Err(error_builder::InvalidValue(val, p_vals, &self.to_string(), &usage));
            }
        }

        // Check the required number of values
        if let Some(num) = self.num_vals {
            if let Some(ref ma) = matches.args.get(self.name) {
                if let Some(ref vals) = ma.values {
                    if (vals.len() as u8) > num && !self.settings.is_set(&ArgSettings::Multiple) {
                        return Err(error_builder::TooManyValues(
                            val,
                            &self.to_string(),
                            &*try!(app.create_current_usage(matches))));
                    }
                }
            }
        }

        // if it's an empty value, and we don't allow that, report the error
        if !self.settings.is_set(&ArgSettings::EmptyValues) &&
            matches.args.contains_key(self.name) &&
            val.is_empty() {
            return Err(error_builder::EmptyValue(&*self.to_string(),
                                                 &*try!(app.create_current_usage(matches))));
        }

        if let Some(ref vtor) = self.validator {
            if let Err(e) = vtor(val.to_owned()) {
                return Err(error_builder::ValueValidationError(&*e));
            }
        }

        Ok(())
    }
}

impl<'n> Display for OptBuilder<'n> {
    fn fmt(&self, f: &mut Formatter) -> Result {
        // Write the name such --long or -l
        if let Some(l) = self.long {
            try!(write!(f, "--{}", l));
        } else {
            try!(write!(f, "-{}", self.short.unwrap()));
        }

        // Write the values such as <name1> <name2>
        if let Some(ref vec) = self.val_names {
            for n in vec.iter() {
                try!(write!(f, " <{}>", n));
            }
        } else {
            let num = self.num_vals.unwrap_or(1);
            for _ in 0..num {
                try!(write!(f, " <{}>", self.name));
            }
            if self.settings.is_set(&ArgSettings::Multiple) && num == 1 {
                try!(write!(f, "..."));
            }
        }

        Ok(())
    }
}

#[cfg(test)]
mod test {
    use super::OptBuilder;
    use std::collections::BTreeSet;
    use args::settings::ArgSettings;

    #[test]
    fn optbuilder_display() {
        let mut o = OptBuilder::new("opt");
        o.long = Some("option");
        o.settings.set(&ArgSettings::Multiple);

        assert_eq!(&*format!("{}", o), "--option <opt>...");

        let mut v_names = BTreeSet::new();
        v_names.insert("file");
        v_names.insert("name");

        let mut o2 = OptBuilder::new("opt");
        o2.short = Some('o');
        o2.val_names = Some(v_names);

        assert_eq!(&*format!("{}", o2), "-o <file> <name>");
    }
}
<|endoftext|>


<commit_before>//! It's a tree!

use std::ptr;
use std::ops::{Deref, DerefMut};
use std::fmt::Debug;

#[derive(Debug, PartialEq, Eq)]
struct Node<T> {
    // We need a mut pointer so we can modify the parent
    parent: *mut Node<T>,
    val: T,
    children: Vec<Node<T>>
}

impl<T> Node<T> {
    /// Create a new node with the existing value.
    /// For root-style constructors.
    pub fn new(val: T) -> Node<T> {
        Node {
            parent: ptr::null_mut(),
            val: val,
            children: Vec::new()
        }
    }

    /// Add a new child node to this node, using a value
    pub fn new_child(&mut self, val: T) -> &mut Node<T> {
        let self_mut = self as *mut Node<T>;
        self.children.push(Node {
            parent: self_mut,
            val: val,
            children: Vec::new()
        });
        let last_ix = self.children.len() -1;
        &mut self.children[last_ix]
    }

    /// Whether this node has a (currently-reachable) parent
    pub fn has_parent(&self) -> bool {
        self.parent.is_null()
    }

    /// Gets the parent of this node (if it exists)
    pub fn get_parent(&self) -> Option<&mut Node<T>> {
        if self.parent.is_null() {
            return None;
        }
        unsafe {
            return Some(&mut *self.parent);
        }
    }

    /// Borrow the children of this node.
    pub fn get_children<'a>(&'a self) -> &Vec<Node<T>> {
        &self.children
    }

    /// Mutably borrow the children of this mutable node
    pub fn get_mut_children(&mut self) -> &mut Vec<Node<T>> {
        &mut self.children
    }

    /// Remove a child at the given index
    pub fn remove_child_at(&mut self, index: usize) -> Node<T> {
        let mut child = self.children.remove(index);
        child.parent = ptr::null_mut();
        child
    }

    /// Whether this node is a parent of another node
    pub fn is_parent_of(&self, other: Node<T>) -> bool {
        self.parent == other.parent
    }
}

impl <T: PartialEq> Node<T> {

    /// Remove a node from its parent.
    /// This method will mutate the parent if it exists.
    pub fn remove_from_parent(&self) {
        if let Some(ref mut parent) = self.get_parent() {
            let children = parent.get_mut_children();
            if let Some(index) = children.iter().position(|c| c == self) {
                children.remove(index);
            }
        }
    }

    /// Removes a child from self
    pub fn remove_child(&mut self, other: &Node<T>) -> Option<Node<T>> {
        if let Some(index) = self.children.iter().position(|c| c == other) {
            Some(self.children.remove(index))
        }
        else {
            None
        }
    }

    pub fn move_to(mut self, new_parent: &mut Node<T>) {
        self.remove_from_parent();
        self.parent = new_parent as *mut Node<T>;
        new_parent.children.push(self);
    }
}

impl<T> Drop for Node<T> {
    fn drop(&mut self) {
        println!("Dropping a node.");
        let children: &mut Vec<Node<T>> = &mut self.children;
        for mut child in children {
            println!("> Unlinking a child");
            child.parent = ptr::null_mut();
        }
    }
}

#[cfg(test)]
mod tests {
    use super::Node;
    use log::LogLevelFilter;
    use env_logger::LogBuilder;

    /// Nodes can have children added to them
    #[test]
    fn test_add_child() {
        let mut root = Node::new(0);
        root.new_child(1);
        root.new_child(2); // This is okay
        {
            let mut third_child = root.new_child(3);
            //root.new_child(4); // Have to wait for 3rd child to drop
        }
        root.new_child(4); // Now this works yay standard borrowing
        assert_eq!(root.children.len(), 4);
        println!("Done with the test now.");
    }

    /// These operations will for example operate on the parent
    /// under an if let. `remove_from_parent` will not panic if the node
    /// already is parentless, for example.
    #[test]
    fn optional_operations() {

    }
}
<commit_msg>Fixed some things<commit_after>//! It's a tree!

use std::ptr;
use std::ops::{Deref, DerefMut};
use std::fmt::Debug;

#[derive(Debug, PartialEq, Eq)]
struct Node<T> {
    // We need a mut pointer so we can modify the parent
    parent: *mut Node<T>,
    val: T,
    children: Vec<Node<T>>
}

impl<T> Node<T> {
    /// Create a new node with the existing value.
    /// For root-style constructors.
    pub fn new(val: T) -> Node<T> {
        Node {
            parent: ptr::null_mut(),
            val: val,
            children: Vec::new()
        }
    }

    /// Add a new child node to this node, using a value
    pub fn new_child(&mut self, val: T) -> &mut Node<T> {
        let self_mut = self as *mut Node<T>;
        self.children.push(Node {
            parent: self_mut,
            val: val,
            children: Vec::new()
        });
        let last_ix = self.children.len() -1;
        &mut self.children[last_ix]
    }

    /// Whether this node has a (currently-reachable) parent
    pub fn has_parent(&self) -> bool {
        self.parent.is_null()
    }

    /// Gets the parent of this node (if it exists)
    pub fn get_parent(&self) -> Option<&mut Node<T>> {
        if self.parent.is_null() {
            return None;
        }
        unsafe {
            return Some(&mut *self.parent);
        }
    }

    /// Borrow the children of this node.
    pub fn get_children(&self) -> &[Node<T>] {
        &self.children
    }

    /// Mutably borrow the children of this mutable node
    pub fn get_mut_children(&mut self) -> &mut[Node<T>] {
        &mut self.children
    }

    /// Remove a child at the given index
    pub fn remove_child_at(&mut self, index: usize) -> Node<T> {
        let mut child = self.children.remove(index);
        child.parent = ptr::null_mut();
        child
    }

    /// Whether this node is a parent of another node
    pub fn is_parent_of(&self, other: &Node<T>) -> bool {
        self.parent == other.parent as *mut Node<T>
    }
}

impl <T: PartialEq> Node<T> {

    /// Remove a node from its parent.
    /// This method will mutate the parent if it exists.
    pub fn remove_from_parent(&mut self) {
        if self.get_parent().is_none() {
            return;
        }
        if let Some(index) = self.children.iter().position(|c| c == self) {
            self.parent = ptr::null_mut();
            self.children.remove(index);
        }
    }

    /// Removes a child from self
    pub fn remove_child(&mut self, other: &Node<T>) -> Option<Node<T>> {
        if let Some(index) = self.children.iter().position(|c| c == other) {
            let mut child = self.children.remove(index);
            child.parent = ptr::null_mut();
            Some(child)
        }
        else {
            None
        }
    }

    pub fn move_to(mut self, new_parent: &mut Node<T>) {
        self.remove_from_parent();
        self.parent = new_parent as *mut Node<T>;
        new_parent.children.push(self);
    }
}

impl<T> Drop for Node<T> {
    fn drop(&mut self) {
        println!("Dropping a node.");
        let children: &mut Vec<Node<T>> = &mut self.children;
        for mut child in children {
            child.parent = ptr::null_mut();
        }
    }
}

#[cfg(test)]
mod tests {
    use super::Node;
    use log::LogLevelFilter;
    use env_logger::LogBuilder;

    /// Nodes can have children added to them
    #[test]
    fn test_add_child() {
        let mut root = Node::new(0);
        root.new_child(1);
        root.new_child(2); // This is okay
        {
            let mut third_child = root.new_child(3);
            //root.new_child(4); // Have to wait for 3rd child to drop
        }
        root.new_child(4); // Now this works yay standard borrowing
        assert_eq!(root.children.len(), 4);
        println!("Done with the test now.");
    }

    /// These operations will for example operate on the parent
    /// under an if let. `remove_from_parent` will not panic if the node
    /// already is parentless, for example.
    #[test]
    fn optional_operations() {

    }
}
<|endoftext|>


<commit_before>#[cfg(test)]
mod parses_create_table_statement {
    use expectest::prelude::be_equal_to;

    use sql::lexer::{Tokenizer, IntoTokenizer};
    use sql::parser::{QueryParser, IntoQueryParser};
    use sql::ast::{Type, Statement, Constraint, CreateTableQuery, ColumnTable};

    #[test]
    fn with_one_column() {
        expect!(String::from("create table table_name_1 (col integer);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_name_1",
                            vec![ColumnTable::new("col", Type::Integer, vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn with_list_of_columns() {
        expect!(String::from("create table table_name_2 (col1 integer, col2 integer, col3 integer);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_name_2",
                            vec![
                                ColumnTable::new("col1", Type::Integer, vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect()),
                                ColumnTable::new("col2", Type::Integer, vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect()),
                                ColumnTable::new("col3", Type::Integer, vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect())
                            ]
                        )
                    )
                )
            );
    }

    #[test]
    fn with_varchar_column_type() {
        expect!(String::from("create table table_1 (col_2 character(10));").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_1",
                            vec![ColumnTable::new("col_2", Type::VarChar(10), vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn with_default_value_constraint() {
        expect!(String::from("create table table1 (col integer default 1);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table1",
                            vec![ColumnTable::new("col", Type::Integer, vec![Constraint::DefaultValue(Some("1".to_owned())), Constraint::Nullable(true)].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn infer_type_for_primary_key_column() {
        expect!(String::from("create table table_1 (col integer primary key);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_1",
                            vec![ColumnTable::new("col", Type::Integer, vec![Constraint::PrimeryKey, Constraint::DefaultValue(None)].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn with_primary_key_discard_default_value() {
        expect!(String::from("create table table_1 (col integer primary key default 1);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_1",
                            vec![ColumnTable::new("col", Type::Integer, vec![Constraint::PrimeryKey, Constraint::DefaultValue(None)].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn not_null_constraint() {
        expect!(String::from("create table table_2 (col integer not null);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_2",
                            vec![ColumnTable::new("col", Type::Integer, vec![Constraint::Nullable(false), Constraint::DefaultValue(Some("0".to_owned()))].into_iter().collect())]
                        )
                    )
                )
            );
    }
}

#[cfg(test)]
mod parses_delete_statements {
    use expectest::prelude::be_equal_to;

    use sql::lexer::{Tokenizer, IntoTokenizer};
    use sql::parser::{QueryParser, IntoQueryParser};
    use sql::ast::{Statement, DeleteQuery, Condition, CondArg};

    #[test]
    fn without_any_predicates() {
        expect!(String::from("delete from table_name_1;").into_tokenizer().tokenize().into_parser().parse())
            .to(be_equal_to(Statement::Delete(DeleteQuery::new("table_name_1", None))));
    }

    #[test]
    fn with_column_const_predicate() {
        expect!(String::from("delete from table_name_2 where col_1 = 5;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Delete(
                        DeleteQuery::new(
                            "table_name_2",
                            Some(
                                Condition::equals(
                                    CondArg::column("col_1"),
                                    CondArg::num("5")
                                )
                            )
                        )
                    )
                )
            );
    }

    #[test]
    fn with_const_column_predicate() {
        expect!(String::from("delete from table_name_3 where 'str' = col_2;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Delete(
                        DeleteQuery::new(
                            "table_name_3",
                            Some(
                                Condition::equals(
                                    CondArg::str("str"),
                                    CondArg::column("col_2")
                                )
                            )
                        )
                    )
                )
            );
    }
}

#[cfg(test)]
mod parses_insert_statements {
    use expectest::prelude::be_equal_to;

    use sql::lexer::{Tokenizer, IntoTokenizer};
    use sql::parser::{QueryParser, IntoQueryParser};
    use sql::ast::{InsertQuery, SelectQuery};
    use sql::ast::Statement::Insert;
    use sql::ast::Value;
    use sql::ast::ValueSource;

    #[test]
    fn with_one_column() {
        expect!(String::from("insert into table_name_1 values(10);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Insert(
                        InsertQuery::new("table_name_1", vec![], ValueSource::Row(vec![Value::num("10")]))
                    )
                )
            );
    }

    #[test]
    fn with_list_of_columns() {
        expect!(String::from("insert into table_name_2 values (10, 'string');").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Insert(
                        InsertQuery::new(
                            "table_name_2",
                            vec![],
                            ValueSource::Row(vec![Value::num("10"), Value::str("string")])
                        )
                    )
                )
            );
    }

    #[test]
    fn with_columns() {
        expect!(String::from("insert into table_name_3 (col_1, col_2) values (10, 'string');").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Insert(
                        InsertQuery::new(
                            "table_name_3",
                            vec!["col_1", "col_2"],
                            ValueSource::Row(vec![Value::num("10"), Value::str("string")])
                        )
                    )
                )
            );
    }

    #[test]
    fn with_sub_select() {
        expect!(String::from("insert into table_1 (col_1, col_2) select col_1, col_2 from table_1;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Insert(
                        InsertQuery::new(
                            "table_1",
                            vec!["col_1", "col_2"],
                            ValueSource::SubQuery(SelectQuery::new("table_1", vec!["col_1", "col_2"], None))
                        )
                    )
                )
            );
    }
}

#[cfg(test)]
mod parse_select_statements {

    use expectest::prelude::be_equal_to;

    use sql::lexer::{Tokenizer, IntoTokenizer};
    use sql::parser::{QueryParser, IntoQueryParser};
    use sql::ast::Statement::Select;
    use sql::ast::SelectQuery;
    use sql::ast::Condition;
    use sql::ast::CondArg;

    #[test]
    fn without_predicates() {
        expect!(String::from("select col_1 from table_name_1;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Select(
                        SelectQuery::new("table_name_1", vec!["col_1"], None)
                    )
                )
            );
    }

    #[test]
    fn with_predicates() {
        expect!(String::from("select col_2 from table_name_2 where col_2 = 10;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Select(
                        SelectQuery::new(
                            "table_name_2",
                            vec!["col_2"],
                            Some(Condition::equals(CondArg::column("col_2"), CondArg::num("10")))
                        )
                    )
                )
            );
    }

    #[test]
    fn with_limit_predicate() {
        expect!(String::from("select col_2 from table_name_2 where limit = 10;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Select(
                        SelectQuery::new(
                            "table_name_2",
                            vec!["col_2"],
                            Some(Condition::equals(CondArg::Limit, CondArg::num("10")))
                        )
                    )
                )
            );
    }

    #[test]
    fn with_not_equal_predicate() {
        expect!(String::from("select col_2 from table_1 where col_1 <> \'a\';").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Select(
                        SelectQuery::new(
                            "table_1",
                            vec!["col_2"],
                            Some(Condition::not_equals(CondArg::column("col_1"), CondArg::str("a")))
                        )
                    )
                )
            );
    }
}
<commit_msg>test for not null with default constraints<commit_after>#[cfg(test)]
mod parses_create_table_statement {
    use expectest::prelude::be_equal_to;

    use sql::lexer::{Tokenizer, IntoTokenizer};
    use sql::parser::{QueryParser, IntoQueryParser};
    use sql::ast::{Type, Statement, Constraint, CreateTableQuery, ColumnTable};

    #[test]
    fn with_one_column() {
        expect!(String::from("create table table_name_1 (col integer);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_name_1",
                            vec![ColumnTable::new("col", Type::Integer, vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn with_list_of_columns() {
        expect!(String::from("create table table_name_2 (col1 integer, col2 integer, col3 integer);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_name_2",
                            vec![
                                ColumnTable::new("col1", Type::Integer, vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect()),
                                ColumnTable::new("col2", Type::Integer, vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect()),
                                ColumnTable::new("col3", Type::Integer, vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect())
                            ]
                        )
                    )
                )
            );
    }

    #[test]
    fn with_varchar_column_type() {
        expect!(String::from("create table table_1 (col_2 character(10));").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_1",
                            vec![ColumnTable::new("col_2", Type::VarChar(10), vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn with_default_value_constraint() {
        expect!(String::from("create table table1 (col integer default 1);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table1",
                            vec![ColumnTable::new("col", Type::Integer, vec![Constraint::DefaultValue(Some("1".to_owned())), Constraint::Nullable(true)].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn infer_type_for_primary_key_column() {
        expect!(String::from("create table table_1 (col integer primary key);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_1",
                            vec![ColumnTable::new("col", Type::Integer, vec![Constraint::PrimeryKey, Constraint::DefaultValue(None)].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn with_primary_key_discard_default_value() {
        expect!(String::from("create table table_1 (col integer primary key default 1);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_1",
                            vec![ColumnTable::new("col", Type::Integer, vec![Constraint::PrimeryKey, Constraint::DefaultValue(None)].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn not_null_constraint() {
        expect!(String::from("create table table_2 (col integer not null);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "table_2",
                            vec![ColumnTable::new("col", Type::Integer, vec![Constraint::Nullable(false), Constraint::DefaultValue(Some("0".to_owned()))].into_iter().collect())]
                        )
                    )
                )
            );
    }

    #[test]
    fn not_null_with_default() {
        expect!(String::from("create table tab3 (col1 integer not null default 4, col2 integer);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Create(
                        CreateTableQuery::new(
                            "tab3",
                            vec![
                                ColumnTable::new("col1", Type::Integer, vec![Constraint::Nullable(false), Constraint::DefaultValue(Some("4".to_owned()))].into_iter().collect()),
                                ColumnTable::new("col2", Type::Integer, vec![Constraint::Nullable(true), Constraint::DefaultValue(None)].into_iter().collect())
                            ]
                        )
                    )
                )
            );
    }
}

#[cfg(test)]
mod parses_delete_statements {
    use expectest::prelude::be_equal_to;

    use sql::lexer::{Tokenizer, IntoTokenizer};
    use sql::parser::{QueryParser, IntoQueryParser};
    use sql::ast::{Statement, DeleteQuery, Condition, CondArg};

    #[test]
    fn without_any_predicates() {
        expect!(String::from("delete from table_name_1;").into_tokenizer().tokenize().into_parser().parse())
            .to(be_equal_to(Statement::Delete(DeleteQuery::new("table_name_1", None))));
    }

    #[test]
    fn with_column_const_predicate() {
        expect!(String::from("delete from table_name_2 where col_1 = 5;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Delete(
                        DeleteQuery::new(
                            "table_name_2",
                            Some(
                                Condition::equals(
                                    CondArg::column("col_1"),
                                    CondArg::num("5")
                                )
                            )
                        )
                    )
                )
            );
    }

    #[test]
    fn with_const_column_predicate() {
        expect!(String::from("delete from table_name_3 where 'str' = col_2;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Statement::Delete(
                        DeleteQuery::new(
                            "table_name_3",
                            Some(
                                Condition::equals(
                                    CondArg::str("str"),
                                    CondArg::column("col_2")
                                )
                            )
                        )
                    )
                )
            );
    }
}

#[cfg(test)]
mod parses_insert_statements {
    use expectest::prelude::be_equal_to;

    use sql::lexer::{Tokenizer, IntoTokenizer};
    use sql::parser::{QueryParser, IntoQueryParser};
    use sql::ast::{InsertQuery, SelectQuery};
    use sql::ast::Statement::Insert;
    use sql::ast::Value;
    use sql::ast::ValueSource;

    #[test]
    fn with_one_column() {
        expect!(String::from("insert into table_name_1 values(10);").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Insert(
                        InsertQuery::new("table_name_1", vec![], ValueSource::Row(vec![Value::num("10")]))
                    )
                )
            );
    }

    #[test]
    fn with_list_of_columns() {
        expect!(String::from("insert into table_name_2 values (10, 'string');").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Insert(
                        InsertQuery::new(
                            "table_name_2",
                            vec![],
                            ValueSource::Row(vec![Value::num("10"), Value::str("string")])
                        )
                    )
                )
            );
    }

    #[test]
    fn with_columns() {
        expect!(String::from("insert into table_name_3 (col_1, col_2) values (10, 'string');").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Insert(
                        InsertQuery::new(
                            "table_name_3",
                            vec!["col_1", "col_2"],
                            ValueSource::Row(vec![Value::num("10"), Value::str("string")])
                        )
                    )
                )
            );
    }

    #[test]
    fn with_sub_select() {
        expect!(String::from("insert into table_1 (col_1, col_2) select col_1, col_2 from table_1;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Insert(
                        InsertQuery::new(
                            "table_1",
                            vec!["col_1", "col_2"],
                            ValueSource::SubQuery(SelectQuery::new("table_1", vec!["col_1", "col_2"], None))
                        )
                    )
                )
            );
    }
}

#[cfg(test)]
mod parse_select_statements {

    use expectest::prelude::be_equal_to;

    use sql::lexer::{Tokenizer, IntoTokenizer};
    use sql::parser::{QueryParser, IntoQueryParser};
    use sql::ast::Statement::Select;
    use sql::ast::SelectQuery;
    use sql::ast::Condition;
    use sql::ast::CondArg;

    #[test]
    fn without_predicates() {
        expect!(String::from("select col_1 from table_name_1;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Select(
                        SelectQuery::new("table_name_1", vec!["col_1"], None)
                    )
                )
            );
    }

    #[test]
    fn with_predicates() {
        expect!(String::from("select col_2 from table_name_2 where col_2 = 10;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Select(
                        SelectQuery::new(
                            "table_name_2",
                            vec!["col_2"],
                            Some(Condition::equals(CondArg::column("col_2"), CondArg::num("10")))
                        )
                    )
                )
            );
    }

    #[test]
    fn with_limit_predicate() {
        expect!(String::from("select col_2 from table_name_2 where limit = 10;").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Select(
                        SelectQuery::new(
                            "table_name_2",
                            vec!["col_2"],
                            Some(Condition::equals(CondArg::Limit, CondArg::num("10")))
                        )
                    )
                )
            );
    }

    #[test]
    fn with_not_equal_predicate() {
        expect!(String::from("select col_2 from table_1 where col_1 <> \'a\';").into_tokenizer().tokenize().into_parser().parse())
            .to(
                be_equal_to(
                    Select(
                        SelectQuery::new(
                            "table_1",
                            vec!["col_2"],
                            Some(Condition::not_equals(CondArg::column("col_1"), CondArg::str("a")))
                        )
                    )
                )
            );
    }
}
<|endoftext|>


<commit_before>use std::fs::File;
use std::io::prelude::*;
use toml::{self, Value};
use toml::value::Table;

use config::Config;
use env::Env;
use file_saver::save_to_file;
use nameutil;
use version::Version;

pub fn generate(env: &Env) -> String {
    info!(
        "Generating sys Cargo.toml for {}",
        env.config.library_name
    );

    let path = env.config.target_path.join("Cargo.toml");

    let mut toml_str = String::new();
    if let Ok(mut file) = File::open(&path) {
        file.read_to_string(&mut toml_str).unwrap();
    }
    let empty = toml_str.trim().is_empty();
    let mut root_table = toml::from_str(&toml_str).unwrap_or_else(|_| Table::new());
    let crate_name = get_crate_name(&env.config, &root_table);

    if empty {
        fill_empty(&mut root_table, env, &crate_name);
    }
    fill_in(&mut root_table, env);

    save_to_file(&path, env.config.make_backup, |w| {
        w.write_all(toml::to_string(&root_table).unwrap().as_bytes())
    });

    crate_name
}

fn fill_empty(root: &mut Table, env: &Env, crate_name: &str) {
    let package_name = nameutil::exported_crate_name(crate_name);

    {
        let package = upsert_table(root, "package");
        set_string(package, "name", package_name);
        set_string(package, "version", "0.0.1");
        set_string(package, "links", nameutil::crate_name(&env.config.library_name));
    }

    {
        let lib = upsert_table(root, "lib");
        set_string(lib, "name", crate_name);
    }

    let deps = upsert_table(root, "dependencies");
    for ext_lib in &env.config.external_libraries {
        let ext_package = format!("{}-sys", ext_lib.crate_name);
        let dep = upsert_table(deps, &*ext_package);
        if ext_package.ends_with("-sys") {
            set_string(dep, "git", "https://github.com/gtk-rs/sys");
        } else {
            set_string(dep, "git", format!("https://github.com/gtk-rs/{}", ext_package));
        }
    }
}

fn fill_in(root: &mut Table, env: &Env) {
    {
        let package = upsert_table(root, "package");
        set_string(package, "build", "build.rs");
        //set_string(package, "version", "0.2.0");
    }

    {
        let deps = upsert_table(root, "dependencies");
        set_string(deps, "libc", "0.2");
    }

    {
        let build_deps = upsert_table(root, "build-dependencies");
        set_string(build_deps, "pkg-config", "0.3.7");
    }

    {
        let dev_deps = upsert_table(root, "dev-dependencies");
        set_string(dev_deps, "shell-words", "0.1.0");
        set_string(dev_deps, "tempdir", "0.3");
    }

    {
        let features = upsert_table(root, "features");
        let versions = env.namespaces
            .main()
            .versions
            .iter()
            .filter(|&&v| v > env.config.min_cfg_version);
        versions.fold(None::<Version>, |prev, &version| {
            let prev_array: Vec<Value> =
                prev.iter().map(|v| Value::String(v.to_feature())).collect();
            features.insert(version.to_feature(), Value::Array(prev_array));
            Some(version)
        });
        features.insert("dox".to_string(), Value::Array(Vec::new()));
    }
}

/// Returns the name of crate being currently generated.
fn get_crate_name(config: &Config, root: &Table) -> String {
    if let Some(&Value::Table(ref lib)) = root.get("lib") {
        if let Some(&Value::String(ref lib_name)) = lib.get("name") {
            //Converting don't needed as library target names cannot contain hyphens
            return lib_name.to_owned();
        }
    }
    if let Some(&Value::Table(ref package)) = root.get("package") {
        if let Some(&Value::String(ref package_name)) = package.get("name") {
            return nameutil::crate_name(package_name);
        }
    }
    return format!("{}_sys", nameutil::crate_name(&config.library_name));
}

fn set_string<S: Into<String>>(table: &mut Table, name: &str, new_value: S) {
    if let Some(v) = table.get_mut(name) {
        *v = Value::String(new_value.into());
        return;
    }
    table.insert(name.into(), Value::String(new_value.into()));
}

fn upsert_table<S: Into<String>>(parent: &mut Table, name: S) -> &mut Table {
    if let Value::Table(ref mut table) = *parent
        .entry(name.into())
        .or_insert_with(|| Value::Table(toml::map::Map::new()))
    {
        table
    } else {
        unreachable!()
    }
}
<commit_msg>Improve specific sys dependencies<commit_after>use std::fs::File;
use std::io::prelude::*;
use toml::{self, Value};
use toml::value::Table;

use config::Config;
use env::Env;
use file_saver::save_to_file;
use nameutil;
use version::Version;

pub fn generate(env: &Env) -> String {
    info!(
        "Generating sys Cargo.toml for {}",
        env.config.library_name
    );

    let path = env.config.target_path.join("Cargo.toml");

    let mut toml_str = String::new();
    if let Ok(mut file) = File::open(&path) {
        file.read_to_string(&mut toml_str).unwrap();
    }
    let empty = toml_str.trim().is_empty();
    let mut root_table = toml::from_str(&toml_str).unwrap_or_else(|_| Table::new());
    let crate_name = get_crate_name(&env.config, &root_table);

    if empty {
        fill_empty(&mut root_table, env, &crate_name);
    }
    fill_in(&mut root_table, env);

    save_to_file(&path, env.config.make_backup, |w| {
        w.write_all(toml::to_string(&root_table).unwrap().as_bytes())
    });

    crate_name
}

fn fill_empty(root: &mut Table, env: &Env, crate_name: &str) {
    let package_name = nameutil::exported_crate_name(crate_name);

    {
        let package = upsert_table(root, "package");
        set_string(package, "name", package_name);
        set_string(package, "version", "0.0.1");
        set_string(package, "links", nameutil::crate_name(&env.config.library_name));
    }

    {
        let lib = upsert_table(root, "lib");
        set_string(lib, "name", crate_name);
    }

    let deps = upsert_table(root, "dependencies");
    for ext_lib in &env.config.external_libraries {
        let ext_package = if ext_lib.crate_name == "cairo" {
            format!("{}-sys-rs", ext_lib.crate_name)
        } else if ext_lib.crate_name == "gdk_pixbuf" {
            format!("gdk-pixbuf-sys")
        } else {
            format!("{}-sys", ext_lib.crate_name)
        };
        let dep = upsert_table(deps, &*ext_package);
        if ext_lib.crate_name == "cairo" {
            set_string(dep, "git", "https://github.com/gtk-rs/cairo");
        } else if ext_package.starts_with("sourceview") {
            set_string(dep, "git", "https://github.com/gtk-rs/sourceview");
        } else {
            set_string(dep, "git", "https://github.com/gtk-rs/sys");
        }
    }
}

fn fill_in(root: &mut Table, env: &Env) {
    {
        let package = upsert_table(root, "package");
        set_string(package, "build", "build.rs");
        //set_string(package, "version", "0.2.0");
    }

    {
        let deps = upsert_table(root, "dependencies");
        set_string(deps, "libc", "0.2");
    }

    {
        let build_deps = upsert_table(root, "build-dependencies");
        set_string(build_deps, "pkg-config", "0.3.7");
    }

    {
        let dev_deps = upsert_table(root, "dev-dependencies");
        set_string(dev_deps, "shell-words", "0.1.0");
        set_string(dev_deps, "tempdir", "0.3");
    }

    {
        let features = upsert_table(root, "features");
        let versions = env.namespaces
            .main()
            .versions
            .iter()
            .filter(|&&v| v > env.config.min_cfg_version);
        versions.fold(None::<Version>, |prev, &version| {
            let prev_array: Vec<Value> =
                prev.iter().map(|v| Value::String(v.to_feature())).collect();
            features.insert(version.to_feature(), Value::Array(prev_array));
            Some(version)
        });
        features.insert("dox".to_string(), Value::Array(Vec::new()));
    }
}

/// Returns the name of crate being currently generated.
fn get_crate_name(config: &Config, root: &Table) -> String {
    if let Some(&Value::Table(ref lib)) = root.get("lib") {
        if let Some(&Value::String(ref lib_name)) = lib.get("name") {
            //Converting don't needed as library target names cannot contain hyphens
            return lib_name.to_owned();
        }
    }
    if let Some(&Value::Table(ref package)) = root.get("package") {
        if let Some(&Value::String(ref package_name)) = package.get("name") {
            return nameutil::crate_name(package_name);
        }
    }
    return format!("{}_sys", nameutil::crate_name(&config.library_name));
}

fn set_string<S: Into<String>>(table: &mut Table, name: &str, new_value: S) {
    if let Some(v) = table.get_mut(name) {
        *v = Value::String(new_value.into());
        return;
    }
    table.insert(name.into(), Value::String(new_value.into()));
}

fn upsert_table<S: Into<String>>(parent: &mut Table, name: S) -> &mut Table {
    if let Value::Table(ref mut table) = *parent
        .entry(name.into())
        .or_insert_with(|| Value::Table(toml::map::Map::new()))
    {
        table
    } else {
        unreachable!()
    }
}
<|endoftext|>


<commit_before><commit_msg>EEWBuffer: Set the initial block capacity to 64<commit_after><|endoftext|>


<commit_before>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Platform-specific types, as defined by C.
//!
//! Code that interacts via FFI will almost certainly be using the
//! base types provided by C, which aren't nearly as nicely defined
//! as Rust's primitive types. This module provides types which will
//! match those defined by C, so that code that interacts with C will
//! refer to the correct types.

#![stable(feature = "raw_os", since = "1.1.0")]

use fmt;

#[doc(include = "os/raw/char.md")]
#[cfg(any(all(target_os = "linux", any(target_arch = "aarch64",
                                       target_arch = "arm",
                                       target_arch = "powerpc",
                                       target_arch = "powerpc64",
                                       target_arch = "s390x")),
          all(target_os = "android", any(target_arch = "aarch64",
                                         target_arch = "arm")),
          all(target_os = "l4re", target_arch = "x86_64"),
          all(target_os = "openbsd", target_arch = "aarch64"),
          all(target_os = "fuchsia", target_arch = "aarch64")))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8;
#[doc(include = "os/raw/char.md")]
#[cfg(not(any(all(target_os = "linux", any(target_arch = "aarch64",
                                           target_arch = "arm",
                                           target_arch = "powerpc",
                                           target_arch = "powerpc64",
                                           target_arch = "s390x")),
              all(target_os = "android", any(target_arch = "aarch64",
                                             target_arch = "arm")),
              all(target_os = "l4re", target_arch = "x86_64"),
              all(target_os = "openbsd", target_arch = "aarch64"),
              all(target_os = "fuchsia", target_arch = "aarch64"))))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8;
#[doc(include = "os/raw/schar.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8;
#[doc(include = "os/raw/uchar.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8;
#[doc(include = "os/raw/short.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_short = i16;
#[doc(include = "os/raw/ushort.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ushort = u16;
#[doc(include = "os/raw/int.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_int = i32;
#[doc(include = "os/raw/uint.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_uint = u32;
#[doc(include = "os/raw/long.md")]
#[cfg(any(target_pointer_width = "32", windows))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i32;
#[doc(include = "os/raw/ulong.md")]
#[cfg(any(target_pointer_width = "32", windows))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u32;
#[doc(include = "os/raw/long.md")]
#[cfg(all(target_pointer_width = "64", not(windows)))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i64;
#[doc(include = "os/raw/ulong.md")]
#[cfg(all(target_pointer_width = "64", not(windows)))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u64;
#[doc(include = "os/raw/longlong.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_longlong = i64;
#[doc(include = "os/raw/ulonglong.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulonglong = u64;
#[doc(include = "os/raw/float.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_float = f32;
#[doc(include = "os/raw/double.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_double = f64;

/// Equivalent to C's `void` type when used as a [pointer].
///
/// In essence, `*const c_void` is equivalent to C's `const void*`
/// and `*mut c_void` is equivalent to C's `void*`. That said, this is
/// *not* the same as C's `void` return type, which is Rust's `()` type.
///
/// Ideally, this type would be equivalent to [`!`], but currently it may
/// be more ideal to use `c_void` for FFI purposes.
///
/// [`!`]: ../../primitive.never.html
/// [pointer]: ../../primitive.pointer.html
// NB: For LLVM to recognize the void pointer type and by extension
//     functions like malloc(), we need to have it represented as i8* in
//     LLVM bitcode. The enum used here ensures this and prevents misuse
//     of the "raw" type by only having private variants.. We need two
//     variants, because the compiler complains about the repr attribute
//     otherwise.
#[repr(u8)]
#[stable(feature = "raw_os", since = "1.1.0")]
pub enum c_void {
    #[unstable(feature = "c_void_variant", reason = "should not have to exist",
               issue = "0")]
    #[doc(hidden)] __variant1,
    #[unstable(feature = "c_void_variant", reason = "should not have to exist",
               issue = "0")]
    #[doc(hidden)] __variant2,
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for c_void {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("c_void")
    }
}

#[cfg(test)]
#[allow(unused_imports)]
mod tests {
    use any::TypeId;
    use libc;
    use mem;

    macro_rules! ok {
        ($($t:ident)*) => {$(
            assert!(TypeId::of::<libc::$t>() == TypeId::of::<raw::$t>(),
                    "{} is wrong", stringify!($t));
        )*}
    }

    #[test]
    fn same() {
        use os::raw;
        ok!(c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong
            c_longlong c_ulonglong c_float c_double);
    }
}
<commit_msg>Rollup merge of #53116 - jakllsch:netbsd-unsigned-char, r=alexcrichton<commit_after>// Copyright 2015 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

//! Platform-specific types, as defined by C.
//!
//! Code that interacts via FFI will almost certainly be using the
//! base types provided by C, which aren't nearly as nicely defined
//! as Rust's primitive types. This module provides types which will
//! match those defined by C, so that code that interacts with C will
//! refer to the correct types.

#![stable(feature = "raw_os", since = "1.1.0")]

use fmt;

#[doc(include = "os/raw/char.md")]
#[cfg(any(all(target_os = "linux", any(target_arch = "aarch64",
                                       target_arch = "arm",
                                       target_arch = "powerpc",
                                       target_arch = "powerpc64",
                                       target_arch = "s390x")),
          all(target_os = "android", any(target_arch = "aarch64",
                                         target_arch = "arm")),
          all(target_os = "l4re", target_arch = "x86_64"),
          all(target_os = "netbsd", any(target_arch = "arm",
                                        target_arch = "powerpc")),
          all(target_os = "openbsd", target_arch = "aarch64"),
          all(target_os = "fuchsia", target_arch = "aarch64")))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = u8;
#[doc(include = "os/raw/char.md")]
#[cfg(not(any(all(target_os = "linux", any(target_arch = "aarch64",
                                           target_arch = "arm",
                                           target_arch = "powerpc",
                                           target_arch = "powerpc64",
                                           target_arch = "s390x")),
              all(target_os = "android", any(target_arch = "aarch64",
                                             target_arch = "arm")),
              all(target_os = "l4re", target_arch = "x86_64"),
              all(target_os = "netbsd", any(target_arch = "arm",
                                            target_arch = "powerpc")),
              all(target_os = "openbsd", target_arch = "aarch64"),
              all(target_os = "fuchsia", target_arch = "aarch64"))))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_char = i8;
#[doc(include = "os/raw/schar.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_schar = i8;
#[doc(include = "os/raw/uchar.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_uchar = u8;
#[doc(include = "os/raw/short.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_short = i16;
#[doc(include = "os/raw/ushort.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ushort = u16;
#[doc(include = "os/raw/int.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_int = i32;
#[doc(include = "os/raw/uint.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_uint = u32;
#[doc(include = "os/raw/long.md")]
#[cfg(any(target_pointer_width = "32", windows))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i32;
#[doc(include = "os/raw/ulong.md")]
#[cfg(any(target_pointer_width = "32", windows))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u32;
#[doc(include = "os/raw/long.md")]
#[cfg(all(target_pointer_width = "64", not(windows)))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_long = i64;
#[doc(include = "os/raw/ulong.md")]
#[cfg(all(target_pointer_width = "64", not(windows)))]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulong = u64;
#[doc(include = "os/raw/longlong.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_longlong = i64;
#[doc(include = "os/raw/ulonglong.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_ulonglong = u64;
#[doc(include = "os/raw/float.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_float = f32;
#[doc(include = "os/raw/double.md")]
#[stable(feature = "raw_os", since = "1.1.0")] pub type c_double = f64;

/// Equivalent to C's `void` type when used as a [pointer].
///
/// In essence, `*const c_void` is equivalent to C's `const void*`
/// and `*mut c_void` is equivalent to C's `void*`. That said, this is
/// *not* the same as C's `void` return type, which is Rust's `()` type.
///
/// Ideally, this type would be equivalent to [`!`], but currently it may
/// be more ideal to use `c_void` for FFI purposes.
///
/// [`!`]: ../../primitive.never.html
/// [pointer]: ../../primitive.pointer.html
// NB: For LLVM to recognize the void pointer type and by extension
//     functions like malloc(), we need to have it represented as i8* in
//     LLVM bitcode. The enum used here ensures this and prevents misuse
//     of the "raw" type by only having private variants.. We need two
//     variants, because the compiler complains about the repr attribute
//     otherwise.
#[repr(u8)]
#[stable(feature = "raw_os", since = "1.1.0")]
pub enum c_void {
    #[unstable(feature = "c_void_variant", reason = "should not have to exist",
               issue = "0")]
    #[doc(hidden)] __variant1,
    #[unstable(feature = "c_void_variant", reason = "should not have to exist",
               issue = "0")]
    #[doc(hidden)] __variant2,
}

#[stable(feature = "std_debug", since = "1.16.0")]
impl fmt::Debug for c_void {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        f.pad("c_void")
    }
}

#[cfg(test)]
#[allow(unused_imports)]
mod tests {
    use any::TypeId;
    use libc;
    use mem;

    macro_rules! ok {
        ($($t:ident)*) => {$(
            assert!(TypeId::of::<libc::$t>() == TypeId::of::<raw::$t>(),
                    "{} is wrong", stringify!($t));
        )*}
    }

    #[test]
    fn same() {
        use os::raw;
        ok!(c_char c_schar c_uchar c_short c_ushort c_int c_uint c_long c_ulong
            c_longlong c_ulonglong c_float c_double);
    }
}
<|endoftext|>


<commit_before>extern crate rspgod;
extern crate postgres;
extern crate rustc_serialize;

use postgres::{Connection, SslMode};
use rspgod::types::{Change};
use rustc_serialize::json;

#[derive(Debug)]
struct TestRecord {
    id:   i32,
    name: String,
}

#[test]
fn sanity_test() {
    with_clean_database(|c| {
        let records = vec![
            TestRecord { id: 1, name: "Michael Baker".to_string() },
            TestRecord { id: 2, name: "Josh Cheek".to_string(),   },
        ];

        for record in records.iter() {
            create_record(c, &record);
        }

        fetch_records(c);
    });
}

#[test]
fn basic_insert() {
    with_slot(|c| {
        let record = TestRecord {id: 1, name: "Michael Baker".to_string(), };
        create_record(c, &record);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 1);
        let change:Change = json::decode(&updates[0][..]).unwrap();
        assert!(match change {
            Change::Insert {..} => { true },
            _                   => { false },
        });
    });
}

#[test]
fn basic_delete() {
    with_slot(|c| {
        let record = TestRecord {id: 1, name: "Michael Baker".to_string(), };
        create_record(c, &record);
        delete_record(c, 1);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 2);
        let change:Change = json::decode(&updates[1][..]).unwrap();
        assert!(match change {
            Change::Delete {..} => { true },
            _                   => { false },
        });
    });
}

//
// [TODO] I want to move a lot of these into a utility module when I can figure out how to do that
//

fn fetch_updates(c: &Connection) -> Vec<String> {
    let stmt = c.prepare("SELECT * FROM pg_logical_slot_peek_changes('slot', NULL, NULL)").unwrap();
    let mut result = vec![];
    for r in stmt.query(&[]).unwrap() {
        result.push(r.get(2));
    }
    result
}

fn create_slot(c: &Connection) {
    let stmt = c.prepare("select * from pg_create_logical_replication_slot('slot', 'thingy')").unwrap();
    stmt.execute(&[]).unwrap();
}

fn drop_slot(c: &Connection) {
    let stmt = c.prepare("select pg_drop_replication_slot('slot')").unwrap();
    match stmt.execute(&[]) {
        _ => {},
    }
}

fn with_slot<F>(f: F) where F:Fn(&Connection) -> () {
    with_clean_database(|c| {
        drop_slot(c);
        create_slot(c);
        f(c);
        drop_slot(c);
    });
}

fn with_clean_database<F>(f: F) where F:Fn(&Connection) -> () {
    let c = connection();
    reset_database(&c);
    f(&c);
    drop_database(&c);
}

fn reset_database(c: &Connection) {
    drop_database(&c);
    create_database(&c);
}

fn create_database(c: &Connection) {
    let stmt = c.prepare("create table test_table (id int primary key, name text)").unwrap();
    stmt.execute(&[]).unwrap();
}

fn fetch_records(c: &Connection) -> Vec<TestRecord> {
    let stmt = c.prepare("select id, name from test_table").unwrap();
    let results = stmt.query(&[]).unwrap();
    results.iter().map(|r| {
        TestRecord {
            id:   r.get(0),
            name: r.get(1),
        }
    }).collect()
}

fn create_record(c: &Connection, r: &TestRecord) {
    let stmt = c.prepare("insert into test_table (id, name) values ($1, $2)").unwrap();
    stmt.execute(&[
        &r.id,
        &r.name,
    ]).unwrap();
}

fn delete_record(c: &Connection, id: i32) {
    let stmt = c.prepare("delete from test_table where id = $1").unwrap();
    stmt.execute(&[&id]).unwrap();
}

fn drop_database(c: &Connection) {
    let stmt = c.prepare("drop table if exists test_table").unwrap();
    stmt.execute(&[]).unwrap();
}

fn connection_string() -> String {
    match std::env::var("POSTGRES_URL") {
        Ok(val) => val,
        Err(e)  => panic!(format!("You must set the POSTGRES_URL environment variable to point to a running Postgres test database when running automated tests: {}", e)),
    }
}

fn connection() -> Connection {
    match Connection::connect(&connection_string()[..], &SslMode::None) {
        Ok(c)  => c,
        Err(e) => panic!(format!("Could not connect to the test database: {}", e)),
    }
}
<commit_msg>Adds an update test<commit_after>extern crate rspgod;
extern crate postgres;
extern crate rustc_serialize;

use postgres::{Connection, SslMode};
use rspgod::types::{Change};
use rustc_serialize::json;

#[derive(Debug)]
struct TestRecord {
    id:   i32,
    name: String,
}

#[test]
fn sanity_test() {
    with_clean_database(|c| {
        let records = vec![
            TestRecord { id: 1, name: "Michael Baker".to_string() },
            TestRecord { id: 2, name: "Josh Cheek".to_string()   },
        ];

        for record in records.iter() {
            create_record(c, &record);
        }

        fetch_records(c);
    });
}

#[test]
fn basic_insert() {
    with_slot(|c| {
        let record = TestRecord { id: 1, name: "Michael Baker".to_string(), };
        create_record(c, &record);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 1);
        let change:Change = json::decode(&updates[0][..]).unwrap();
        assert!(match change {
            Change::Insert {..} => { true },
            _                   => { false },
        });
    });
}

#[test]
fn basic_delete() {
    with_slot(|c| {
        let record = TestRecord { id: 1, name: "Michael Baker".to_string() };
        create_record(c, &record);
        delete_record(c, 1);
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 2);
        let change:Change = json::decode(&updates[1][..]).unwrap();
        assert!(match change {
            Change::Delete {..} => { true },
            _                   => { false },
        });
    });
}

#[test]
fn basic_update() {
    with_slot(|c| {
        let record = TestRecord { id: 1, name: "Michael Baker".to_string() };
        create_record(c, &record);
        update_record(c, TestRecord { id: 1, name: "Bichael Maker".to_string() });
        let updates = fetch_updates(c);
        assert_eq!(updates.len(), 2);
        let change:Change = json::decode(&updates[1][..]).unwrap();
        assert!(match change {
            Change::Update {..} => { true },
            _                   => { false },
        });
    });
}

//
// [TODO] I want to move a lot of these into a utility module when I can figure out how to do that
//

fn fetch_updates(c: &Connection) -> Vec<String> {
    let stmt = c.prepare("SELECT * FROM pg_logical_slot_peek_changes('slot', NULL, NULL)").unwrap();
    let mut result = vec![];
    for r in stmt.query(&[]).unwrap() {
        result.push(r.get(2));
    }
    result
}

fn create_slot(c: &Connection) {
    let stmt = c.prepare("select * from pg_create_logical_replication_slot('slot', 'thingy')").unwrap();
    stmt.execute(&[]).unwrap();
}

fn drop_slot(c: &Connection) {
    let stmt = c.prepare("select pg_drop_replication_slot('slot')").unwrap();
    match stmt.execute(&[]) {
        _ => {},
    }
}

fn with_slot<F>(f: F) where F:Fn(&Connection) -> () {
    with_clean_database(|c| {
        drop_slot(c);
        create_slot(c);
        f(c);
        drop_slot(c);
    });
}

fn with_clean_database<F>(f: F) where F:Fn(&Connection) -> () {
    let c = connection();
    reset_database(&c);
    f(&c);
    drop_database(&c);
}

fn reset_database(c: &Connection) {
    drop_database(&c);
    create_database(&c);
}

fn create_database(c: &Connection) {
    let stmt = c.prepare("create table test_table (id int primary key, name text)").unwrap();
    stmt.execute(&[]).unwrap();
}

fn fetch_records(c: &Connection) -> Vec<TestRecord> {
    let stmt = c.prepare("select id, name from test_table").unwrap();
    let results = stmt.query(&[]).unwrap();
    results.iter().map(|r| {
        TestRecord {
            id:   r.get(0),
            name: r.get(1),
        }
    }).collect()
}

fn create_record(c: &Connection, r: &TestRecord) {
    let stmt = c.prepare("insert into test_table (id, name) values ($1, $2)").unwrap();
    stmt.execute(&[
        &r.id,
        &r.name,
    ]).unwrap();
}

fn delete_record(c: &Connection, id: i32) {
    let stmt = c.prepare("delete from test_table where id = $1").unwrap();
    stmt.execute(&[&id]).unwrap();
}

fn update_record(c: &Connection, new_record: TestRecord) {
    let stmt = c.prepare("update test_table set name = $2 where id = $1").unwrap();
    stmt.execute(&[&new_record.id, &new_record.name]).unwrap();
}

fn drop_database(c: &Connection) {
    let stmt = c.prepare("drop table if exists test_table").unwrap();
    stmt.execute(&[]).unwrap();
}

fn connection_string() -> String {
    match std::env::var("POSTGRES_URL") {
        Ok(val) => val,
        Err(e)  => panic!(format!("You must set the POSTGRES_URL environment variable to point to a running Postgres test database when running automated tests: {}", e)),
    }
}

fn connection() -> Connection {
    match Connection::connect(&connection_string()[..], &SslMode::None) {
        Ok(c)  => c,
        Err(e) => panic!(format!("Could not connect to the test database: {}", e)),
    }
}
<|endoftext|>