<commit_before>use hb;

/// A type to represent 4 byte tags that are used in many font formats for naming font tables,
/// font features and similar.
///
/// The user-facing representation is a 4-character ASCII string. `Tag` provides methods to create
/// `Tag`s from such a representation and to get the string representation from a `Tag`.
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct Tag(pub hb::hb_tag_t);

impl Tag {
    /// Create a `Tag` from its four-char textual representation.
    ///
    /// # Examples
    ///
    /// ```
    /// use harfbuzz_rs::Tag;
    /// let cmap_tag = Tag::new('c', 'm', 'a', 'p');
    /// assert_eq!(cmap_tag.to_string(), "cmap")
    /// ```
    ///
    pub fn new(a: char, b: char, c: char, d: char) -> Self {
        Tag(((a as u32) << 24) | ((b as u32) << 16) | ((c as u32) << 8) | (d as u32))
    }

    fn tag_to_string(self) -> String {
        let mut buf: [u8; 4] = [0; 4];
        unsafe { hb::hb_tag_to_string(self.0, buf.as_mut_ptr() as *mut _) };
        String::from_utf8_lossy(&buf).into()
    }
}

use std::fmt;
use std::fmt::{Debug, Display, Formatter};
impl Debug for Tag {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let string = self.tag_to_string();
        let mut chars = string.chars().chain(std::iter::repeat('\u{FFFD}'));
        write!(f,
               "Tag({:?}, {:?}, {:?}, {:?})",
               chars.next().unwrap(),
               chars.next().unwrap(),
               chars.next().unwrap(),
               chars.next().unwrap())
    }
}

impl Display for Tag {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{}", self.tag_to_string())
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// An Error generated when a `Tag` fails to parse from a `&str` with the `from_str` function.
pub enum TagFromStrErr {
    /// The string contains non-ASCII characters.
    NonAscii,
    /// The string has length zero.
    ZeroLengthString,
}

use std;
use std::str::FromStr;
use std::ascii::AsciiExt;

impl FromStr for Tag {
    type Err = TagFromStrErr;
    /// Parses a `Tag` from a `&str` that contains four or less ASCII characters. When the string's
    /// length is smaller than 4 it is extended with `' '` (Space) characters. The remaining bytes
    /// of strings longer than 4 bytes are ignored.
    ///
    /// # Examples
    ///
    /// ```
    /// use harfbuzz_rs::Tag;
    /// use std::str::FromStr;
    /// let tag1 = Tag::from_str("ABCD").unwrap();
    /// let tag2 = Tag::new('A', 'B', 'C', 'D');
    /// assert_eq!(tag1, tag2);
    /// ```
    ///
    fn from_str(s: &str) -> Result<Tag, TagFromStrErr> {
        if s.is_ascii() == false {
            return Err(TagFromStrErr::NonAscii);
        }
        if s.len() == 0 {
            return Err(TagFromStrErr::ZeroLengthString);
        }
        let len = std::cmp::max(s.len(), 4) as i32;
        unsafe { Ok(Tag(hb::hb_tag_from_string(s.as_ptr() as *mut _, len))) }
    }
}

/// All trait all wrappers for harfbuzz objects implement. It exposes common functionality for
/// converting from and to the underlying raw harfbuzz pointers.
pub trait HarfbuzzObject: Clone {
    /// Type of the raw harfbuzz object pointer;
    type Raw;

    /// Creates a value safely wrapping the raw harfbuzz pointer. Transfers ownership. _Use of the
    /// original pointer is now forbidden!_ Unsafe because a dereference of a raw pointer is
    /// necesarry.
    unsafe fn from_raw(val: Self::Raw) -> Self;

    /// Creates a value safely wrapping the raw harfbuzz pointer and references it immediately so
    /// that the existing pointer can still be used as normal. Unsafe because a dereference of a
    /// raw pointer is necesarry.
    unsafe fn from_raw_referenced(val: Self::Raw) -> Self {
        let result = Self::from_raw(val);
        std::mem::forget(result.clone()); // increase reference count
        result
    }

    /// Returns the underlying harfbuzz object pointer. The caller must ensure, that this pointer is
    /// not used after the `self`'s destruction.
    fn as_raw(&self) -> Self::Raw;

    /// Returns the underlying harfbuzz object pointer after referencing the object. The resulting
    /// pointer has to be manually destroyed using `hb_TYPE_destroy` or be converted back into the
    /// wrapper using the `from_raw` function.
    fn as_raw_referenced(&self) -> Self::Raw {
        std::mem::forget(self.clone()); // increase reference count
        self.as_raw()
    }

    /// Converts `self` into the underlying harfbuzz object pointer value. The resulting pointer
    /// has to be manually destroyed using `hb_TYPE_destroy` or be converted back into the wrapper
    /// using the `from_raw` function.
    fn into_raw(self) -> Self::Raw {
        let result = self.as_raw();
        std::mem::forget(self);
        result
    }
}

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

    #[test]
    fn test_tag_debugging() {
        let tag = Tag::from_str("ABCD").unwrap();
        assert_eq!("ABCD", format!("{}", tag));
        assert_eq!("Tag('A', 'B', 'C', 'D')", format!("{:?}", tag));
    }

    #[test]
    fn test_tag_creation() {
        assert!(Tag::from_str("∞BCD").is_err());
        assert!(Tag::from_str("").is_err());
        assert_eq!(Tag::from_str("ABCDE"), Tag::from_str("ABCD"));
        assert_eq!(Tag::from_str("abWd").unwrap(), Tag::new('a', 'b', 'W', 'd'));
    }
}
<commit_msg>Add a wrapper struct for hb_language_t.<commit_after>use hb;

/// A type to represent 4 byte tags that are used in many font formats for naming font tables,
/// font features and similar.
///
/// The user-facing representation is a 4-character ASCII string. `Tag` provides methods to create
/// `Tag`s from such a representation and to get the string representation from a `Tag`.
#[derive(Copy, Clone, Hash, PartialEq, Eq)]
pub struct Tag(pub hb::hb_tag_t);

impl Tag {
    /// Create a `Tag` from its four-char textual representation.
    ///
    /// # Examples
    ///
    /// ```
    /// use harfbuzz_rs::Tag;
    /// let cmap_tag = Tag::new('c', 'm', 'a', 'p');
    /// assert_eq!(cmap_tag.to_string(), "cmap")
    /// ```
    ///
    pub fn new(a: char, b: char, c: char, d: char) -> Self {
        Tag(((a as u32) << 24) | ((b as u32) << 16) | ((c as u32) << 8) | (d as u32))
    }

    fn tag_to_string(self) -> String {
        let mut buf: [u8; 4] = [0; 4];
        unsafe { hb::hb_tag_to_string(self.0, buf.as_mut_ptr() as *mut _) };
        String::from_utf8_lossy(&buf).into()
    }
}

use std::fmt;
use std::fmt::{Debug, Display, Formatter};
impl Debug for Tag {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let string = self.tag_to_string();
        let mut chars = string.chars().chain(std::iter::repeat('\u{FFFD}'));
        write!(f,
               "Tag({:?}, {:?}, {:?}, {:?})",
               chars.next().unwrap(),
               chars.next().unwrap(),
               chars.next().unwrap(),
               chars.next().unwrap())
    }
}

impl Display for Tag {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "{}", self.tag_to_string())
    }
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
/// An Error generated when a `Tag` fails to parse from a `&str` with the `from_str` function.
pub enum TagFromStrErr {
    /// The string contains non-ASCII characters.
    NonAscii,
    /// The string has length zero.
    ZeroLengthString,
}

use std;
use std::str::FromStr;
use std::ascii::AsciiExt;

impl FromStr for Tag {
    type Err = TagFromStrErr;
    /// Parses a `Tag` from a `&str` that contains four or less ASCII characters. When the string's
    /// length is smaller than 4 it is extended with `' '` (Space) characters. The remaining bytes
    /// of strings longer than 4 bytes are ignored.
    ///
    /// # Examples
    ///
    /// ```
    /// use harfbuzz_rs::Tag;
    /// use std::str::FromStr;
    /// let tag1 = Tag::from_str("ABCD").unwrap();
    /// let tag2 = Tag::new('A', 'B', 'C', 'D');
    /// assert_eq!(tag1, tag2);
    /// ```
    ///
    fn from_str(s: &str) -> Result<Tag, TagFromStrErr> {
        if s.is_ascii() == false {
            return Err(TagFromStrErr::NonAscii);
        }
        if s.len() == 0 {
            return Err(TagFromStrErr::ZeroLengthString);
        }
        let len = std::cmp::max(s.len(), 4) as i32;
        unsafe { Ok(Tag(hb::hb_tag_from_string(s.as_ptr() as *mut _, len))) }
    }
}

pub struct Language(hb::hb_language_t);

impl Default for Language {
    fn default() -> Language {
        Language(unsafe { hb::hb_language_get_default() })
    }
}

impl Debug for Language {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        write!(f, "Language(\"{}\")", self)
    }
}

use std::ffi::CStr;
impl Display for Language {
    fn fmt(&self, f: &mut Formatter) -> fmt::Result {
        let string = unsafe {
            let char_ptr = hb::hb_language_to_string(self.0);
            CStr::from_ptr(char_ptr)
                .to_str()
                .expect("String representation of language is not valid utf8.")
        };
        write!(f, "{}", string)
    }
}

pub struct InvalidLanguage;

impl FromStr for Language {
    type Err = InvalidLanguage;
    fn from_str(s: &str) -> Result<Language, InvalidLanguage> {
        let len = std::cmp::max(s.len(), std::i32::MAX as _) as i32;
        let lang = unsafe { hb::hb_language_from_string(s.as_ptr() as *mut _, len) };
        if lang.is_null() {
            Err(InvalidLanguage {})
        } else {
            Ok(Language(lang))
        }
    }
}

/// All trait all wrappers for harfbuzz objects implement. It exposes common functionality for
/// converting from and to the underlying raw harfbuzz pointers.
pub trait HarfbuzzObject: Clone {
    /// Type of the raw harfbuzz object pointer;
    type Raw;

    /// Creates a value safely wrapping the raw harfbuzz pointer. Transfers ownership. _Use of the
    /// original pointer is now forbidden!_ Unsafe because a dereference of a raw pointer is
    /// necesarry.
    unsafe fn from_raw(val: Self::Raw) -> Self;

    /// Creates a value safely wrapping the raw harfbuzz pointer and references it immediately so
    /// that the existing pointer can still be used as normal. Unsafe because a dereference of a
    /// raw pointer is necesarry.
    unsafe fn from_raw_referenced(val: Self::Raw) -> Self {
        let result = Self::from_raw(val);
        std::mem::forget(result.clone()); // increase reference count
        result
    }

    /// Returns the underlying harfbuzz object pointer. The caller must ensure, that this pointer is
    /// not used after the `self`'s destruction.
    fn as_raw(&self) -> Self::Raw;

    /// Returns the underlying harfbuzz object pointer after referencing the object. The resulting
    /// pointer has to be manually destroyed using `hb_TYPE_destroy` or be converted back into the
    /// wrapper using the `from_raw` function.
    fn as_raw_referenced(&self) -> Self::Raw {
        std::mem::forget(self.clone()); // increase reference count
        self.as_raw()
    }

    /// Converts `self` into the underlying harfbuzz object pointer value. The resulting pointer
    /// has to be manually destroyed using `hb_TYPE_destroy` or be converted back into the wrapper
    /// using the `from_raw` function.
    fn into_raw(self) -> Self::Raw {
        let result = self.as_raw();
        std::mem::forget(self);
        result
    }
}

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

    #[test]
    fn test_tag_debugging() {
        let tag = Tag::from_str("ABCD").unwrap();
        assert_eq!("ABCD", format!("{}", tag));
        assert_eq!("Tag('A', 'B', 'C', 'D')", format!("{:?}", tag));
    }

    #[test]
    fn test_tag_creation() {
        assert!(Tag::from_str("∞BCD").is_err());
        assert!(Tag::from_str("").is_err());
        assert_eq!(Tag::from_str("ABCDE"), Tag::from_str("ABCD"));
        assert_eq!(Tag::from_str("abWd").unwrap(), Tag::new('a', 'b', 'W', 'd'));
    }
}
<|endoftext|>


<commit_before>use libc;
use std;
use sys;
use sys::{VALUE};
use std::ffi::CString;

use super::{UncheckedValue, CheckResult, CheckedValue, ToRust, ToRuby};

// VALUE -> to_coercible_rust<String> -> CheckResult<String> -> unwrap() -> Coercible<String> -> to_rust() -> String

impl UncheckedValue<String> for VALUE {
    fn to_checked(self) -> CheckResult<String> {
        if unsafe { sys::RB_TYPE_P(self, sys::T_STRING) } {
            Ok(unsafe { CheckedValue::<String>::new(self) })
        } else {
            Err(CString::new(format!("No implicit conversion from {} to String", "?")).unwrap())
        }
    }
}

impl ToRust<String> for CheckedValue<String> {
    fn to_rust(self) -> String {
        let size = unsafe { sys::RSTRING_LEN(self.inner) };
        let ptr = unsafe { sys::RSTRING_PTR(self.inner) };
        let slice = unsafe { std::slice::from_raw_parts(ptr as *const u8, size as usize) };
        unsafe { std::str::from_utf8_unchecked(slice) }.to_string()
    }
}

impl ToRuby for String {
    fn to_ruby(self) -> VALUE {
        let ptr = self.as_ptr();
        let len = self.len();
        unsafe { sys::rb_utf8_str_new(ptr as *const libc::c_char, len as libc::c_long) }
    }
}
<commit_msg>Improve error message for String conversion<commit_after>use libc;
use std;
use sys;
use sys::{VALUE};
use std::ffi::CString;

use super::{UncheckedValue, CheckResult, CheckedValue, ToRust, ToRuby};

// VALUE -> to_coercible_rust<String> -> CheckResult<String> -> unwrap() -> Coercible<String> -> to_rust() -> String

impl UncheckedValue<String> for VALUE {
    fn to_checked(self) -> CheckResult<String> {
        if unsafe { sys::RB_TYPE_P(self, sys::T_STRING) } {
            Ok(unsafe { CheckedValue::<String>::new(self) })
        } else {
            let val = unsafe { CheckedValue::<String>::new(sys::rb_inspect(self)) };
            Err(CString::new(format!("No implicit conversion from {} to String", val.to_rust())).unwrap())
        }
    }
}

impl ToRust<String> for CheckedValue<String> {
    fn to_rust(self) -> String {
        let size = unsafe { sys::RSTRING_LEN(self.inner) };
        let ptr = unsafe { sys::RSTRING_PTR(self.inner) };
        let slice = unsafe { std::slice::from_raw_parts(ptr as *const u8, size as usize) };
        unsafe { std::str::from_utf8_unchecked(slice) }.to_string()
    }
}

impl ToRuby for String {
    fn to_ruby(self) -> VALUE {
        let ptr = self.as_ptr();
        let len = self.len();
        unsafe { sys::rb_utf8_str_new(ptr as *const libc::c_char, len as libc::c_long) }
    }
}
<|endoftext|>


<commit_before>extern crate fsevent;
use std::sync::mpsc::channel;
use std::thread;

#[allow(dead_code)]
fn main() {
  let (sender, receiver) = channel();

  let _t = thread::spawn(move || {
    let fsevent = fsevent::FsEvent::new(sender);
    fsevent.append_path("../../");
    fsevent.observe();
  });

  loop {
    select! (
      val = receiver.recv() => {
        println!("{:?}", val.unwrap());
      }
    )
  }
}
<commit_msg>Remove select and fix sample code<commit_after>extern crate fsevent;
use std::sync::mpsc::channel;
use std::thread;

fn main() {
  let (sender, receiver) = channel();

  let _t = thread::spawn(move || {
    let fsevent = fsevent::FsEvent::new(sender);
    fsevent.append_path("../../");
    fsevent.observe();
  });

  loop {
    let val = receiver.recv();
    println!("{:?}", val.unwrap());
  }
}
<|endoftext|>


<commit_before>/*
ゴール：
- コンパイルし、実行してください
- worldを自分の名前に置き換えてみてください
- 変数 name を導入してみましょう
- println!("{}", name)を試しください
- println!("{}", name)とprintln!("{:?}", name)の違いを確認してください
- greetingsを呼ぶように変更してください
*/
#![allow(dead_code)]

fn main() {
    println!("Hello, world!");
    //greetings(name);
}

fn greetings(name: String) {
    println!("Hello, {}!", name);
}

<commit_msg>editorial update<commit_after>/*
ゴール：
1. コンパイルし、実行してください
2. worldを自分の名前に置き換えてみてください
3. 変数 name を使って2を実現してください
4. println!("{}", name)を試しください
5. println!("{}", name)とprintln!("{:?}", name)の違いを確認してください
6. greetingsを呼ぶように変更してください
*/
#![allow(dead_code)]

fn main() {
    println!("Hello, world!");
    //greetings(name);
}

fn greetings(name: String) {
    println!("Hello, {}!", name);
}

<|endoftext|>


<commit_before>//! To see how color numbers map to actual colors in your terminal run
//! `cargo run --example colors`. Use tab to swap fg/bg colors.

use yaml_rust::Yaml;
use yaml_rust::YamlLoader;

use std::env::home_dir;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;

#[derive(Debug, Clone)]
pub struct Server {
    /// Address of the server
    pub server_addr: String,

    /// Port of the server
    pub server_port: u16,

    /// Hostname to be used in connection registration
    pub hostname: String,

    /// Real name to be used in connection registration
    pub real_name: String,

    /// Nicks to try when connecting to this server. tiny tries these sequentially, and starts
    /// adding trailing underscores to the last one if none of the nicks are available.
    pub nicks: Vec<String>,

    /// Commands to automatically run after joining to the server. Useful for e.g. registering the
    /// nick via nickserv or joining channels. Uses tiny command syntax.
    pub auto_cmds: Vec<String>,
}

/// Similar to `Server`, but used when connecting via the `/connect` command.
#[derive(Debug, Clone)]
pub struct Defaults {
    pub nicks: Vec<String>,
    pub hostname: String,
    pub realname: String,
    pub auto_cmds: Vec<String>
}

pub fn get_defaults() -> Defaults {
    Defaults {
        nicks: vec!["tiny_user".to_owned()],
        hostname: "tiny".to_owned(),
        realname: "anonymous tiny user".to_owned(),
        auto_cmds: vec![],
    }
}

fn get_config_path() -> PathBuf {
    let mut config_path = home_dir().unwrap();
    config_path.push(".tinyrc.yaml");
    config_path
}

pub fn read_config() -> Option<(Vec<Server>, Defaults)> {

    // sigh ... what a mess

    let config_str = {
        let config_path = get_config_path();
        if !config_path.exists() { return None; }
        let mut config_file = File::open(get_config_path()).unwrap();
        let mut config_str = String::new();
        config_file.read_to_string(&mut config_str).unwrap();
        config_str
    };

    let config_yaml = YamlLoader::load_from_str(&config_str).unwrap();

    let servers_yaml: &Yaml =
        config_yaml[0].as_hash().unwrap()
            .get(&Yaml::String("servers".to_owned())).unwrap();
                // duh, allocation for lookup

    let defaults_yaml: &Yaml =
        config_yaml[0].as_hash().unwrap()
            .get(&Yaml::String("defaults".to_owned())).unwrap();

    let mut servers = vec![];

    let yaml_addr_key = Yaml::String("addr".to_owned());
    let yaml_port_key = Yaml::String("port".to_owned());
    let yaml_hostname_key = Yaml::String("hostname".to_owned());
    let yaml_realname_key = Yaml::String("realname".to_owned());
    let yaml_nicks_key = Yaml::String("nicks".to_owned());
    let yaml_auto_cmds_key = Yaml::String("auto_cmds".to_owned());

    for server in servers_yaml.as_vec().unwrap().into_iter() {
        let server_hash = server.as_hash().unwrap();
        let server_addr =
            server_hash.get(&yaml_addr_key).unwrap().as_str().unwrap().to_owned();
        let server_port =
            server_hash.get(&yaml_port_key).unwrap().as_i64().unwrap().to_owned() as u16;
        let hostname =
            server_hash.get(&yaml_hostname_key).unwrap().as_str().unwrap().to_owned();
        let real_name =
            server_hash.get(&yaml_realname_key).unwrap().as_str().unwrap().to_owned();
        let nicks: Vec<String> =
            server_hash.get(&yaml_nicks_key).unwrap().as_vec().unwrap()
                .into_iter().map(|s| s.as_str().unwrap().to_owned()).collect();
        let auto_cmds: Vec<String> =
            server_hash.get(&yaml_auto_cmds_key).unwrap().as_vec().unwrap()
                .into_iter().map(|s| s.as_str().unwrap().to_owned()).collect();

        servers.push(Server {
            server_addr, server_port, hostname, real_name, nicks, auto_cmds
        });
    }

    let defaults = defaults_yaml.as_hash().unwrap();
    let defaults = Defaults {
        nicks: defaults.get(&yaml_nicks_key).unwrap().as_vec().unwrap()
                   .into_iter().map(|s| s.as_str().unwrap().to_owned()).collect(),
        hostname: defaults.get(&yaml_hostname_key).unwrap().as_str().unwrap().to_owned(),
        realname: defaults.get(&yaml_realname_key).unwrap().as_str().unwrap().to_owned(),
        auto_cmds: defaults.get(&yaml_auto_cmds_key).unwrap().as_vec().unwrap()
                       .into_iter().map(|s| s.as_str().unwrap().to_owned()).collect(),
    };

    Some((servers, defaults))
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Colors
////////////////////////////////////////////////////////////////////////////////////////////////////

/// Colors used to highlight nicks
pub static NICK_COLORS: [u8; 15] =
    [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ];

pub use termbox_simple::*;

#[derive(Debug, Clone, Copy)]
pub struct Style {
    /// Termbox fg.
    pub fg: u16,

    /// Termbox bg.
    pub bg: u16,
}

pub const CLEAR: Style =
    Style {
        fg: TB_DEFAULT,
        bg: TB_DEFAULT,
    };

pub const USER_MSG: Style =
    Style {
        fg: 15,
        bg: TB_DEFAULT,
    };

pub const ERR_MSG: Style =
    Style {
        fg: 15 | TB_BOLD,
        bg: 1,
    };

pub const TOPIC: Style =
    Style {
        fg: 14 | TB_BOLD,
        bg: TB_DEFAULT,
    };

pub const CURSOR: Style =
    USER_MSG;

pub const JOIN: Style =
    Style {
        fg: 242,
        bg: TB_DEFAULT,
    };

pub const PART: Style =
    Style {
        fg: 242,
        bg: TB_DEFAULT,
    };

pub const NICK: Style =
    Style {
        fg: 242,
        bg: TB_DEFAULT,
    };

pub const EXIT_DIALOGUE: Style =
    Style {
        fg: TB_DEFAULT,
        bg: 4,
    };

pub const HIGHLIGHT: Style =
    Style {
        fg: 9 | TB_BOLD,
        bg: TB_DEFAULT,
    };

// Currently unused
// pub const MENTION: Style =
//     Style {
//         fg: 220,
//         bg: TB_DEFAULT,
//     };

pub const COMPLETION: Style =
    Style {
        fg: 84,
        bg: TB_DEFAULT,
    };

pub const TIMESTAMP: Style =
    Style {
        fg: 15 | TB_BOLD,
        bg: TB_DEFAULT,
    };

pub const TAB_ACTIVE: Style =
    Style {
        fg: 15 | TB_BOLD,
        bg: 0,
    };

pub const TAB_NORMAL: Style =
    Style {
        fg: 8,
        bg: 0,
    };

pub const TAB_IMPORTANT: Style =
    Style {
        fg: 9 | TB_BOLD,
        bg: 0,
    };

pub const TAB_HIGHLIGHT: Style =
    Style {
        fg: 5,
        bg: 0,
    };
<commit_msg>Change config file extension to .yml<commit_after>//! To see how color numbers map to actual colors in your terminal run
//! `cargo run --example colors`. Use tab to swap fg/bg colors.

use yaml_rust::Yaml;
use yaml_rust::YamlLoader;

use std::env::home_dir;
use std::fs::File;
use std::io::Read;
use std::path::PathBuf;

#[derive(Debug, Clone)]
pub struct Server {
    /// Address of the server
    pub server_addr: String,

    /// Port of the server
    pub server_port: u16,

    /// Hostname to be used in connection registration
    pub hostname: String,

    /// Real name to be used in connection registration
    pub real_name: String,

    /// Nicks to try when connecting to this server. tiny tries these sequentially, and starts
    /// adding trailing underscores to the last one if none of the nicks are available.
    pub nicks: Vec<String>,

    /// Commands to automatically run after joining to the server. Useful for e.g. registering the
    /// nick via nickserv or joining channels. Uses tiny command syntax.
    pub auto_cmds: Vec<String>,
}

/// Similar to `Server`, but used when connecting via the `/connect` command.
#[derive(Debug, Clone)]
pub struct Defaults {
    pub nicks: Vec<String>,
    pub hostname: String,
    pub realname: String,
    pub auto_cmds: Vec<String>
}

pub fn get_defaults() -> Defaults {
    Defaults {
        nicks: vec!["tiny_user".to_owned()],
        hostname: "tiny".to_owned(),
        realname: "anonymous tiny user".to_owned(),
        auto_cmds: vec![],
    }
}

fn get_config_path() -> PathBuf {
    let mut config_path = home_dir().unwrap();
    config_path.push(".tinyrc.yml");
    config_path
}

pub fn read_config() -> Option<(Vec<Server>, Defaults)> {

    // sigh ... what a mess

    let config_str = {
        let config_path = get_config_path();
        if !config_path.exists() { return None; }
        let mut config_file = File::open(get_config_path()).unwrap();
        let mut config_str = String::new();
        config_file.read_to_string(&mut config_str).unwrap();
        config_str
    };

    let config_yaml = YamlLoader::load_from_str(&config_str).unwrap();

    let servers_yaml: &Yaml =
        config_yaml[0].as_hash().unwrap()
            .get(&Yaml::String("servers".to_owned())).unwrap();
                // duh, allocation for lookup

    let defaults_yaml: &Yaml =
        config_yaml[0].as_hash().unwrap()
            .get(&Yaml::String("defaults".to_owned())).unwrap();

    let mut servers = vec![];

    let yaml_addr_key = Yaml::String("addr".to_owned());
    let yaml_port_key = Yaml::String("port".to_owned());
    let yaml_hostname_key = Yaml::String("hostname".to_owned());
    let yaml_realname_key = Yaml::String("realname".to_owned());
    let yaml_nicks_key = Yaml::String("nicks".to_owned());
    let yaml_auto_cmds_key = Yaml::String("auto_cmds".to_owned());

    for server in servers_yaml.as_vec().unwrap().into_iter() {
        let server_hash = server.as_hash().unwrap();
        let server_addr =
            server_hash.get(&yaml_addr_key).unwrap().as_str().unwrap().to_owned();
        let server_port =
            server_hash.get(&yaml_port_key).unwrap().as_i64().unwrap().to_owned() as u16;
        let hostname =
            server_hash.get(&yaml_hostname_key).unwrap().as_str().unwrap().to_owned();
        let real_name =
            server_hash.get(&yaml_realname_key).unwrap().as_str().unwrap().to_owned();
        let nicks: Vec<String> =
            server_hash.get(&yaml_nicks_key).unwrap().as_vec().unwrap()
                .into_iter().map(|s| s.as_str().unwrap().to_owned()).collect();
        let auto_cmds: Vec<String> =
            server_hash.get(&yaml_auto_cmds_key).unwrap().as_vec().unwrap()
                .into_iter().map(|s| s.as_str().unwrap().to_owned()).collect();

        servers.push(Server {
            server_addr, server_port, hostname, real_name, nicks, auto_cmds
        });
    }

    let defaults = defaults_yaml.as_hash().unwrap();
    let defaults = Defaults {
        nicks: defaults.get(&yaml_nicks_key).unwrap().as_vec().unwrap()
                   .into_iter().map(|s| s.as_str().unwrap().to_owned()).collect(),
        hostname: defaults.get(&yaml_hostname_key).unwrap().as_str().unwrap().to_owned(),
        realname: defaults.get(&yaml_realname_key).unwrap().as_str().unwrap().to_owned(),
        auto_cmds: defaults.get(&yaml_auto_cmds_key).unwrap().as_vec().unwrap()
                       .into_iter().map(|s| s.as_str().unwrap().to_owned()).collect(),
    };

    Some((servers, defaults))
}

////////////////////////////////////////////////////////////////////////////////////////////////////
// Colors
////////////////////////////////////////////////////////////////////////////////////////////////////

/// Colors used to highlight nicks
pub static NICK_COLORS: [u8; 15] =
    [ 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15 ];

pub use termbox_simple::*;

#[derive(Debug, Clone, Copy)]
pub struct Style {
    /// Termbox fg.
    pub fg: u16,

    /// Termbox bg.
    pub bg: u16,
}

pub const CLEAR: Style =
    Style {
        fg: TB_DEFAULT,
        bg: TB_DEFAULT,
    };

pub const USER_MSG: Style =
    Style {
        fg: 15,
        bg: TB_DEFAULT,
    };

pub const ERR_MSG: Style =
    Style {
        fg: 15 | TB_BOLD,
        bg: 1,
    };

pub const TOPIC: Style =
    Style {
        fg: 14 | TB_BOLD,
        bg: TB_DEFAULT,
    };

pub const CURSOR: Style =
    USER_MSG;

pub const JOIN: Style =
    Style {
        fg: 242,
        bg: TB_DEFAULT,
    };

pub const PART: Style =
    Style {
        fg: 242,
        bg: TB_DEFAULT,
    };

pub const NICK: Style =
    Style {
        fg: 242,
        bg: TB_DEFAULT,
    };

pub const EXIT_DIALOGUE: Style =
    Style {
        fg: TB_DEFAULT,
        bg: 4,
    };

pub const HIGHLIGHT: Style =
    Style {
        fg: 9 | TB_BOLD,
        bg: TB_DEFAULT,
    };

// Currently unused
// pub const MENTION: Style =
//     Style {
//         fg: 220,
//         bg: TB_DEFAULT,
//     };

pub const COMPLETION: Style =
    Style {
        fg: 84,
        bg: TB_DEFAULT,
    };

pub const TIMESTAMP: Style =
    Style {
        fg: 15 | TB_BOLD,
        bg: TB_DEFAULT,
    };

pub const TAB_ACTIVE: Style =
    Style {
        fg: 15 | TB_BOLD,
        bg: 0,
    };

pub const TAB_NORMAL: Style =
    Style {
        fg: 8,
        bg: 0,
    };

pub const TAB_IMPORTANT: Style =
    Style {
        fg: 9 | TB_BOLD,
        bg: 0,
    };

pub const TAB_HIGHLIGHT: Style =
    Style {
        fg: 5,
        bg: 0,
    };
<|endoftext|>


<commit_before>use std::io::prelude::*;
use std::fs::File;
use docopt::Docopt;
use toml;

use gobjects;

static USAGE: &'static str = "
Usage: gir [-d <girs_dir>] [-o <target_path>] [<library> <version>]

Options:
    -d PATH             Directory for girs
    -o PATH             Target root path
";

#[derive(Debug)]
pub struct Config {
    pub girs_dir: String,
    pub library_name: String,
    pub library_version: String,
    pub target_path: String,
    pub objects: gobjects::GObjects,
}

impl Config {
    pub fn new() -> Config {
        let args = Docopt::new(USAGE).unwrap()
            .parse().unwrap_or_else(|e| e.exit());

        let toml = read_toml("Gir.toml");

        let girs_dir = match args.get_str("-d") {
            "" => toml.lookup("options.girs_dir")
                      .unwrap_or_else(|| panic!("No options.girs_dir in config"))
                      .as_str().unwrap(),
            a => a
        };

        let library_name = match args.get_str("<library>") {
            "" => toml.lookup("options.library")
                    .unwrap_or_else(|| panic!("No options.library in config"))
                    .as_str().unwrap(),
            a => a
        };

        let library_version = match args.get_str("<version>") {
            "" => toml.lookup("options.version")
                    .unwrap_or_else(|| panic!("No options.version in config"))
                    .as_str().unwrap(),
            a => a
        };

        let target_path = match args.get_str("-o") {
            "" => toml.lookup("options.target_path")
                    .unwrap_or_else(|| panic!("No options.target_path in config"))
                    .as_str().unwrap(),
            a => a
        };

        let objects = gobjects::parse_toml(toml.lookup("object").unwrap());

        Config {
            girs_dir: girs_dir.into(),
            library_name: library_name.into(),
            library_version: library_version.into(),
            target_path: target_path.into(),
            objects: objects,
        }
    }

    pub fn library_full_name(&self) -> String {
        format!("{}-{}", self.library_name, self.library_version)
    }
}

fn read_toml(filename: &str) -> toml::Value {
    let mut input = String::new();
    File::open(filename).and_then(|mut f| {
        f.read_to_string(&mut input)
    }).unwrap();
    let mut parser = toml::Parser::new(&input);
    match parser.parse() {
        Some(toml) => toml::Value::Table(toml),
        None => {
            for err in &parser.errors {
                let (loline, locol) = parser.to_linecol(err.lo);
                let (hiline, hicol) = parser.to_linecol(err.hi);
                println!("{}:{}:{}-{}:{} error: {}",
                         filename, loline, locol, hiline, hicol, err.desc);
            }
            panic!("Errors in config")
        }
    }
}
<commit_msg>Fix command line parsing<commit_after>use std::io::prelude::*;
use std::fs::File;
use docopt::Docopt;
use toml;

use gobjects;

static USAGE: &'static str = "
Usage: gir [options] [<library> <version>]

Options:
    -d PATH             Directory for girs
    -o PATH             Target root path
";

#[derive(Debug)]
pub struct Config {
    pub girs_dir: String,
    pub library_name: String,
    pub library_version: String,
    pub target_path: String,
    pub objects: gobjects::GObjects,
}

impl Config {
    pub fn new() -> Config {
        let args = Docopt::new(USAGE)
            .and_then(|dopt| dopt.parse())
            .unwrap_or_else(|e| e.exit());

        let toml = read_toml("Gir.toml");

        let girs_dir = match args.get_str("-d") {
            "" => toml.lookup("options.girs_dir")
                      .unwrap_or_else(|| panic!("No options.girs_dir in config"))
                      .as_str().unwrap(),
            a => a
        };

        let (library_name, library_version) =
            match (args.get_str("<library>"), args.get_str("<version>")) {
            ("", "") => (
                toml.lookup("options.library")
                    .unwrap_or_else(|| panic!("No options.library in config"))
                    .as_str().unwrap(),
                toml.lookup("options.version")
                    .unwrap_or_else(|| panic!("No options.version in config"))
                    .as_str().unwrap()
            ),
            ("", _) | (_, "") => panic!("Library and version can not be specified separately"),
            (a, b) => (a, b)
        };

        let target_path = match args.get_str("-o") {
            "" => toml.lookup("options.target_path")
                    .unwrap_or_else(|| panic!("No options.target_path in config"))
                    .as_str().unwrap(),
            a => a
        };

        let objects = gobjects::parse_toml(toml.lookup("object").unwrap());

        Config {
            girs_dir: girs_dir.into(),
            library_name: library_name.into(),
            library_version: library_version.into(),
            target_path: target_path.into(),
            objects: objects,
        }
    }

    pub fn library_full_name(&self) -> String {
        format!("{}-{}", self.library_name, self.library_version)
    }
}

fn read_toml(filename: &str) -> toml::Value {
    let mut input = String::new();
    File::open(filename).and_then(|mut f| {
        f.read_to_string(&mut input)
    }).unwrap();
    let mut parser = toml::Parser::new(&input);
    match parser.parse() {
        Some(toml) => toml::Value::Table(toml),
        None => {
            for err in &parser.errors {
                let (loline, locol) = parser.to_linecol(err.lo);
                let (hiline, hicol) = parser.to_linecol(err.hi);
                println!("{}:{}:{}-{}:{} error: {}",
                         filename, loline, locol, hiline, hicol, err.desc);
            }
            panic!("Errors in config")
        }
    }
}
<|endoftext|>


<commit_before>use utils;
use buffer::Link;

pub enum Direction {
    Up,
    Down,
    Left,
    Right,
}

#[deriving(Clone)]
pub struct Cursor {
    pub x: uint,
    pub y: uint,

    pub line: Link,
}

impl Cursor {
    pub fn new() -> Cursor {
        Cursor {
            x: 0,
            y: 0,
            line: None,
        }
    }

    pub fn draw(&self) {
        utils::draw_cursor(self.x, self.y);
    }

    pub fn adjust(&mut self, direction: Direction) {
        let mut line = self.line.clone().unwrap();
        match direction {
            Up => {
                let prev_line = line.prev.resolve().map(|prev| prev);
                if prev_line.is_some() {
                    self.line = Some(box prev_line.unwrap().clone());
                    self.y -= 1
                }
            },
            Down => {
                if line.next.is_some() {
                    self.y += 1;
                    self.line = line.next;
                }
            },
            Left => {
                if self.x > 0 {
                    self.x -= 1
                }
            },
            Right => {
                if self.x < line.len() {
                    self.x += 1
                }
            },
        }
    }
}
<commit_msg>Refactor cursor module<commit_after>use utils;
use buffer::{Line, Link};

pub enum Direction {
    Up,
    Down,
    Left,
    Right,
}

#[deriving(Clone)]
pub struct Cursor {
    pub x: uint,
    pub y: uint,

    pub line: Link,
}

impl Cursor {
    /// Create a new cursor instance
    pub fn new() -> Cursor {
        Cursor {
            x: 0,
            y: 0,
            line: None,
        }
    }

    /// Draw the cursor based on the `x` and `y` values
    pub fn draw(&self) {
        utils::draw_cursor(self.x, self.y);
    }

    /// Adjust the cursor position
    pub fn adjust(&mut self, direction: Direction) {
        match direction {
            Up => { self.move_up() },
            Down => { self.move_down() },
            Left => { self.move_left() },
            Right => { self.move_right() },
        }
    }

    /// Get the current line
    ///
    /// Returns a clone of the line from within the Link structure
    fn get_line(&mut self) -> Box<Line> {
        self.line.clone().unwrap()
    }

    /// Move the cursor up one line
    fn move_up(&mut self) {
        let mut line = self.get_line();

        let prev_line = line.prev.resolve().map(|prev| prev);
        if prev_line.is_some() {
            self.line = Some(box prev_line.unwrap().clone());
            self.y -= 1;
            self.maybe_goto_end_line();
        }
    }

    /// Move the cursor down one line
    fn move_down(&mut self) {
        let line = self.get_line();
        if line.next.is_some() {
            self.y += 1;
            self.line = line.next;
            self.maybe_goto_end_line();
        }

    }

    /// Move the cursor left by one character
    fn move_left(&mut self) {
        if self.x > 0 {
            self.x -= 1
        }
    }

    /// Move the cursor right by one character
    fn move_right(&mut self) {
        let line = self.get_line();
        if self.x < line.len() {
            self.x += 1
        }
    }

    /// Check if the cursors `x` position is greater than the length of the
    /// current line. If so, move it back to the end of the line.
    fn maybe_goto_end_line(&mut self) {
        let line = self.get_line();
        if line.len() < self.x {
            self.goto_end_line();
        }
    }

    fn goto_end_line(&mut self) {
        self.x = self.get_line().len()
    }

}
<|endoftext|>


<commit_before>use crate::{
    table::SchemaContent,
    users::{
        Role,
        User,
    },
    DBPlatform,
    DataError,
    Database,
    DatabaseName,
    DbError,
    Table,
    ToValue,
    Value,
};

use rustorm_dao::{
    FromDao,
    TableName,
    ToColumnNames,
    ToDao,
    ToTableName,
};

pub struct EntityManager(pub DBPlatform);

impl EntityManager {
    pub fn set_session_user(&mut self, username: &str) -> Result<(), DbError> {
        let sql = format!("SET SESSION ROLE '{}'", username);
        self.0.execute_sql_with_return(&sql, &[])?;
        Ok(())
    }

    pub fn get_role(&mut self, username: &str) -> Result<Option<Role>, DbError> {
        let result = self.0.get_roles(username);
        match result {
            Ok(mut result) => {
                match result.len() {
                    0 => Ok(None),
                    1 => Ok(Some(result.remove(0))),
                    _ => Err(DbError::DataError(DataError::MoreThan1RecordReturned)),
                }
            }
            Err(e) => Err(e),
        }
    }

    pub fn db(&mut self) -> &mut dyn Database { &mut *self.0 }

    /// get all the records of this table
    pub fn get_all<T>(&mut self) -> Result<Vec<T>, DbError>
    where
        T: ToTableName + ToColumnNames + FromDao,
    {
        let table = T::to_table_name();
        let columns = T::to_column_names();
        let enumerated_columns = columns
            .iter()
            .map(|c| c.name.to_owned())
            .collect::<Vec<_>>()
            .join(", ");
        let sql = format!(
            "SELECT {} FROM {}",
            enumerated_columns,
            table.complete_name()
        );
        let rows = self.0.execute_sql_with_return(&sql, &[])?;
        let mut entities = vec![];
        for dao in rows.iter() {
            let entity = T::from_dao(&dao);
            entities.push(entity)
        }
        Ok(entities)
    }

    /// get the table from database based on this column name
    pub fn get_table(&mut self, table_name: &TableName) -> Result<Table, DbError> {
        self.0.get_table(table_name)
    }

    /// get all the user table and views from the database
    pub fn get_all_tables(&mut self) -> Result<Vec<Table>, DbError> {
        info!("EXPENSIVE DB OPERATION: get_all_tables");
        self.0.get_all_tables()
    }

    /// Get the total count of records
    pub fn get_total_records(&mut self, table_name: &TableName) -> Result<usize, DbError> {
        #[derive(crate::FromDao)]
        struct Count {
            count: i64,
        }
        let sql = format!(
            "SELECT COUNT(*) AS count FROM {}",
            table_name.complete_name()
        );
        let count: Result<Count, DbError> = self.execute_sql_with_one_return(&sql, &[]);
        count.map(|c| c.count as usize)
    }

    pub fn get_users(&mut self) -> Result<Vec<User>, DbError> { self.0.get_users() }

    pub fn get_database_name(&mut self) -> Result<Option<DatabaseName>, DbError> {
        self.0.get_database_name()
    }

    /// get all table and views grouped per schema
    pub fn get_grouped_tables(&mut self) -> Result<Vec<SchemaContent>, DbError> {
        self.0.get_grouped_tables()
    }

    pub fn insert<T, R>(&mut self, entities: &[&T]) -> Result<Vec<R>, DbError>
    where
        T: ToTableName + ToColumnNames + ToDao,
        R: FromDao + ToColumnNames,
    {
        match self.0 {
            #[cfg(feature = "with-sqlite")]
            DBPlatform::Sqlite(_) => self.insert_simple(entities),
            #[cfg(feature = "with-postgres")]
            DBPlatform::Postgres(_) => self.insert_bulk_with_returning_support(entities),
            #[cfg(feature = "with-mysql")]
            DBPlatform::Mysql(_) => self.insert_simple(entities),
        }
    }

    /// called when the platform used is postgresql
    pub fn insert_bulk_with_returning_support<T, R>(
        &mut self,
        entities: &[&T],
    ) -> Result<Vec<R>, DbError>
    where
        T: ToTableName + ToColumnNames + ToDao,
        R: FromDao + ToColumnNames,
    {
        let columns = T::to_column_names();
        let mut sql = self.build_insert_clause(entities);
        let return_columns = R::to_column_names();
        sql += &self.build_returning_clause(return_columns);

        let mut values: Vec<Value> = Vec::with_capacity(entities.len() * columns.len());
        for entity in entities {
            let dao = entity.to_dao();
            for col in columns.iter() {
                let value = dao.get_value(&col.name);
                match value {
                    Some(value) => values.push(value.clone()),
                    None => values.push(Value::Nil),
                }
            }
        }
        let bvalues: Vec<&Value> = values.iter().collect();
        let rows = self.0.execute_sql_with_return(&sql, &bvalues)?;
        let mut retrieved_entities = vec![];
        for dao in rows.iter() {
            let retrieved = R::from_dao(&dao);
            retrieved_entities.push(retrieved);
        }
        Ok(retrieved_entities)
    }

    /// called multiple times when using database platform that doesn;t support multiple value
    /// insert such as sqlite
    pub fn single_insert<T>(&mut self, entity: &T) -> Result<(), DbError>
    where
        T: ToTableName + ToColumnNames + ToDao,
    {
        let columns = T::to_column_names();
        let sql = self.build_insert_clause(&[entity]);
        let dao = entity.to_dao();
        let mut values: Vec<Value> = Vec::with_capacity(columns.len());
        for col in columns.iter() {
            let value = dao.get_value(&col.name);
            match value {
                Some(value) => values.push(value.clone()),
                None => values.push(Value::Nil),
            }
        }
        let bvalues: Vec<&Value> = values.iter().collect();
        self.0.execute_sql_with_return(&sql, &bvalues)?;
        Ok(())
    }

    /// this is soly for use with sqlite since sqlite doesn't support bulk insert
    pub fn insert_simple<T, R>(&mut self, entities: &[&T]) -> Result<Vec<R>, DbError>
    where
        T: ToTableName + ToColumnNames + ToDao,
        R: FromDao + ToColumnNames,
    {
        let return_columns = R::to_column_names();
        let return_column_names = return_columns
            .iter()
            .map(|rc| rc.name.to_owned())
            .collect::<Vec<_>>()
            .join(", ");

        let table = T::to_table_name();
        //TODO: move this specific query to sqlite
        let last_insert_sql = format!(
            "\
             SELECT {} \
             FROM {} \
             WHERE ROWID = (\
             SELECT LAST_INSERT_ROWID() FROM {})",
            return_column_names,
            table.complete_name(),
            table.complete_name()
        );
        let mut retrieved_entities = vec![];
        println!("sql: {}", last_insert_sql);
        for entity in entities {
            self.single_insert(*entity)?;
            let retrieved = self.execute_sql_with_return(&last_insert_sql, &[])?;
            retrieved_entities.extend(retrieved);
        }
        Ok(retrieved_entities)
    }

    /// build the returning clause
    fn build_returning_clause(&self, return_columns: Vec<rustorm_dao::ColumnName>) -> String {
        format!(
            "\nRETURNING \n{}",
            return_columns
                .iter()
                .map(|rc| rc.name.to_owned())
                .collect::<Vec<_>>()
                .join(", ")
        )
    }

    /// build an insert clause
    fn build_insert_clause<T>(&self, entities: &[&T]) -> String
    where
        T: ToTableName + ToColumnNames + ToDao,
    {
        let table = T::to_table_name();
        let columns = T::to_column_names();
        let columns_len = columns.len();
        let mut sql = String::new();
        sql += &format!("INSERT INTO {} ", table.complete_name());
        sql += &format!(
            "({})\n",
            columns
                .iter()
                .map(|c| c.name.to_owned())
                .collect::<Vec<_>>()
                .join(", ")
        );
        sql += "VALUES ";
        sql += &entities
            .iter()
            .enumerate()
            .map(|(y, _)| {
                format!(
                    "\n\t({})",
                    columns
                        .iter()
                        .enumerate()
                        .map(|(x, _)| {
                            #[allow(unreachable_patterns)]
                            match self.0 {
                                #[cfg(feature = "with-sqlite")]
                                DBPlatform::Sqlite(_) => format!("${}", y * columns_len + x + 1),
                                #[cfg(feature = "with-postgres")]
                                DBPlatform::Postgres(_) => format!("${}", y * columns_len + x + 1),
                                #[cfg(feature = "with-mysql")]
                                DBPlatform::Mysql(_) => "?".to_string(),
                                _ => format!("${}", y * columns_len + x + 1),
                            }
                        })
                        .collect::<Vec<_>>()
                        .join(", ")
                )
            })
            .collect::<Vec<_>>()
            .join(", ");
        sql
    }

    #[allow(clippy::redundant_closure)]
    pub fn execute_sql_with_return<'a, R>(
        &mut self,
        sql: &str,
        params: &[&'a dyn ToValue],
    ) -> Result<Vec<R>, DbError>
    where
        R: FromDao,
    {
        let values: Vec<Value> = params.iter().map(|p| p.to_value()).collect();
        let bvalues: Vec<&Value> = values.iter().collect();
        let rows = self.0.execute_sql_with_return(sql, &bvalues)?;
        Ok(rows.iter().map(|dao| R::from_dao(&dao)).collect::<Vec<R>>())
    }

    pub fn execute_sql_with_one_return<'a, R>(
        &mut self,
        sql: &str,
        params: &[&'a dyn ToValue],
    ) -> Result<R, DbError>
    where
        R: FromDao,
    {
        let result: Result<Vec<R>, DbError> = self.execute_sql_with_return(sql, &params);
        match result {
            Ok(mut result) => {
                match result.len() {
                    0 => Err(DbError::DataError(DataError::ZeroRecordReturned)),
                    1 => Ok(result.remove(0)),
                    _ => Err(DbError::DataError(DataError::MoreThan1RecordReturned)),
                }
            }
            Err(e) => Err(e),
        }
    }

    pub fn execute_sql_with_maybe_one_return<'a, R>(
        &mut self,
        sql: &str,
        params: &[&'a dyn ToValue],
    ) -> Result<Option<R>, DbError>
    where
        R: FromDao,
    {
        let result: Result<Vec<R>, DbError> = self.execute_sql_with_return(sql, &params);
        match result {
            Ok(mut result) => {
                match result.len() {
                    0 => Ok(None),
                    1 => Ok(Some(result.remove(0))),
                    _ => Err(DbError::DataError(DataError::MoreThan1RecordReturned)),
                }
            }
            Err(e) => Err(e),
        }
    }
}
<commit_msg>Fix warning<commit_after>use crate::{
    table::SchemaContent,
    users::{
        Role,
        User,
    },
    DBPlatform,
    DataError,
    Database,
    DatabaseName,
    DbError,
    Table,
    ToValue,
    Value,
};

use rustorm_dao::{
    FromDao,
    TableName,
    ToColumnNames,
    ToDao,
    ToTableName,
};

pub struct EntityManager(pub DBPlatform);

impl EntityManager {
    pub fn set_session_user(&mut self, username: &str) -> Result<(), DbError> {
        let sql = format!("SET SESSION ROLE '{}'", username);
        self.0.execute_sql_with_return(&sql, &[])?;
        Ok(())
    }

    pub fn get_role(&mut self, username: &str) -> Result<Option<Role>, DbError> {
        let result = self.0.get_roles(username);
        match result {
            Ok(mut result) => {
                match result.len() {
                    0 => Ok(None),
                    1 => Ok(Some(result.remove(0))),
                    _ => Err(DbError::DataError(DataError::MoreThan1RecordReturned)),
                }
            }
            Err(e) => Err(e),
        }
    }

    pub fn db(&mut self) -> &mut dyn Database { &mut *self.0 }

    /// get all the records of this table
    pub fn get_all<T>(&mut self) -> Result<Vec<T>, DbError>
    where
        T: ToTableName + ToColumnNames + FromDao,
    {
        let table = T::to_table_name();
        let columns = T::to_column_names();
        let enumerated_columns = columns
            .iter()
            .map(|c| c.name.to_owned())
            .collect::<Vec<_>>()
            .join(", ");
        let sql = format!(
            "SELECT {} FROM {}",
            enumerated_columns,
            table.complete_name()
        );
        let rows = self.0.execute_sql_with_return(&sql, &[])?;
        let mut entities = vec![];
        for dao in rows.iter() {
            let entity = T::from_dao(&dao);
            entities.push(entity)
        }
        Ok(entities)
    }

    /// get the table from database based on this column name
    pub fn get_table(&mut self, table_name: &TableName) -> Result<Table, DbError> {
        self.0.get_table(table_name)
    }

    /// get all the user table and views from the database
    pub fn get_all_tables(&mut self) -> Result<Vec<Table>, DbError> {
        info!("EXPENSIVE DB OPERATION: get_all_tables");
        self.0.get_all_tables()
    }

    /// Get the total count of records
    pub fn get_total_records(&mut self, table_name: &TableName) -> Result<usize, DbError> {
        #[derive(crate::FromDao)]
        struct Count {
            count: i64,
        }
        let sql = format!(
            "SELECT COUNT(*) AS count FROM {}",
            table_name.complete_name()
        );
        let count: Result<Count, DbError> = self.execute_sql_with_one_return(&sql, &[]);
        count.map(|c| c.count as usize)
    }

    pub fn get_users(&mut self) -> Result<Vec<User>, DbError> { self.0.get_users() }

    pub fn get_database_name(&mut self) -> Result<Option<DatabaseName>, DbError> {
        self.0.get_database_name()
    }

    /// get all table and views grouped per schema
    pub fn get_grouped_tables(&mut self) -> Result<Vec<SchemaContent>, DbError> {
        self.0.get_grouped_tables()
    }

    #[allow(unused_variables)]
    pub fn insert<T, R>(&mut self, entities: &[&T]) -> Result<Vec<R>, DbError>
    where
        T: ToTableName + ToColumnNames + ToDao,
        R: FromDao + ToColumnNames,
    {
        match self.0 {
            #[cfg(feature = "with-sqlite")]
            DBPlatform::Sqlite(_) => self.insert_simple(entities),
            #[cfg(feature = "with-postgres")]
            DBPlatform::Postgres(_) => self.insert_bulk_with_returning_support(entities),
            #[cfg(feature = "with-mysql")]
            DBPlatform::Mysql(_) => self.insert_simple(entities),
        }
    }

    /// called when the platform used is postgresql
    pub fn insert_bulk_with_returning_support<T, R>(
        &mut self,
        entities: &[&T],
    ) -> Result<Vec<R>, DbError>
    where
        T: ToTableName + ToColumnNames + ToDao,
        R: FromDao + ToColumnNames,
    {
        let columns = T::to_column_names();
        let mut sql = self.build_insert_clause(entities);
        let return_columns = R::to_column_names();
        sql += &self.build_returning_clause(return_columns);

        let mut values: Vec<Value> = Vec::with_capacity(entities.len() * columns.len());
        for entity in entities {
            let dao = entity.to_dao();
            for col in columns.iter() {
                let value = dao.get_value(&col.name);
                match value {
                    Some(value) => values.push(value.clone()),
                    None => values.push(Value::Nil),
                }
            }
        }
        let bvalues: Vec<&Value> = values.iter().collect();
        let rows = self.0.execute_sql_with_return(&sql, &bvalues)?;
        let mut retrieved_entities = vec![];
        for dao in rows.iter() {
            let retrieved = R::from_dao(&dao);
            retrieved_entities.push(retrieved);
        }
        Ok(retrieved_entities)
    }

    /// called multiple times when using database platform that doesn;t support multiple value
    /// insert such as sqlite
    pub fn single_insert<T>(&mut self, entity: &T) -> Result<(), DbError>
    where
        T: ToTableName + ToColumnNames + ToDao,
    {
        let columns = T::to_column_names();
        let sql = self.build_insert_clause(&[entity]);
        let dao = entity.to_dao();
        let mut values: Vec<Value> = Vec::with_capacity(columns.len());
        for col in columns.iter() {
            let value = dao.get_value(&col.name);
            match value {
                Some(value) => values.push(value.clone()),
                None => values.push(Value::Nil),
            }
        }
        let bvalues: Vec<&Value> = values.iter().collect();
        self.0.execute_sql_with_return(&sql, &bvalues)?;
        Ok(())
    }

    /// this is soly for use with sqlite since sqlite doesn't support bulk insert
    pub fn insert_simple<T, R>(&mut self, entities: &[&T]) -> Result<Vec<R>, DbError>
    where
        T: ToTableName + ToColumnNames + ToDao,
        R: FromDao + ToColumnNames,
    {
        let return_columns = R::to_column_names();
        let return_column_names = return_columns
            .iter()
            .map(|rc| rc.name.to_owned())
            .collect::<Vec<_>>()
            .join(", ");

        let table = T::to_table_name();
        //TODO: move this specific query to sqlite
        let last_insert_sql = format!(
            "\
             SELECT {} \
             FROM {} \
             WHERE ROWID = (\
             SELECT LAST_INSERT_ROWID() FROM {})",
            return_column_names,
            table.complete_name(),
            table.complete_name()
        );
        let mut retrieved_entities = vec![];
        println!("sql: {}", last_insert_sql);
        for entity in entities {
            self.single_insert(*entity)?;
            let retrieved = self.execute_sql_with_return(&last_insert_sql, &[])?;
            retrieved_entities.extend(retrieved);
        }
        Ok(retrieved_entities)
    }

    /// build the returning clause
    fn build_returning_clause(&self, return_columns: Vec<rustorm_dao::ColumnName>) -> String {
        format!(
            "\nRETURNING \n{}",
            return_columns
                .iter()
                .map(|rc| rc.name.to_owned())
                .collect::<Vec<_>>()
                .join(", ")
        )
    }

    /// build an insert clause
    fn build_insert_clause<T>(&self, entities: &[&T]) -> String
    where
        T: ToTableName + ToColumnNames + ToDao,
    {
        let table = T::to_table_name();
        let columns = T::to_column_names();
        let columns_len = columns.len();
        let mut sql = String::new();
        sql += &format!("INSERT INTO {} ", table.complete_name());
        sql += &format!(
            "({})\n",
            columns
                .iter()
                .map(|c| c.name.to_owned())
                .collect::<Vec<_>>()
                .join(", ")
        );
        sql += "VALUES ";
        sql += &entities
            .iter()
            .enumerate()
            .map(|(y, _)| {
                format!(
                    "\n\t({})",
                    columns
                        .iter()
                        .enumerate()
                        .map(|(x, _)| {
                            #[allow(unreachable_patterns)]
                            match self.0 {
                                #[cfg(feature = "with-sqlite")]
                                DBPlatform::Sqlite(_) => format!("${}", y * columns_len + x + 1),
                                #[cfg(feature = "with-postgres")]
                                DBPlatform::Postgres(_) => format!("${}", y * columns_len + x + 1),
                                #[cfg(feature = "with-mysql")]
                                DBPlatform::Mysql(_) => "?".to_string(),
                                _ => format!("${}", y * columns_len + x + 1),
                            }
                        })
                        .collect::<Vec<_>>()
                        .join(", ")
                )
            })
            .collect::<Vec<_>>()
            .join(", ");
        sql
    }

    #[allow(clippy::redundant_closure)]
    pub fn execute_sql_with_return<'a, R>(
        &mut self,
        sql: &str,
        params: &[&'a dyn ToValue],
    ) -> Result<Vec<R>, DbError>
    where
        R: FromDao,
    {
        let values: Vec<Value> = params.iter().map(|p| p.to_value()).collect();
        let bvalues: Vec<&Value> = values.iter().collect();
        let rows = self.0.execute_sql_with_return(sql, &bvalues)?;
        Ok(rows.iter().map(|dao| R::from_dao(&dao)).collect::<Vec<R>>())
    }

    pub fn execute_sql_with_one_return<'a, R>(
        &mut self,
        sql: &str,
        params: &[&'a dyn ToValue],
    ) -> Result<R, DbError>
    where
        R: FromDao,
    {
        let result: Result<Vec<R>, DbError> = self.execute_sql_with_return(sql, &params);
        match result {
            Ok(mut result) => {
                match result.len() {
                    0 => Err(DbError::DataError(DataError::ZeroRecordReturned)),
                    1 => Ok(result.remove(0)),
                    _ => Err(DbError::DataError(DataError::MoreThan1RecordReturned)),
                }
            }
            Err(e) => Err(e),
        }
    }

    pub fn execute_sql_with_maybe_one_return<'a, R>(
        &mut self,
        sql: &str,
        params: &[&'a dyn ToValue],
    ) -> Result<Option<R>, DbError>
    where
        R: FromDao,
    {
        let result: Result<Vec<R>, DbError> = self.execute_sql_with_return(sql, &params);
        match result {
            Ok(mut result) => {
                match result.len() {
                    0 => Ok(None),
                    1 => Ok(Some(result.remove(0))),
                    _ => Err(DbError::DataError(DataError::MoreThan1RecordReturned)),
                }
            }
            Err(e) => Err(e),
        }
    }
}
<|endoftext|>


<commit_before>use std::{result, io, fmt};
use std::error;

use protobuf::ProtobufError;

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    NotFound,
    Protobuf(ProtobufError),
    Other(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::NotFound => write!(f, "not found"),
            Error::Io(ref error) => fmt::Display::fmt(error, f),
            _ => fmt::Display::fmt(self, f),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match self {
            // not sure that cause should be included in message
            &Error::Io(ref e) => e.description(),
            &Error::NotFound => "not found",
            &Error::Protobuf(ref e) => e.description(),
            &Error::Other(ref e) => &e,
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match self {
            &Error::Io(ref e) => Some(e),
            &Error::Protobuf(ref e) => Some(e),
            _ => None,
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error{
        Error::Io(err)
    }
 }

impl From<ProtobufError> for Error {
    fn from(err: ProtobufError) -> Error{
        Error::Protobuf(err)
    }
 }

pub type Result<T> = result::Result<T, Error>;
<commit_msg>raft: format code.<commit_after>use std::{result, io, fmt};
use std::error;

use protobuf::ProtobufError;

#[derive(Debug)]
pub enum Error {
    Io(io::Error),
    NotFound,
    Protobuf(ProtobufError),
    Other(String),
}

impl fmt::Display for Error {
    fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
        match *self {
            Error::NotFound => write!(f, "not found"),
            Error::Io(ref error) => fmt::Display::fmt(error, f),
            _ => fmt::Display::fmt(self, f),
        }
    }
}

impl error::Error for Error {
    fn description(&self) -> &str {
        match self {
            // not sure that cause should be included in message
            &Error::Io(ref e) => e.description(),
            &Error::NotFound => "not found",
            &Error::Protobuf(ref e) => e.description(),
            &Error::Other(ref e) => &e,
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match self {
            &Error::Io(ref e) => Some(e),
            &Error::Protobuf(ref e) => Some(e),
            _ => None,
        }
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Error {
        Error::Io(err)
    }
}

impl From<ProtobufError> for Error {
    fn from(err: ProtobufError) -> Error {
        Error::Protobuf(err)
    }
}

pub type Result<T> = result::Result<T, Error>;
<|endoftext|>


<commit_before>
pub struct Events {
    up: bool,
    down: bool,
    left: bool,
    right: bool,
}

impl Events {
    pub fn is_up() -> bool {
        self.up
    }

    pub fn is_down() -> bool {
        self.down
    }

    pub fn is_left() -> bool {
        self.left
    }

    pub fn is_right() -> bool {
        self.right
    }
}

<commit_msg>TODO: handle_input function<commit_after>
pub struct Events {
    up: bool,
    down: bool,
    left: bool,
    right: bool,
}

impl Events {
    pub fn is_up() -> bool {
        self.up
    }

    pub fn is_down() -> bool {
        self.down
    }

    pub fn is_left() -> bool {
        self.left
    }

    pub fn is_right() -> bool {
        self.right
    }

    pub fn handle_input() {
    }
}
<|endoftext|>


<commit_before>//! Offsets to tables

use crate::Uint24;

/// A trait for the different offset representations.
pub trait Offset: Sized {
    /// The length in bytes of this offset type.
    const SIZE: OffsetLen;

    /// Returns this offsize as a `usize`, or `None` if it is `0`.
    fn non_null(self) -> Option<usize>;
    fn read<'a, T: crate::FontRead<'a>>(self, bytes: &'a [u8]) -> Option<T> {
        self.non_null()
            .and_then(|off| bytes.get(off..))
            .and_then(T::read)
    }
}

/// A type that contains data referenced by offsets.
pub trait OffsetHost<'a> {
    /// Return a slice of bytes from which offsets may be resolved.
    ///
    /// This should be relative to the start of the host.
    fn bytes(&self) -> &'a [u8];

    /// Return the bytes for a given offset
    fn bytes_at_offset(&self, offset: impl Offset) -> &'a [u8] {
        offset
            .non_null()
            .and_then(|off| self.bytes().get(off..))
            .unwrap_or_default()
    }

    fn resolve_offset<T: crate::FontRead<'a>>(&self, offset: impl Offset) -> Option<T> {
        crate::FontRead::read(self.bytes_at_offset(offset))
    }
}

/// The byte length of some offset.
///
/// This is sort of redundant, but it is useful during compilation to have
/// some token type that represents a pending offset.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
#[repr(u8)]
pub enum OffsetLen {
    Offset16 = 2,
    Offset24 = 3,
    Offset32 = 4,
}

impl OffsetLen {
    /// The empty represntation of this offset
    pub fn null_bytes(self) -> &'static [u8] {
        match self {
            Self::Offset16 => &[0, 0],
            Self::Offset24 => &[0, 0, 0],
            Self::Offset32 => &[0, 0, 0, 0],
        }
    }
}

impl std::fmt::Display for OffsetLen {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            Self::Offset16 => write!(f, "Offset16"),
            Self::Offset24 => write!(f, "Offset24"),
            Self::Offset32 => write!(f, "Offset32"),
        }
    }
}

macro_rules! impl_offset {
    ($name:ident, $bits:literal, $rawty:ty) => {
        #[doc = concat!("A", stringify!($bits), "-bit offset to a table.")]
        ///
        /// Specific offset fields may or may not permit NULL values; however we
        /// assume that errors are possible, and expect the caller to handle
        /// the `None` case.
        #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
        pub struct $name($rawty);

        impl $name {
            /// Create a new offset.
            pub fn new(raw: $rawty) -> Self {
                Self(raw)
            }
        }

        impl crate::raw::Scalar for $name {
            type Raw = <$rawty as crate::raw::Scalar>::Raw;
            fn from_raw(raw: Self::Raw) -> Self {
                let raw = <$rawty>::from_raw(raw);
                $name::new(raw)
            }

            fn to_raw(self) -> Self::Raw {
                self.0.to_raw()
            }
        }

        impl Offset for $name {
            const SIZE: OffsetLen = OffsetLen::$name;

            fn non_null(self) -> Option<usize> {
                let raw: u32 = self.0.into();
                if raw == 0 {
                    None
                } else {
                    Some(raw as usize)
                }
            }
        }
    };
}

impl_offset!(Offset16, 16, u16);
impl_offset!(Offset24, 24, Uint24);
impl_offset!(Offset32, 32, u32);
<commit_msg>Add Offset::read_with_args<commit_after>//! Offsets to tables

use crate::Uint24;

/// A trait for the different offset representations.
pub trait Offset: Sized {
    /// The length in bytes of this offset type.
    const SIZE: OffsetLen;

    /// Returns this offsize as a `usize`, or `None` if it is `0`.
    fn non_null(self) -> Option<usize>;
    fn read<'a, T: crate::FontRead<'a>>(self, bytes: &'a [u8]) -> Option<T> {
        self.non_null()
            .and_then(|off| bytes.get(off..))
            .and_then(T::read)
    }

    fn read_with_args<'a, Args, T>(self, bytes: &'a [u8], args: &Args) -> Option<T>
    where
        T: crate::FontReadWithArgs<'a, Args>,
    {
        self.non_null()
            .and_then(|off| bytes.get(off..))
            .and_then(|bytes| T::read_with_args(bytes, args))
            .map(|(t, _)| t)
    }
}

/// A type that contains data referenced by offsets.
pub trait OffsetHost<'a> {
    /// Return a slice of bytes from which offsets may be resolved.
    ///
    /// This should be relative to the start of the host.
    fn bytes(&self) -> &'a [u8];

    /// Return the bytes for a given offset
    fn bytes_at_offset(&self, offset: impl Offset) -> &'a [u8] {
        offset
            .non_null()
            .and_then(|off| self.bytes().get(off..))
            .unwrap_or_default()
    }

    fn resolve_offset<T: crate::FontRead<'a>>(&self, offset: impl Offset) -> Option<T> {
        crate::FontRead::read(self.bytes_at_offset(offset))
    }
}

/// The byte length of some offset.
///
/// This is sort of redundant, but it is useful during compilation to have
/// some token type that represents a pending offset.
#[derive(Debug, Clone, Copy, Hash, PartialEq, Eq)]
#[repr(u8)]
pub enum OffsetLen {
    Offset16 = 2,
    Offset24 = 3,
    Offset32 = 4,
}

impl OffsetLen {
    /// The empty represntation of this offset
    pub fn null_bytes(self) -> &'static [u8] {
        match self {
            Self::Offset16 => &[0, 0],
            Self::Offset24 => &[0, 0, 0],
            Self::Offset32 => &[0, 0, 0, 0],
        }
    }
}

impl std::fmt::Display for OffsetLen {
    fn fmt(&self, f: &mut std::fmt::Formatter) -> std::fmt::Result {
        match self {
            Self::Offset16 => write!(f, "Offset16"),
            Self::Offset24 => write!(f, "Offset24"),
            Self::Offset32 => write!(f, "Offset32"),
        }
    }
}

macro_rules! impl_offset {
    ($name:ident, $bits:literal, $rawty:ty) => {
        #[doc = concat!("A", stringify!($bits), "-bit offset to a table.")]
        ///
        /// Specific offset fields may or may not permit NULL values; however we
        /// assume that errors are possible, and expect the caller to handle
        /// the `None` case.
        #[derive(Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
        pub struct $name($rawty);

        impl $name {
            /// Create a new offset.
            pub fn new(raw: $rawty) -> Self {
                Self(raw)
            }
        }

        impl crate::raw::Scalar for $name {
            type Raw = <$rawty as crate::raw::Scalar>::Raw;
            fn from_raw(raw: Self::Raw) -> Self {
                let raw = <$rawty>::from_raw(raw);
                $name::new(raw)
            }

            fn to_raw(self) -> Self::Raw {
                self.0.to_raw()
            }
        }

        impl Offset for $name {
            const SIZE: OffsetLen = OffsetLen::$name;

            fn non_null(self) -> Option<usize> {
                let raw: u32 = self.0.into();
                if raw == 0 {
                    None
                } else {
                    Some(raw as usize)
                }
            }
        }
    };
}

impl_offset!(Offset16, 16, u16);
impl_offset!(Offset24, 24, Uint24);
impl_offset!(Offset32, 32, u32);
<|endoftext|>


<commit_before>// See LICENSE file for copyright and license details.

// Marauder is grid-less turn-based strategy game.

extern mod glfw;
extern mod gl;
extern mod cgmath;

use gl::types::{
  GLenum,
  GLuint,
  GLint,
  GLchar,
  GLfloat,
  GLsizeiptr,
  GLboolean
};
use cgmath::matrix::{Matrix, Mat4, Mat3, ToMat4};
use cgmath::projection;
use cgmath::angle;
use cgmath::vector::{Vec3, Vec2};

#[link(name = "glfw")]
#[link(name = "m")]
extern {}

/// usage: let s = mvp_matrix; println(type_of(&s));
fn type_of<T>(_: &T) -> &'static str {
  unsafe {
    (*std::unstable::intrinsics::get_tydesc::<T>()).name
  }
}

fn print_mat4(name: &str, mat: Mat4<f32>) {
  println!("{}:", name);
  for i in range(0u, 4) {
    for j in range(0u, 4) {
      print!("{} ", *mat.cr(i, j));
    }
    println("");
  }
  println("");
}

static mut MOUSE_POS: Vec2<f32> = Vec2{x: 0.0f32, y: 0.0};
static mut CAMERA_POS: Vec3<f32> = Vec3{x: 0.0f32, y: 0.0, z: 0.0};

static WIN_SIZE: Vec2<uint> = Vec2{x: 640, y: 480};
static VERTICES_COUNT: i32 = 3 * 2;

static VERTEX_DATA: [GLfloat, ..VERTICES_COUNT * 3] = [
   0.0,  1.0, 0.0,
   2.0, -1.0, 0.0,
  -2.0, -1.0, 0.0,

  0.0,  1.0,  0.0,
  0.0, -1.0,  2.0,
  0.0, -1.0, -2.0
];

static VERTEX_SHADER_SRC: &'static str = "
  #version 130
  in vec3 position;
  uniform mat4 model_view_proj_matrix;
  void main() {
    vec4 v = vec4(position, 1);
    gl_Position = model_view_proj_matrix * v;
  }
";

static FRAGMENT_SHADER_SRC: &'static str = "
  #version 130
  out vec4 out_color;
  void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
  }
";

#[start]
fn start(argc: int, argv: **u8) -> int {
  std::rt::start_on_main_thread(argc, argv, main)
}

fn compile_shader(src: &str, ty: GLenum) -> GLuint {
  let shader = gl::CreateShader(ty);
  unsafe {
    // Attempt to compile the shader
    gl::ShaderSource(shader, 1, &src.to_c_str().unwrap(), std::ptr::null());
    gl::CompileShader(shader);

    // Get the compile status
    let mut status = gl::FALSE as GLint;
    gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len = 0;
      gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetShaderInfoLog(shader, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("compile_shader(): " + std::str::raw::from_utf8(buf));
    }
  }
  shader
}

fn link_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint {
  let program = gl::CreateProgram();
  gl::AttachShader(program, vertex_shader);
  gl::AttachShader(program, fragment_shader);
  gl::LinkProgram(program);
  unsafe {
    // Get the link status
    let mut status = gl::FALSE as GLint;
    gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len: GLint = 0;
      gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetProgramInfoLog(program, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("link_program(): " + std::str::raw::from_utf8(buf));
    }
  }
  program
}

fn tr(m: Mat4<f32>, v: Vec3<f32>) -> Mat4<f32> {
  let mut t = Mat4::<f32>::identity();
  *t.mut_cr(3, 0) = v.x;
  *t.mut_cr(3, 1) = v.y;
  *t.mut_cr(3, 2) = v.z;
  m.mul_m(&t)
}

fn rot_x(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_x(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

fn rot_y(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_y(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

// change matrices
fn upd(programId: GLuint) {
  let fov = angle::deg(45.0f32);
  let ratio = 4.0 / 3.0;
  let display_range_min = 0.1;
  let display_range_max = 100.0;
  let projection_matrix = projection::perspective(
    fov, ratio, display_range_min, display_range_max
  );

  let mut mvp_matrix = projection_matrix;
  unsafe {
    mvp_matrix = tr(mvp_matrix, Vec3{x: 0.0f32, y: 0.0, z: -10.0f32});
    mvp_matrix = rot_x(mvp_matrix, MOUSE_POS.y / 100.0);
    mvp_matrix = rot_y(mvp_matrix, MOUSE_POS.x / 100.0);
    mvp_matrix = tr(mvp_matrix, CAMERA_POS);
  }

  unsafe {
    // Get a handle for our "model_view_proj_matrix" uniform.
    // Only at initialisation time.
    let matrixId = gl::GetUniformLocation(
      programId, "model_view_proj_matrix".to_c_str().unwrap());

    // Send our transformation to the currently bound shader,
    // in the "model_view_proj_matrix" uniform.
    // For each model you render, since the model_view_proj_matrix
    // will be different (at least the M part).
    gl::UniformMatrix4fv(matrixId, 1, gl::FALSE, mvp_matrix.cr(0, 0));
  }
}

struct Win {
  vertex_shader: GLuint,
  fragment_shader: GLuint,
  program: GLuint,
  vertex_array_obj: GLuint,
  vertex_buffer_obj: GLuint,
  window: glfw::Window
}

impl Win {
  fn new() -> Win {
    let mut win =  Win{
      vertex_shader: 0,
      fragment_shader: 0,
      program: 0,
      vertex_array_obj: 0,
      vertex_buffer_obj: 0,
      window: glfw::Window::create(
        WIN_SIZE.x,
        WIN_SIZE.y,
        "OpenGL",
        glfw::Windowed
      ).unwrap()
    };

    win.window.make_context_current();
    win.window.set_cursor_pos_callback(~CursorPosContext);
    win.window.set_key_callback(~KeyContext);

    // Load the OpenGL function pointers
    gl::load_with(glfw::get_proc_address);

    // Create GLSL shaders
    win.vertex_shader = compile_shader(
      VERTEX_SHADER_SRC, gl::VERTEX_SHADER);
    win.fragment_shader = compile_shader(
      FRAGMENT_SHADER_SRC, gl::FRAGMENT_SHADER);
    win.program = link_program(win.vertex_shader, win.fragment_shader);

    unsafe {
      // Create Vertex Array Object
      gl::GenVertexArrays(1, &mut win.vertex_array_obj);
      gl::BindVertexArray(win.vertex_array_obj);

      // Create a Vertex Buffer Object and copy the vertex data to it
      gl::GenBuffers(1, &mut win.vertex_buffer_obj);
      gl::BindBuffer(gl::ARRAY_BUFFER, win.vertex_buffer_obj);
      let float_size = std::mem::size_of::<GLfloat>();
      let vertices_ptr = (VERTEX_DATA.len() * float_size) as GLsizeiptr;
      gl::BufferData(
        gl::ARRAY_BUFFER,
        vertices_ptr,
        std::cast::transmute(&VERTEX_DATA[0]),
        gl::STATIC_DRAW
      );

      gl::UseProgram(win.program);
      gl::BindFragDataLocation(win.program, 0, "out_color".to_c_str().unwrap());

      // Specify the layout of the vertex data
      let pos_attr = gl::GetAttribLocation(
        win.program, "position".to_c_str().unwrap()) as GLuint;
      gl::EnableVertexAttribArray(pos_attr);
      let size = 3;
      let normalized = gl::FALSE as GLboolean;
      let stride = 0;
      gl::VertexAttribPointer(
        pos_attr,
        size,
        gl::FLOAT,
        normalized,
        stride,
        std::ptr::null()
      );
    }

    win
  }

  fn cleanup(&self) {
    // Cleanup
    gl::DeleteProgram(self.program);
    gl::DeleteShader(self.fragment_shader);
    gl::DeleteShader(self.vertex_shader);
    unsafe {
      gl::DeleteBuffers(1, &self.vertex_buffer_obj);
      gl::DeleteVertexArrays(1, &self.vertex_array_obj);
    }
  }

  fn draw(&self) {
    upd(self.program);

    // Clear the screen to black
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT);

    // Draw a triangle from the 3 vertices
    gl::DrawArrays(gl::TRIANGLES, 0, VERTICES_COUNT);

    self.window.swap_buffers();
  }

  fn is_running(&self) -> bool {
    return !self.window.should_close()
  }

  fn process_events(&self) {
    glfw::poll_events();
  }
}

fn main() {
  glfw::set_error_callback(~ErrorContext);

  do glfw::start {
    // glfw::window_hint::context_version(3, 2);

    let win =  Win::new();

    while win.is_running() {
      win.process_events();
      win.draw();
    }

    win.cleanup();
  }
}

struct CursorPosContext;
impl glfw::CursorPosCallback for CursorPosContext {
  fn call(&self, w: &glfw::Window, xpos: f64, ypos: f64) {
    if w.get_mouse_button(glfw::MouseButtonRight) == glfw::Press {
      // println!("Cursor position: ({}, {})", xpos, ypos);
      unsafe {
        MOUSE_POS.x = xpos as f32;
        MOUSE_POS.y = ypos as f32;
      }
    }
  }
}

struct ErrorContext;
impl glfw::ErrorCallback for ErrorContext {
  fn call(&self, _: glfw::Error, description: ~str) {
    println!("GLFW Error: {:s}", description);
  }
}

struct KeyContext;
impl glfw::KeyCallback for KeyContext {
  fn call(
    &self,
    window: &glfw::Window,
    key:    glfw::Key,
    _:      std::libc::c_int,
    action: glfw::Action,
    _:      glfw::Modifiers
  ) {
    match (action, key) {
      (glfw::Press, glfw::KeyEscape) => {
        window.set_should_close(true)
      }
      (glfw::Press, glfw::KeySpace) => {
        println!("space")
      }
      (glfw::Press, glfw::KeyUp) => unsafe { CAMERA_POS.y -= 1.0f32 },
      (glfw::Press, glfw::KeyDown) => unsafe { CAMERA_POS.y += 1.0f32 },
      (glfw::Press, glfw::KeyRight) => unsafe { CAMERA_POS.x -= 1.0f32 },
      (glfw::Press, glfw::KeyLeft) => unsafe { CAMERA_POS.x += 1.0f32 },
      _ => {}
    }
  }
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<commit_msg>Moved start() and main() to bottom of file<commit_after>// See LICENSE file for copyright and license details.

// Marauder is grid-less turn-based strategy game.

extern mod glfw;
extern mod gl;
extern mod cgmath;

use gl::types::{
  GLenum,
  GLuint,
  GLint,
  GLchar,
  GLfloat,
  GLsizeiptr,
  GLboolean
};
use cgmath::matrix::{Matrix, Mat4, Mat3, ToMat4};
use cgmath::projection;
use cgmath::angle;
use cgmath::vector::{Vec3, Vec2};

#[link(name = "glfw")]
#[link(name = "m")]
extern {}

/// usage: let s = mvp_matrix; println(type_of(&s));
fn type_of<T>(_: &T) -> &'static str {
  unsafe {
    (*std::unstable::intrinsics::get_tydesc::<T>()).name
  }
}

fn print_mat4(name: &str, mat: Mat4<f32>) {
  println!("{}:", name);
  for i in range(0u, 4) {
    for j in range(0u, 4) {
      print!("{} ", *mat.cr(i, j));
    }
    println("");
  }
  println("");
}

static mut MOUSE_POS: Vec2<f32> = Vec2{x: 0.0f32, y: 0.0};
static mut CAMERA_POS: Vec3<f32> = Vec3{x: 0.0f32, y: 0.0, z: 0.0};

static WIN_SIZE: Vec2<uint> = Vec2{x: 640, y: 480};
static VERTICES_COUNT: i32 = 3 * 2;

static VERTEX_DATA: [GLfloat, ..VERTICES_COUNT * 3] = [
   0.0,  1.0, 0.0,
   2.0, -1.0, 0.0,
  -2.0, -1.0, 0.0,

  0.0,  1.0,  0.0,
  0.0, -1.0,  2.0,
  0.0, -1.0, -2.0
];

static VERTEX_SHADER_SRC: &'static str = "
  #version 130
  in vec3 position;
  uniform mat4 model_view_proj_matrix;
  void main() {
    vec4 v = vec4(position, 1);
    gl_Position = model_view_proj_matrix * v;
  }
";

static FRAGMENT_SHADER_SRC: &'static str = "
  #version 130
  out vec4 out_color;
  void main() {
    out_color = vec4(1.0, 1.0, 1.0, 1.0);
  }
";

fn compile_shader(src: &str, ty: GLenum) -> GLuint {
  let shader = gl::CreateShader(ty);
  unsafe {
    // Attempt to compile the shader
    gl::ShaderSource(shader, 1, &src.to_c_str().unwrap(), std::ptr::null());
    gl::CompileShader(shader);

    // Get the compile status
    let mut status = gl::FALSE as GLint;
    gl::GetShaderiv(shader, gl::COMPILE_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len = 0;
      gl::GetShaderiv(shader, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetShaderInfoLog(shader, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("compile_shader(): " + std::str::raw::from_utf8(buf));
    }
  }
  shader
}

fn link_program(vertex_shader: GLuint, fragment_shader: GLuint) -> GLuint {
  let program = gl::CreateProgram();
  gl::AttachShader(program, vertex_shader);
  gl::AttachShader(program, fragment_shader);
  gl::LinkProgram(program);
  unsafe {
    // Get the link status
    let mut status = gl::FALSE as GLint;
    gl::GetProgramiv(program, gl::LINK_STATUS, &mut status);

    // Fail on error
    if status != (gl::TRUE as GLint) {
      let mut len: GLint = 0;
      gl::GetProgramiv(program, gl::INFO_LOG_LENGTH, &mut len);
      // subtract 1 to skip the trailing null character
      let mut buf = std::vec::from_elem(len as uint - 1, 0u8);
      gl::GetProgramInfoLog(program, len, std::ptr::mut_null(),
        std::vec::raw::to_mut_ptr(buf) as *mut GLchar
      );
      fail!("link_program(): " + std::str::raw::from_utf8(buf));
    }
  }
  program
}

fn tr(m: Mat4<f32>, v: Vec3<f32>) -> Mat4<f32> {
  let mut t = Mat4::<f32>::identity();
  *t.mut_cr(3, 0) = v.x;
  *t.mut_cr(3, 1) = v.y;
  *t.mut_cr(3, 2) = v.z;
  m.mul_m(&t)
}

fn rot_x(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_x(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

fn rot_y(m: Mat4<f32>, angle: f32) -> Mat4<f32> {
  let r = Mat3::from_angle_y(angle::rad(angle)).to_mat4();
  m.mul_m(&r)
}

// change matrices
fn upd(programId: GLuint) {
  let fov = angle::deg(45.0f32);
  let ratio = 4.0 / 3.0;
  let display_range_min = 0.1;
  let display_range_max = 100.0;
  let projection_matrix = projection::perspective(
    fov, ratio, display_range_min, display_range_max
  );

  let mut mvp_matrix = projection_matrix;
  unsafe {
    mvp_matrix = tr(mvp_matrix, Vec3{x: 0.0f32, y: 0.0, z: -10.0f32});
    mvp_matrix = rot_x(mvp_matrix, MOUSE_POS.y / 100.0);
    mvp_matrix = rot_y(mvp_matrix, MOUSE_POS.x / 100.0);
    mvp_matrix = tr(mvp_matrix, CAMERA_POS);
  }

  unsafe {
    // Get a handle for our "model_view_proj_matrix" uniform.
    // Only at initialisation time.
    let matrixId = gl::GetUniformLocation(
      programId, "model_view_proj_matrix".to_c_str().unwrap());

    // Send our transformation to the currently bound shader,
    // in the "model_view_proj_matrix" uniform.
    // For each model you render, since the model_view_proj_matrix
    // will be different (at least the M part).
    gl::UniformMatrix4fv(matrixId, 1, gl::FALSE, mvp_matrix.cr(0, 0));
  }
}

struct Win {
  vertex_shader: GLuint,
  fragment_shader: GLuint,
  program: GLuint,
  vertex_array_obj: GLuint,
  vertex_buffer_obj: GLuint,
  window: glfw::Window
}

impl Win {
  fn new() -> Win {
    let mut win =  Win{
      vertex_shader: 0,
      fragment_shader: 0,
      program: 0,
      vertex_array_obj: 0,
      vertex_buffer_obj: 0,
      window: glfw::Window::create(
        WIN_SIZE.x,
        WIN_SIZE.y,
        "OpenGL",
        glfw::Windowed
      ).unwrap()
    };

    win.window.make_context_current();
    win.window.set_cursor_pos_callback(~CursorPosContext);
    win.window.set_key_callback(~KeyContext);

    // Load the OpenGL function pointers
    gl::load_with(glfw::get_proc_address);

    // Create GLSL shaders
    win.vertex_shader = compile_shader(
      VERTEX_SHADER_SRC, gl::VERTEX_SHADER);
    win.fragment_shader = compile_shader(
      FRAGMENT_SHADER_SRC, gl::FRAGMENT_SHADER);
    win.program = link_program(win.vertex_shader, win.fragment_shader);

    unsafe {
      // Create Vertex Array Object
      gl::GenVertexArrays(1, &mut win.vertex_array_obj);
      gl::BindVertexArray(win.vertex_array_obj);

      // Create a Vertex Buffer Object and copy the vertex data to it
      gl::GenBuffers(1, &mut win.vertex_buffer_obj);
      gl::BindBuffer(gl::ARRAY_BUFFER, win.vertex_buffer_obj);
      let float_size = std::mem::size_of::<GLfloat>();
      let vertices_ptr = (VERTEX_DATA.len() * float_size) as GLsizeiptr;
      gl::BufferData(
        gl::ARRAY_BUFFER,
        vertices_ptr,
        std::cast::transmute(&VERTEX_DATA[0]),
        gl::STATIC_DRAW
      );

      gl::UseProgram(win.program);
      gl::BindFragDataLocation(win.program, 0, "out_color".to_c_str().unwrap());

      // Specify the layout of the vertex data
      let pos_attr = gl::GetAttribLocation(
        win.program, "position".to_c_str().unwrap()) as GLuint;
      gl::EnableVertexAttribArray(pos_attr);
      let size = 3;
      let normalized = gl::FALSE as GLboolean;
      let stride = 0;
      gl::VertexAttribPointer(
        pos_attr,
        size,
        gl::FLOAT,
        normalized,
        stride,
        std::ptr::null()
      );
    }

    win
  }

  fn cleanup(&self) {
    // Cleanup
    gl::DeleteProgram(self.program);
    gl::DeleteShader(self.fragment_shader);
    gl::DeleteShader(self.vertex_shader);
    unsafe {
      gl::DeleteBuffers(1, &self.vertex_buffer_obj);
      gl::DeleteVertexArrays(1, &self.vertex_array_obj);
    }
  }

  fn draw(&self) {
    upd(self.program);

    // Clear the screen to black
    gl::ClearColor(0.3, 0.3, 0.3, 1.0);
    gl::Clear(gl::COLOR_BUFFER_BIT);

    // Draw a triangle from the 3 vertices
    gl::DrawArrays(gl::TRIANGLES, 0, VERTICES_COUNT);

    self.window.swap_buffers();
  }

  fn is_running(&self) -> bool {
    return !self.window.should_close()
  }

  fn process_events(&self) {
    glfw::poll_events();
  }
}

struct CursorPosContext;
impl glfw::CursorPosCallback for CursorPosContext {
  fn call(&self, w: &glfw::Window, xpos: f64, ypos: f64) {
    if w.get_mouse_button(glfw::MouseButtonRight) == glfw::Press {
      // println!("Cursor position: ({}, {})", xpos, ypos);
      unsafe {
        MOUSE_POS.x = xpos as f32;
        MOUSE_POS.y = ypos as f32;
      }
    }
  }
}

struct ErrorContext;
impl glfw::ErrorCallback for ErrorContext {
  fn call(&self, _: glfw::Error, description: ~str) {
    println!("GLFW Error: {:s}", description);
  }
}

struct KeyContext;
impl glfw::KeyCallback for KeyContext {
  fn call(
    &self,
    window: &glfw::Window,
    key:    glfw::Key,
    _:      std::libc::c_int,
    action: glfw::Action,
    _:      glfw::Modifiers
  ) {
    match (action, key) {
      (glfw::Press, glfw::KeyEscape) => {
        window.set_should_close(true)
      }
      (glfw::Press, glfw::KeySpace) => {
        println!("space")
      }
      (glfw::Press, glfw::KeyUp) => unsafe { CAMERA_POS.y -= 1.0f32 },
      (glfw::Press, glfw::KeyDown) => unsafe { CAMERA_POS.y += 1.0f32 },
      (glfw::Press, glfw::KeyRight) => unsafe { CAMERA_POS.x -= 1.0f32 },
      (glfw::Press, glfw::KeyLeft) => unsafe { CAMERA_POS.x += 1.0f32 },
      _ => {}
    }
  }
}

fn main() {
  glfw::set_error_callback(~ErrorContext);
  do glfw::start {
    // glfw::window_hint::context_version(3, 2);
    let win =  Win::new();
    while win.is_running() {
      win.process_events();
      win.draw();
    }
    win.cleanup();
  }
}

#[start]
fn start(argc: int, argv: **u8) -> int {
  std::rt::start_on_main_thread(argc, argv, main)
}

// vim: set tabstop=2 shiftwidth=2 softtabstop=2 expandtab:
<|endoftext|>


<commit_before>use expression::predicates::Or;
use query_builder::insert_statement::{IncompleteInsertStatement, Insert};
use super::nodes::Replace;
/// Creates a SQLite `INSERT OR REPLACE` statement. If a constraint violation
/// fails, SQLite will attempt to replace the offending row instead.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # include!("src/doctest_setup.rs");
/// #
/// # table! {
/// #     users {
/// #         id -> Integer,
/// #         name -> VarChar,
/// #     }
/// # }
/// #
/// # #[derive(Insertable)]
/// # #[table_name="users"]
/// # struct User<'a> {
/// #     id: i32,
/// #     name: &'a str,
/// # }
/// #
/// #
/// # fn main() {
/// #     use self::users::dsl::*;
/// #     use self::diesel::{insert, insert_or_replace};
/// #     use self::diesel::sqlite::SqliteConnection;
/// #
/// #     let conn = SqliteConnection::establish(":memory:").unwrap();
/// #     conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR)").unwrap();
/// insert(&NewUser::new("Sean")).into(users).execute(&conn).unwrap();
/// insert(&NewUser::new("Tess")).into(users).execute(&conn).unwrap();
///
/// let new_user = User { id: 1, name: "Jim" };
/// insert_or_replace(&new_user).into(users).execute(&conn).unwrap();
///
/// let names = users.select(name).order(id).load::<String>(&conn);
/// assert_eq!(Ok(vec!["Jim".into(), "Tess".into()]), names);
/// # }
/// ```
pub fn insert_or_replace<'a, T: ?Sized>(records: &'a T)
    -> IncompleteInsertStatement<&'a T, Or<Insert, Replace>>
{
    IncompleteInsertStatement::new(records, Or::new(Insert, Replace))
}
<commit_msg>Add missing `extern crate` to SQLite doctest.<commit_after>use expression::predicates::Or;
use query_builder::insert_statement::{IncompleteInsertStatement, Insert};
use super::nodes::Replace;
/// Creates a SQLite `INSERT OR REPLACE` statement. If a constraint violation
/// fails, SQLite will attempt to replace the offending row instead.
///
/// # Example
///
/// ```rust
/// # #[macro_use] extern crate diesel;
/// # #[macro_use] extern crate diesel_codegen;
/// # include!("src/doctest_setup.rs");
/// #
/// # table! {
/// #     users {
/// #         id -> Integer,
/// #         name -> VarChar,
/// #     }
/// # }
/// #
/// # #[derive(Insertable)]
/// # #[table_name="users"]
/// # struct User<'a> {
/// #     id: i32,
/// #     name: &'a str,
/// # }
/// #
/// #
/// # fn main() {
/// #     use self::users::dsl::*;
/// #     use self::diesel::{insert, insert_or_replace};
/// #     use self::diesel::sqlite::SqliteConnection;
/// #
/// #     let conn = SqliteConnection::establish(":memory:").unwrap();
/// #     conn.execute("CREATE TABLE users (id INTEGER PRIMARY KEY AUTOINCREMENT, name VARCHAR)").unwrap();
/// insert(&NewUser::new("Sean")).into(users).execute(&conn).unwrap();
/// insert(&NewUser::new("Tess")).into(users).execute(&conn).unwrap();
///
/// let new_user = User { id: 1, name: "Jim" };
/// insert_or_replace(&new_user).into(users).execute(&conn).unwrap();
///
/// let names = users.select(name).order(id).load::<String>(&conn);
/// assert_eq!(Ok(vec!["Jim".into(), "Tess".into()]), names);
/// # }
/// ```
pub fn insert_or_replace<'a, T: ?Sized>(records: &'a T)
    -> IncompleteInsertStatement<&'a T, Or<Insert, Replace>>
{
    IncompleteInsertStatement::new(records, Or::new(Insert, Replace))
}
<|endoftext|>