<commit_before>// Copyright (C) 2017, 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::firmware::{
    self,
    installation_set::{self, Set},
};
use chrono::{DateTime, NaiveDateTime, Utc};
use derive_more::{Deref, DerefMut};
use sdk::api::info::runtime_settings as api;
use slog_scope::debug;
use std::{fs, io, path::Path};
use thiserror::Error;

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

#[derive(Debug, Error)]
pub enum Error {
    #[error("IO error: {0}")]
    Io(#[from] io::Error),
    #[error("Fail with serialization/deserialization: {0}")]
    SerdeJson(#[from] serde_json::Error),
    #[error("Firmware error: {0}")]
    FirmwareError(#[from] firmware::Error),

    #[error("Invalid runtime settings destination")]
    InvalidDestination,
}

#[derive(Debug, Deref, DerefMut, PartialEq)]
pub(crate) struct RuntimeSettings(pub(crate) api::RuntimeSettings);

impl Default for RuntimeSettings {
    fn default() -> Self {
        RuntimeSettings(api::RuntimeSettings {
            polling: api::RuntimePolling {
                last: DateTime::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc),
                retries: 0,
                now: false,
                server_address: api::ServerAddress::Default,
            },
            update: api::RuntimeUpdate { upgrade_to_installation: None, applied_package_uid: None },
            path: std::path::PathBuf::new(),
            persistent: false,
        })
    }
}

impl RuntimeSettings {
    pub(crate) fn load(path: &Path) -> Result<Self> {
        let mut this = if path.exists() {
            debug!("Loading runtime settings from {:?}...", path);
            Self::parse(&fs::read_to_string(path)?)?
        } else {
            debug!(
                "Runtime settings file {:?} does not exists. Using default runtime settings...",
                path
            );
            Self::default()
        };

        this.path = path.to_path_buf();
        Ok(this)
    }

    fn parse(content: &str) -> Result<Self> {
        Ok(RuntimeSettings(serde_json::from_str::<api::RuntimeSettings>(&content)?))
    }

    fn save(&self) -> Result<()> {
        if !self.persistent {
            debug!("Skipping runtime settings save, using non-persistent.");
            return Ok(());
        }

        let parent = self.path.parent().ok_or_else(|| Error::InvalidDestination)?;
        if !parent.exists() {
            debug!("Creating runtime settings to store state.");
            fs::create_dir_all(parent)?;
        }

        debug!("Saving runtime settings from {:?}...", &self.path);
        fs::write(&self.path, self.serialize()?)?;

        Ok(())
    }

    fn serialize(&self) -> Result<String> {
        Ok(serde_json::to_string(&self.0)?)
    }

    pub(crate) fn get_inactive_installation_set(&self) -> Result<Set> {
        Ok(match self.update.upgrade_to_installation {
            // If upgrade_to_installation has already been set
            // the current inactive installation_set will already be swapped
            // so we can just install over the same one as before
            Some(s) => Set(s),
            // If no installation has been made so far we can check
            // the system for the current inactive installation set
            None => installation_set::inactive()?,
        })
    }

    pub(crate) fn enable_persistency(&mut self) {
        self.persistent = true;
    }

    pub(crate) fn is_polling_forced(&self) -> bool {
        self.polling.now
    }

    pub(crate) fn force_poll(&mut self) -> Result<()> {
        self.polling.now = true;
        self.save()
    }

    pub(crate) fn retries(&self) -> usize {
        self.polling.retries
    }

    pub(crate) fn inc_retries(&mut self) {
        self.polling.retries += 1;
    }

    pub(crate) fn clear_retries(&mut self) {
        self.polling.retries = 0;
    }

    pub(crate) fn last_polling(&self) -> DateTime<Utc> {
        self.polling.last
    }

    pub(crate) fn set_last_polling(&mut self, last_polling: DateTime<Utc>) -> Result<()> {
        self.polling.last = last_polling;
        self.save()
    }

    pub(crate) fn applied_package_uid(&self) -> Option<String> {
        self.update.applied_package_uid.clone()
    }

    pub(crate) fn set_applied_package_uid(&mut self, applied_package_uid: &str) -> Result<()> {
        self.update.applied_package_uid = Some(applied_package_uid.to_string());
        self.save()
    }

    pub(crate) fn set_upgrading_to(&mut self, new_install_set: Set) -> Result<()> {
        self.update.upgrade_to_installation = Some(new_install_set.0);
        self.save()
    }

    pub(crate) fn custom_server_address(&self) -> Option<&str> {
        match &self.polling.server_address {
            api::ServerAddress::Custom(s) => Some(s),
            api::ServerAddress::Default => None,
        }
    }

    pub(crate) fn set_custom_server_address(&mut self, server_address: &str) {
        self.polling.server_address = api::ServerAddress::Custom(server_address.to_owned());
    }

    /// Reset settings that are only need through a single installation
    pub(crate) fn reset_transient_settings(&mut self) {
        // Server address is reset so it doesn't keep probing the last custom server
        // requested
        self.polling.server_address = api::ServerAddress::Default;
    }

    pub(crate) fn reset_installation_settings(&mut self) -> Result<()> {
        self.update.upgrade_to_installation = None;
        self.update.applied_package_uid = None;
        self.save()
    }
}

#[test]
fn default() {
    use pretty_assertions::assert_eq;
    let settings = RuntimeSettings::default();
    let expected = RuntimeSettings(api::RuntimeSettings {
        polling: api::RuntimePolling {
            last: DateTime::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc),
            retries: 0,
            now: false,
            server_address: api::ServerAddress::Default,
        },
        update: api::RuntimeUpdate { upgrade_to_installation: None, applied_package_uid: None },
        path: std::path::PathBuf::new(),
        persistent: false,
    });

    assert_eq!(Some(settings), Some(expected));
}

#[test]
fn load_and_save() {
    use pretty_assertions::assert_eq;
    use std::fs;
    use tempfile::NamedTempFile;

    let tempfile = NamedTempFile::new().unwrap();
    let settings_file = tempfile.path();
    fs::remove_file(&settings_file).unwrap();

    let mut settings = RuntimeSettings::load(settings_file).unwrap();
    settings.force_poll().unwrap();

    let new_settings = RuntimeSettings::load(settings_file).unwrap();

    assert_eq!(settings.update, new_settings.update);
}
<commit_msg>updatehub: Fail safety for badly formatted Runtime Settings file<commit_after>// Copyright (C) 2017, 2018 O.S. Systems Sofware LTDA
//
// SPDX-License-Identifier: Apache-2.0

use crate::firmware::{
    self,
    installation_set::{self, Set},
};
use chrono::{DateTime, NaiveDateTime, Utc};
use derive_more::{Deref, DerefMut};
use sdk::api::info::runtime_settings as api;
use slog_scope::{debug, warn};
use std::{fs, io, path::Path};
use thiserror::Error;

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

#[derive(Debug, Error)]
pub enum Error {
    #[error("IO error: {0}")]
    Io(#[from] io::Error),
    #[error("Fail with serialization/deserialization: {0}")]
    SerdeJson(#[from] serde_json::Error),
    #[error("Firmware error: {0}")]
    FirmwareError(#[from] firmware::Error),

    #[error("Invalid runtime settings destination")]
    InvalidDestination,
}

#[derive(Debug, Deref, DerefMut, PartialEq)]
pub(crate) struct RuntimeSettings(pub(crate) api::RuntimeSettings);

impl Default for RuntimeSettings {
    fn default() -> Self {
        RuntimeSettings(api::RuntimeSettings {
            polling: api::RuntimePolling {
                last: DateTime::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc),
                retries: 0,
                now: false,
                server_address: api::ServerAddress::Default,
            },
            update: api::RuntimeUpdate { upgrade_to_installation: None, applied_package_uid: None },
            path: std::path::PathBuf::new(),
            persistent: false,
        })
    }
}

impl RuntimeSettings {
    pub(crate) fn load(path: &Path) -> Result<Self> {
        let mut this = if path.exists() {
            debug!("Loading runtime settings from {:?}...", path);
            match fs::read_to_string(path).map_err(Error::from).and_then(|ref s| Self::parse(s)) {
                Ok(v) => v,
                Err(e) => {
                    warn!("Failed to load current runtime settings: {}", e);
                    let _ = fs::rename(
                        path,
                        path.with_file_name(format!(
                            "{}.old",
                            path.file_name().unwrap().to_str().unwrap()
                        )),
                    );
                    debug!("Using default runtime settings...");
                    Self::default()
                }
            }
        } else {
            debug!(
                "Runtime settings file {:?} does not exists. Using default runtime settings...",
                path
            );
            Self::default()
        };

        this.path = path.to_path_buf();
        Ok(this)
    }

    fn parse(content: &str) -> Result<Self> {
        Ok(RuntimeSettings(serde_json::from_str::<api::RuntimeSettings>(&content)?))
    }

    fn save(&self) -> Result<()> {
        if !self.persistent {
            debug!("Skipping runtime settings save, using non-persistent.");
            return Ok(());
        }

        let parent = self.path.parent().ok_or_else(|| Error::InvalidDestination)?;
        if !parent.exists() {
            debug!("Creating runtime settings to store state.");
            fs::create_dir_all(parent)?;
        }

        debug!("Saving runtime settings from {:?}...", &self.path);
        fs::write(&self.path, self.serialize()?)?;

        Ok(())
    }

    fn serialize(&self) -> Result<String> {
        Ok(serde_json::to_string(&self.0)?)
    }

    pub(crate) fn get_inactive_installation_set(&self) -> Result<Set> {
        Ok(match self.update.upgrade_to_installation {
            // If upgrade_to_installation has already been set
            // the current inactive installation_set will already be swapped
            // so we can just install over the same one as before
            Some(s) => Set(s),
            // If no installation has been made so far we can check
            // the system for the current inactive installation set
            None => installation_set::inactive()?,
        })
    }

    pub(crate) fn enable_persistency(&mut self) {
        self.persistent = true;
    }

    pub(crate) fn is_polling_forced(&self) -> bool {
        self.polling.now
    }

    pub(crate) fn force_poll(&mut self) -> Result<()> {
        self.polling.now = true;
        self.save()
    }

    pub(crate) fn retries(&self) -> usize {
        self.polling.retries
    }

    pub(crate) fn inc_retries(&mut self) {
        self.polling.retries += 1;
    }

    pub(crate) fn clear_retries(&mut self) {
        self.polling.retries = 0;
    }

    pub(crate) fn last_polling(&self) -> DateTime<Utc> {
        self.polling.last
    }

    pub(crate) fn set_last_polling(&mut self, last_polling: DateTime<Utc>) -> Result<()> {
        self.polling.last = last_polling;
        self.save()
    }

    pub(crate) fn applied_package_uid(&self) -> Option<String> {
        self.update.applied_package_uid.clone()
    }

    pub(crate) fn set_applied_package_uid(&mut self, applied_package_uid: &str) -> Result<()> {
        self.update.applied_package_uid = Some(applied_package_uid.to_string());
        self.save()
    }

    pub(crate) fn set_upgrading_to(&mut self, new_install_set: Set) -> Result<()> {
        self.update.upgrade_to_installation = Some(new_install_set.0);
        self.save()
    }

    pub(crate) fn custom_server_address(&self) -> Option<&str> {
        match &self.polling.server_address {
            api::ServerAddress::Custom(s) => Some(s),
            api::ServerAddress::Default => None,
        }
    }

    pub(crate) fn set_custom_server_address(&mut self, server_address: &str) {
        self.polling.server_address = api::ServerAddress::Custom(server_address.to_owned());
    }

    /// Reset settings that are only need through a single installation
    pub(crate) fn reset_transient_settings(&mut self) {
        // Server address is reset so it doesn't keep probing the last custom server
        // requested
        self.polling.server_address = api::ServerAddress::Default;
    }

    pub(crate) fn reset_installation_settings(&mut self) -> Result<()> {
        self.update.upgrade_to_installation = None;
        self.update.applied_package_uid = None;
        self.save()
    }
}

#[test]
fn default() {
    use pretty_assertions::assert_eq;
    let settings = RuntimeSettings::default();
    let expected = RuntimeSettings(api::RuntimeSettings {
        polling: api::RuntimePolling {
            last: DateTime::from_utc(NaiveDateTime::from_timestamp(0, 0), Utc),
            retries: 0,
            now: false,
            server_address: api::ServerAddress::Default,
        },
        update: api::RuntimeUpdate { upgrade_to_installation: None, applied_package_uid: None },
        path: std::path::PathBuf::new(),
        persistent: false,
    });

    assert_eq!(Some(settings), Some(expected));
}

#[test]
fn load_and_save() {
    use pretty_assertions::assert_eq;
    use std::fs;
    use tempfile::NamedTempFile;

    let tempfile = NamedTempFile::new().unwrap();
    let settings_file = tempfile.path();
    fs::remove_file(&settings_file).unwrap();

    let mut settings = RuntimeSettings::load(settings_file).unwrap();
    settings.force_poll().unwrap();

    let new_settings = RuntimeSettings::load(settings_file).unwrap();

    assert_eq!(settings.update, new_settings.update);
}

#[test]
fn load_bad_formated_file() {
    use pretty_assertions::assert_eq;
    use std::fs;
    use tempfile::NamedTempFile;

    let tempfile = NamedTempFile::new().unwrap();
    let settings_file = tempfile.path();
    fs::write(&settings_file, "foo").unwrap();

    let load_result = RuntimeSettings::load(settings_file);
    assert!(load_result.is_ok(), "We should fail when reading a unformated formatted file");

    let old_file = settings_file
        .with_file_name(format!("{}.old", settings_file.file_name().unwrap().to_str().unwrap()));
    let old_content = fs::read_to_string(&old_file).unwrap();
    assert_eq!(
        old_content, "foo",
        "Old file should still be accessible as a .old file in the same directory"
    );
    fs::remove_file(old_file).unwrap();
}
<|endoftext|>


<commit_before>use dao::Dao;
use std::slice;
use value::Value;

/// use this to store data retrieved from the database
/// This is also slimmer than Vec<Dao> when serialized
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Rows {
    pub columns: Vec<String>,
    pub data: Vec<Vec<Value>>,
    /// can be optionally set, indicates how many total rows are there in the table
    pub count: Option<u64>,
}

impl Rows {
    pub fn empty() -> Self {
        Rows::new(vec![])
    }
    pub fn new(columns: Vec<String>) -> Self {
        Rows {
            columns,
            data: vec![],
            count: None,
        }
    }

    pub fn push(&mut self, row: Vec<Value>) {
        self.data.push(row)
    }

    /// Returns an iterator over the `Row`s.
    pub fn iter<'a>(&'a self) -> Iter<'a> {
        Iter {
            columns: &self.columns,
            iter: self.data.iter(),
        }
    }
}

impl<'a> IntoIterator for &'a Rows {
    type Item = Dao<'a>;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        self.iter()
    }
}

/// An iterator over `Row`s.
pub struct Iter<'a> {
    columns: &'a Vec<String>,
    iter: slice::Iter<'a, Vec<Value>>,
}

impl<'a> Iterator for Iter<'a> {
    type Item = Dao<'a>;

    fn next(&mut self) -> Option<Dao<'a>> {
        self.iter.next().map(|row| {
            let mut dao = Dao::new();
            for (i, column) in self.columns.iter().enumerate() {
                dao.insert(column, row[i].clone());
            }
            dao
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a> DoubleEndedIterator for Iter<'a> {
    fn next_back(&mut self) -> Option<Dao<'a>> {
        self.iter.next_back().map(|row| {
            let mut dao = Dao::new();
            for (i, column) in self.columns.iter().enumerate() {
                dao.insert(column, row[i].clone());
            }
            dao
        })
    }
}

impl<'a> ExactSizeIterator for Iter<'a> {}

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

    #[test]
    fn iteration_count() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![vec![1.into(), "ivanceras".into()]];
        let rows = Rows {
            columns: columns,
            data: data,
        };
        assert_eq!(1, rows.iter().count());
    }

    #[test]
    fn iteration_count2() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![
            vec![1.into(), "ivanceras".into()],
            vec![2.into(), "lee".into()],
        ];
        let rows = Rows {
            columns: columns,
            data: data,
        };
        assert_eq!(2, rows.iter().count());
    }

    #[test]
    fn dao() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![vec![1.into(), "ivanceras".into()]];
        let rows = Rows {
            columns: columns,
            data: data,
        };
        let mut dao = Dao::new();
        dao.insert("id", 1);
        dao.insert("username", "ivanceras");
        assert_eq!(dao, rows.iter().next().unwrap());
    }

    #[test]
    fn dao2() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![
            vec![1.into(), "ivanceras".into()],
            vec![2.into(), "lee".into()],
        ];
        let rows = Rows {
            columns: columns,
            data: data,
        };
        let mut iter = rows.iter();
        let mut dao = Dao::new();
        dao.insert("id", 1);
        dao.insert("username", "ivanceras");
        assert_eq!(dao, iter.next().unwrap());

        let mut dao2 = Dao::new();
        dao2.insert("id", 2);
        dao2.insert("username", "lee");
        assert_eq!(dao2, iter.next().unwrap());
    }

    #[test]
    fn from_back() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![
            vec![1.into(), "ivanceras".into()],
            vec![2.into(), "lee".into()],
        ];
        let rows = Rows {
            columns: columns,
            data: data,
        };
        let mut iter = rows.iter();
        let mut dao2 = Dao::new();
        dao2.insert("id", 2);
        dao2.insert("username", "lee");
        assert_eq!(dao2, iter.next_back().unwrap());

        let mut dao = Dao::new();
        dao.insert("id", 1);
        dao.insert("username", "ivanceras");
        assert_eq!(dao, iter.next_back().unwrap());
    }

    #[test]
    fn into_iter() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![
            vec![1.into(), "ivanceras".into()],
            vec![2.into(), "lee".into()],
        ];
        let rows = Rows {
            columns: columns,
            data: data,
        };
        let mut iter = rows.into_iter();
        let mut dao = Dao::new();
        dao.insert("id", 1);
        dao.insert("username", "ivanceras");
        assert_eq!(dao, iter.next().unwrap());

        let mut dao2 = Dao::new();
        dao2.insert("id", 2);
        dao2.insert("username", "lee");
        assert_eq!(dao2, iter.next().unwrap());

        assert_eq!(2, rows.iter().count());
    }
}
<commit_msg>Fix tests<commit_after>use dao::Dao;
use std::slice;
use value::Value;

/// use this to store data retrieved from the database
/// This is also slimmer than Vec<Dao> when serialized
#[derive(Debug, Serialize, Deserialize, Clone)]
pub struct Rows {
    pub columns: Vec<String>,
    pub data: Vec<Vec<Value>>,
    /// can be optionally set, indicates how many total rows are there in the table
    pub count: Option<u64>,
}

impl Rows {
    pub fn empty() -> Self {
        Rows::new(vec![])
    }
    pub fn new(columns: Vec<String>) -> Self {
        Rows {
            columns,
            data: vec![],
            count: None,
        }
    }

    pub fn push(&mut self, row: Vec<Value>) {
        self.data.push(row)
    }

    /// Returns an iterator over the `Row`s.
    pub fn iter<'a>(&'a self) -> Iter<'a> {
        Iter {
            columns: &self.columns,
            iter: self.data.iter(),
        }
    }
}

impl<'a> IntoIterator for &'a Rows {
    type Item = Dao<'a>;
    type IntoIter = Iter<'a>;

    fn into_iter(self) -> Iter<'a> {
        self.iter()
    }
}

/// An iterator over `Row`s.
pub struct Iter<'a> {
    columns: &'a Vec<String>,
    iter: slice::Iter<'a, Vec<Value>>,
}

impl<'a> Iterator for Iter<'a> {
    type Item = Dao<'a>;

    fn next(&mut self) -> Option<Dao<'a>> {
        self.iter.next().map(|row| {
            let mut dao = Dao::new();
            for (i, column) in self.columns.iter().enumerate() {
                dao.insert(column, row[i].clone());
            }
            dao
        })
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        self.iter.size_hint()
    }
}

impl<'a> DoubleEndedIterator for Iter<'a> {
    fn next_back(&mut self) -> Option<Dao<'a>> {
        self.iter.next_back().map(|row| {
            let mut dao = Dao::new();
            for (i, column) in self.columns.iter().enumerate() {
                dao.insert(column, row[i].clone());
            }
            dao
        })
    }
}

impl<'a> ExactSizeIterator for Iter<'a> {}

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

    #[test]
    fn iteration_count() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![vec![1.into(), "ivanceras".into()]];
        let rows = Rows {
            columns: columns,
            data: data,
            count: None,
        };
        assert_eq!(1, rows.iter().count());
    }

    #[test]
    fn iteration_count2() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![
            vec![1.into(), "ivanceras".into()],
            vec![2.into(), "lee".into()],
        ];
        let rows = Rows {
            columns: columns,
            data: data,
            count: None,
        };
        assert_eq!(2, rows.iter().count());
    }

    #[test]
    fn dao() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![vec![1.into(), "ivanceras".into()]];
        let rows = Rows {
            columns: columns,
            data: data,
            count: None,
        };
        let mut dao = Dao::new();
        dao.insert("id", 1);
        dao.insert("username", "ivanceras");
        assert_eq!(dao, rows.iter().next().unwrap());
    }

    #[test]
    fn dao2() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![
            vec![1.into(), "ivanceras".into()],
            vec![2.into(), "lee".into()],
        ];
        let rows = Rows {
            columns: columns,
            data: data,
            count: None,
        };
        let mut iter = rows.iter();
        let mut dao = Dao::new();
        dao.insert("id", 1);
        dao.insert("username", "ivanceras");
        assert_eq!(dao, iter.next().unwrap());

        let mut dao2 = Dao::new();
        dao2.insert("id", 2);
        dao2.insert("username", "lee");
        assert_eq!(dao2, iter.next().unwrap());
    }

    #[test]
    fn from_back() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![
            vec![1.into(), "ivanceras".into()],
            vec![2.into(), "lee".into()],
        ];
        let rows = Rows {
            columns: columns,
            data: data,
            count: None,
        };
        let mut iter = rows.iter();
        let mut dao2 = Dao::new();
        dao2.insert("id", 2);
        dao2.insert("username", "lee");
        assert_eq!(dao2, iter.next_back().unwrap());

        let mut dao = Dao::new();
        dao.insert("id", 1);
        dao.insert("username", "ivanceras");
        assert_eq!(dao, iter.next_back().unwrap());
    }

    #[test]
    fn into_iter() {
        let columns = vec!["id".to_string(), "username".to_string()];
        let data: Vec<Vec<Value>> = vec![
            vec![1.into(), "ivanceras".into()],
            vec![2.into(), "lee".into()],
        ];
        let rows = Rows {
            columns: columns,
            data: data,
            count: None,
        };
        let mut iter = rows.into_iter();
        let mut dao = Dao::new();
        dao.insert("id", 1);
        dao.insert("username", "ivanceras");
        assert_eq!(dao, iter.next().unwrap());

        let mut dao2 = Dao::new();
        dao2.insert("id", 2);
        dao2.insert("username", "lee");
        assert_eq!(dao2, iter.next().unwrap());

        assert_eq!(2, rows.iter().count());
    }
}
<|endoftext|>


<commit_before>use toml::Value;

use libimagerror::into::IntoError;
use libimagutil::edit::edit_in_tmpfile_with_command;

use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::MapErrInto;
use vcs::git::result::Result;

use vcs::git::action::StoreAction;

use git2::Repository;

pub fn commit_interactive(config: &Value) -> bool {
    match config.lookup("commit.interactive") {
        Some(&Value::Boolean(b)) => b,
        Some(_) => {
            warn!("Configuration error, 'store.hooks.stdhook_git_update.commit.interactive' must be a Boolean.");
            warn!("Defaulting to commit.interactive = false");
            false
        }
        None => {
            warn!("Unavailable configuration for");
            warn!("\t'store.hooks.stdhook_git_update.commit.interactive'");
            warn!("Defaulting to false");
            false
        }
    }
}

fn commit_with_editor(config: &Value) -> bool {
    match config.lookup("commit.interactive_editor") {
        Some(&Value::Boolean(b)) => b,
        Some(_) => {
            warn!("Configuration error, 'store.hooks.stdhook_git_update.commit.interactive_editor' must be a Boolean.");
            warn!("Defaulting to commit.interactive_editor = false");
            false
        }
        None => {
            warn!("Unavailable configuration for");
            warn!("\t'store.hooks.stdhook_git_update.commit.interactive_editor'");
            warn!("Defaulting to false");
            false
        }
    }
}

fn commit_default_msg<'a>(config: &'a Value) -> &'a str {
    match config.lookup("commit.message") {
        Some(&Value::String(ref b)) => b,
        Some(_) => {
            warn!("Configuration error, 'store.hooks.stdhook_git_update.commit.message' must be a String.");
            warn!("Defaulting to commit.message = 'Update'");
            "Update"
        }
        None => {
            warn!("Unavailable configuration for");
            warn!("\t'store.hooks.stdhook_git_update.commit.message'");
            warn!("Defaulting to commit.message = 'Update'");
            "Update"
        }
    }
}

fn commit_template() -> &'static str {
    "Commit template"
}

pub fn commit_message(repo: &Repository, config: &Value, action: StoreAction) -> Result<String> {
    use libimaginteraction::ask::ask_string;
    use libimagutil::edit::edit_in_tmpfile_with_command;
    use std::process::Command;

    if commit_interactive(config) {
        if commit_with_editor(config) {
            repo.config()
                .map_err_into(GHEK::GitConfigFetchError)
                .and_then(|c| c.get_string("core.editor").map_err_into(GHEK::GitConfigEditorFetchError))
                .map_err_into(GHEK::ConfigError)
                .map(Command::new)
                .and_then(|cmd| {
                    let mut s = String::from(commit_template());
                    edit_in_tmpfile_with_command(cmd, &mut s).map(|_| s)
                        .map_err_into(GHEK::EditorError)
                })
        } else {
            Ok(ask_string("Commit Message", None, false, false, None, "> "))
        }
    } else {
        Ok(String::from(commit_default_msg(config)))
    }
}

pub fn abort_on_repo_init_err(cfg: Option<&Value>) -> bool {
    get_bool_cfg(cfg, "abort_on_repo_init_failure", true, true)
}

pub fn ensure_branch(cfg: Option<&Value>) -> Result<Option<String>> {
    match cfg {
        Some(cfg) => {
            match cfg.lookup("ensure_branch") {
                Some(&Value::String(ref s)) => Ok(Some(s.clone())),
                Some(_) => {
                    warn!("Configuration error, 'ensure_branch' must be a String.");
                    Err(GHEK::ConfigTypeError.into_error())
                        .map_err_into(GHEK::ConfigTypeError)
                },
                None => {
                    debug!("No key `ensure_branch'");
                    Ok(None)
                },
            }
        },
        None => Ok(None),
    }
}

pub fn do_checkout_ensure_branch(cfg: Option<&Value>) -> bool {
    get_bool_cfg(cfg, "try_checkout_ensure_branch", true, true)
}

fn get_bool_cfg(cfg: Option<&Value>, name: &str, on_fail: bool, on_unavail: bool) -> bool {
    cfg.map(|cfg| {
        match cfg.lookup(name) {
            Some(&Value::Boolean(b)) => b,
            Some(_) => {
                warn!("Configuration error, '{}' must be a Boolean (true|false).", name);
                warn!("Assuming '{}' now.", on_fail);
                on_fail
            },
            None => {
                debug!("No key '{}' - Assuming '{}'", name, on_unavail);
                on_unavail
            },
        }
    })
    .unwrap_or(on_unavail)
}

<commit_msg>Remove unused import: config module<commit_after>use toml::Value;

use libimagerror::into::IntoError;

use vcs::git::error::GitHookErrorKind as GHEK;
use vcs::git::error::MapErrInto;
use vcs::git::result::Result;

use vcs::git::action::StoreAction;

use git2::Repository;

pub fn commit_interactive(config: &Value) -> bool {
    match config.lookup("commit.interactive") {
        Some(&Value::Boolean(b)) => b,
        Some(_) => {
            warn!("Configuration error, 'store.hooks.stdhook_git_update.commit.interactive' must be a Boolean.");
            warn!("Defaulting to commit.interactive = false");
            false
        }
        None => {
            warn!("Unavailable configuration for");
            warn!("\t'store.hooks.stdhook_git_update.commit.interactive'");
            warn!("Defaulting to false");
            false
        }
    }
}

fn commit_with_editor(config: &Value) -> bool {
    match config.lookup("commit.interactive_editor") {
        Some(&Value::Boolean(b)) => b,
        Some(_) => {
            warn!("Configuration error, 'store.hooks.stdhook_git_update.commit.interactive_editor' must be a Boolean.");
            warn!("Defaulting to commit.interactive_editor = false");
            false
        }
        None => {
            warn!("Unavailable configuration for");
            warn!("\t'store.hooks.stdhook_git_update.commit.interactive_editor'");
            warn!("Defaulting to false");
            false
        }
    }
}

fn commit_default_msg<'a>(config: &'a Value) -> &'a str {
    match config.lookup("commit.message") {
        Some(&Value::String(ref b)) => b,
        Some(_) => {
            warn!("Configuration error, 'store.hooks.stdhook_git_update.commit.message' must be a String.");
            warn!("Defaulting to commit.message = 'Update'");
            "Update"
        }
        None => {
            warn!("Unavailable configuration for");
            warn!("\t'store.hooks.stdhook_git_update.commit.message'");
            warn!("Defaulting to commit.message = 'Update'");
            "Update"
        }
    }
}

fn commit_template() -> &'static str {
    "Commit template"
}

pub fn commit_message(repo: &Repository, config: &Value, action: StoreAction) -> Result<String> {
    use libimaginteraction::ask::ask_string;
    use libimagutil::edit::edit_in_tmpfile_with_command;
    use std::process::Command;

    if commit_interactive(config) {
        if commit_with_editor(config) {
            repo.config()
                .map_err_into(GHEK::GitConfigFetchError)
                .and_then(|c| c.get_string("core.editor").map_err_into(GHEK::GitConfigEditorFetchError))
                .map_err_into(GHEK::ConfigError)
                .map(Command::new)
                .and_then(|cmd| {
                    let mut s = String::from(commit_template());
                    edit_in_tmpfile_with_command(cmd, &mut s).map(|_| s)
                        .map_err_into(GHEK::EditorError)
                })
        } else {
            Ok(ask_string("Commit Message", None, false, false, None, "> "))
        }
    } else {
        Ok(String::from(commit_default_msg(config)))
    }
}

pub fn abort_on_repo_init_err(cfg: Option<&Value>) -> bool {
    get_bool_cfg(cfg, "abort_on_repo_init_failure", true, true)
}

pub fn ensure_branch(cfg: Option<&Value>) -> Result<Option<String>> {
    match cfg {
        Some(cfg) => {
            match cfg.lookup("ensure_branch") {
                Some(&Value::String(ref s)) => Ok(Some(s.clone())),
                Some(_) => {
                    warn!("Configuration error, 'ensure_branch' must be a String.");
                    Err(GHEK::ConfigTypeError.into_error())
                        .map_err_into(GHEK::ConfigTypeError)
                },
                None => {
                    debug!("No key `ensure_branch'");
                    Ok(None)
                },
            }
        },
        None => Ok(None),
    }
}

pub fn do_checkout_ensure_branch(cfg: Option<&Value>) -> bool {
    get_bool_cfg(cfg, "try_checkout_ensure_branch", true, true)
}

fn get_bool_cfg(cfg: Option<&Value>, name: &str, on_fail: bool, on_unavail: bool) -> bool {
    cfg.map(|cfg| {
        match cfg.lookup(name) {
            Some(&Value::Boolean(b)) => b,
            Some(_) => {
                warn!("Configuration error, '{}' must be a Boolean (true|false).", name);
                warn!("Assuming '{}' now.", on_fail);
                on_fail
            },
            None => {
                debug!("No key '{}' - Assuming '{}'", name, on_unavail);
                on_unavail
            },
        }
    })
    .unwrap_or(on_unavail)
}

<|endoftext|>


<commit_before>use encoding;

import io::writer_util;
import encoding::base64;

fn main(args: [str]) {
    let mut args = args;
    let binary = vec::shift(args);
    let stdout = io::stdout(), stderr = io::stderr();
    let b64 = base64::mk();
    if vec::len(args) < 2u {
        stderr.write_line(#fmt["Usage: %s <mode> <filename>", binary]);
        ret;
    }
    alt io::read_whole_file(args[1]) {
      result::ok(data) {
        let res = alt args[0] {
          "encode" { b64.encode_bytes(data) }
          "decode" { b64.decode_bytes(data) }
          _ { ret; }
        };
        stdout.write(res);
      }
      result::err(msg) {
        stderr.write_line(#fmt["Error: %s", msg]);
      }
    }
}
<commit_msg>examples: update b64.rs<commit_after>use encoding;

import io::writer_util;
import encoding::base64;

fn main(args: [str]) {
    let mut args = args;
    let binary = vec::shift(args);
    let stdout = io::stdout();
    let stderr = io::stderr();

    if vec::len(args) < 2u {
        stderr.write_line(#fmt["Usage: %s <mode> <filename>", binary]);
        ret;
    }

    alt io::read_whole_file(args[1]) {
      result::ok(data) {
        let res = alt args[0] {
          "encode" { base64::encode(data) }
          "decode" { base64::decode(data) }
          _ { ret; }
        };
        stdout.write(res);
      }
      result::err(msg) {
        stderr.write_line(#fmt["Error: %s", msg]);
      }
    }
}
<|endoftext|>


<commit_before>#![allow(unused_variables)]

extern crate nalgebra as na;

use na::{Vector3, Point3, Isometry3, Perspective3};

fn main() {
    // Our object is translated along the x axis.
    let model = Isometry3::new(Vector3::x(), na::zero());

    // Our camera looks toward the point (1.0, 0.0, 0.0).
    // It is located at (0.0, 0.0, 1.0).
    let eye    = Point3::new(0.0, 0.0, 1.0);
    let target = Point3::new(1.0, 0.0, 0.0);
    let view   = Isometry3::look_at_rh(&eye, &target, &Vector3::y());

    // A perspective projection.
    let projection = Perspective3::new(16.0 / 9.0, 3.14 / 2.0, 1.0, 1000.0);

    // The combination of the model with the view is still an isometry.
    let model_view = model * view;

    // Convert everything to a `Matrix4` so that they can be combined.
    let mat_model_view = model_view.to_homogeneous();

    // Combine everything.
    let model_view_projection = projection.as_matrix() * mat_model_view;
}
<commit_msg>Fix mvp matrix construction typo.<commit_after>#![allow(unused_variables)]

extern crate nalgebra as na;

use na::{Vector3, Point3, Isometry3, Perspective3};

fn main() {
    // Our object is translated along the x axis.
    let model = Isometry3::new(Vector3::x(), na::zero());

    // Our camera looks toward the point (1.0, 0.0, 0.0).
    // It is located at (0.0, 0.0, 1.0).
    let eye    = Point3::new(0.0, 0.0, 1.0);
    let target = Point3::new(1.0, 0.0, 0.0);
    let view   = Isometry3::look_at_rh(&eye, &target, &Vector3::y());

    // A perspective projection.
    let projection = Perspective3::new(16.0 / 9.0, 3.14 / 2.0, 1.0, 1000.0);

    // The combination of the model with the view is still an isometry.
    let model_view = view * model;

    // Convert everything to a `Matrix4` so that they can be combined.
    let mat_model_view = model_view.to_homogeneous();

    // Combine everything.
    let model_view_projection = projection.as_matrix() * mat_model_view;
}
<|endoftext|>


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

use env::Env;
use file_saver::save_to_file;
use nameutil::crate_name;
use version::Version;

pub fn generate(env: &Env) {
    println!(
        "manipulating sys Cargo.toml for {}",
        env.config.library_name
    );

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

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

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

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

fn fill_empty(root: &mut Table, env: &Env) {
    let name = format!("{}_sys", crate_name(&env.config.library_name));
    let package_name = name.replace("_", "-");

    {
        let package = upsert_table(root, "package");
        set_string(package, "name", package_name);
        set_string(package, "version", "0.2.0");
    }

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

    let deps = upsert_table(root, "dependencies");
    for ext_lib in &env.config.external_libraries {
        let ext_package = format!("{}-sys", ext_lib.crate_name);
        let dep = upsert_table(deps, &*ext_package);
        set_string(dep, "path", format!("../{}", ext_package));
        set_string(dep, "version", "0.2.0");
    }
}

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

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

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

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

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

fn upsert_table<S: Into<String>>(parent: &mut Table, name: S) -> &mut Table {
    if let Value::Table(ref mut table) =
        *parent
            .entry(name.into())
            .or_insert_with(|| Value::Table(BTreeMap::new()))
    {
        table
    } else {
        unreachable!()
    }
}
<commit_msg>Move filling package.links from each update to creating empty Cargo.toml<commit_after>use std::collections::BTreeMap;
use std::fs::File;
use std::io::prelude::*;
use toml::{self, Value};
use toml::value::Table;

use env::Env;
use file_saver::save_to_file;
use nameutil::crate_name;
use version::Version;

pub fn generate(env: &Env) {
    println!(
        "manipulating sys Cargo.toml for {}",
        env.config.library_name
    );

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

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

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

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

fn fill_empty(root: &mut Table, env: &Env) {
    let name = format!("{}_sys", crate_name(&env.config.library_name));
    let package_name = name.replace("_", "-");

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

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

    let deps = upsert_table(root, "dependencies");
    for ext_lib in &env.config.external_libraries {
        let ext_package = format!("{}-sys", ext_lib.crate_name);
        let dep = upsert_table(deps, &*ext_package);
        set_string(dep, "path", format!("../{}", ext_package));
        set_string(dep, "version", "0.2.0");
    }
}

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

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

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

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

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

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


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

use env::Env;
use file_saver::save_to_file;
use nameutil::crate_name;
use version::Version;

pub fn generate(env: &Env) {
    println!(
        "manipulating sys Cargo.toml for {}",
        env.config.library_name
    );

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

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

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

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

fn fill_empty(root: &mut Table, env: &Env) {
    let name = format!("{}_sys", crate_name(&env.config.library_name));
    let package_name = name.replace("_", "-");

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

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

    let deps = upsert_table(root, "dependencies");
    for ext_lib in &env.config.external_libraries {
        let ext_package = format!("{}-sys", ext_lib.crate_name);
        let dep = upsert_table(deps, &*ext_package);
        set_string(dep, "path", format!("../{}", ext_package));
        set_string(dep, "version", "0.2.0");
    }
}

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

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

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

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

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

fn upsert_table<S: Into<String>>(parent: &mut Table, name: S) -> &mut Table {
    if let Value::Table(ref mut table) = *parent
        .entry(name.into())
        .or_insert_with(|| Value::Table(BTreeMap::new()))
    {
        table
    } else {
        unreachable!()
    }
}
<commit_msg>Generate dox feature as well<commit_after>use std::collections::BTreeMap;
use std::fs::File;
use std::io::prelude::*;
use toml::{self, Value};
use toml::value::Table;

use env::Env;
use file_saver::save_to_file;
use nameutil::crate_name;
use version::Version;

pub fn generate(env: &Env) {
    println!(
        "manipulating sys Cargo.toml for {}",
        env.config.library_name
    );

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

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

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

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

fn fill_empty(root: &mut Table, env: &Env) {
    let name = format!("{}_sys", crate_name(&env.config.library_name));
    let package_name = name.replace("_", "-");

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

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

    let deps = upsert_table(root, "dependencies");
    for ext_lib in &env.config.external_libraries {
        let ext_package = format!("{}-sys", ext_lib.crate_name);
        let dep = upsert_table(deps, &*ext_package);
        set_string(dep, "path", format!("../{}", ext_package));
        set_string(dep, "version", "0.2.0");
    }
}

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

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

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

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

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

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


<commit_before>use conduit::{Request, Response};
use diesel::prelude::*;
use time::Timespec;
use serde_json;

use db::RequestTransaction;
use schema::{crate_owner_invitations, users, crates, crate_owners};
use user::RequestUser;
use util::errors::{CargoResult, human};
use util::RequestUtils;
use owner::{CrateOwner, OwnerKind};

/// The model representing a row in the `crate_owner_invitations` database table.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Identifiable, Queryable)]
#[primary_key(invited_user_id, crate_id)]
pub struct CrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
    pub created_at: Timespec,
}

#[derive(Insertable, Clone, Copy, Debug)]
#[table_name = "crate_owner_invitations"]
pub struct NewCrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
}

impl CrateOwnerInvitation {
    pub fn invited_by_username(&self, conn: &PgConnection) -> String {
        users::table
            .find(self.invited_by_user_id)
            .select(users::gh_login)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown username)"))
    }

    pub fn crate_name(&self, conn: &PgConnection) -> String {
        crates::table
            .find(self.crate_id)
            .select(crates::name)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown crate name)"))
    }

    pub fn encodable(self, conn: &PgConnection) -> EncodableCrateOwnerInvitation {
        EncodableCrateOwnerInvitation {
            invited_by_username: self.invited_by_username(conn),
            crate_name: self.crate_name(conn),
            crate_id: self.crate_id,
            created_at: ::encode_time(self.created_at),
        }
    }
}

/// The serialization format for the `CrateOwnerInvitation` model.
#[derive(Deserialize, Serialize, Debug)]
pub struct EncodableCrateOwnerInvitation {
    pub invited_by_username: String,
    pub crate_name: String,
    pub crate_id: i32,
    pub created_at: String,
}

/// Handles the `GET /me/crate_owner_invitations` route.
pub fn list(req: &mut Request) -> CargoResult<Response> {
    let conn = &*req.db_conn()?;
    let user_id = req.user()?.id;

    let crate_owner_invitations = crate_owner_invitations::table
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .load::<CrateOwnerInvitation>(&*conn)?
        .into_iter()
        .map(|i| i.encodable(conn))
        .collect();

    #[derive(Serialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }
    Ok(req.json(&R { crate_owner_invitations }))
}

#[derive(Deserialize)]
struct OwnerInvitation {
    crate_owner_invite: InvitationResponse,
}

#[derive(Deserialize, Serialize, Debug, Copy, Clone)]
pub struct InvitationResponse {
    pub crate_id: i32,
    pub accepted: bool,
}

/// Handles the `PUT /me/crate_owner_invitations/:crate_id` route.
pub fn handle_invite(req: &mut Request) -> CargoResult<Response> {

    let conn = &*req.db_conn()?;

    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    let crate_invite: OwnerInvitation = serde_json::from_str(&body).map_err(|_| {
        human("invalid json request")
    })?;

    let crate_invite = crate_invite.crate_owner_invite;

    if crate_invite.accepted {
        accept_invite(req, conn, crate_invite)
    } else {
        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R { crate_owner_invitation: crate_invite }))
    }
}

fn accept_invite(
    req: &mut Request,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
) -> CargoResult<Response> {
    let user_id = req.user()?.id;
    use diesel::{insert, delete};
    let pending_crate_owner = crate_owner_invitations::table
        .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .first::<CrateOwnerInvitation>(&*conn)?;

    let owner = CrateOwner {
        crate_id: crate_invite.crate_id,
        owner_id: user_id,
        created_by: pending_crate_owner.invited_by_user_id,
        owner_kind: OwnerKind::User as i32,
    };

    conn.transaction(|| {
        insert(&owner).into(crate_owners::table).execute(conn)?;
        delete(
            crate_owner_invitations::table
                .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
                .filter(crate_owner_invitations::invited_user_id.eq(user_id)),
        ).execute(conn)?;

        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R { crate_owner_invitation: crate_invite }))
    })
}

/// Handles the `PUT /me/decline_owner_invite` route.
pub fn decline_invite(req: &mut Request) -> CargoResult<Response> {
    use diesel::delete;
    let conn = &*req.db_conn()?;
    let user_id = req.user()?.id;

    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    #[derive(Deserialize)]
    struct OwnerInvitation {
        crate_owner_invitation: EncodableCrateOwnerInvitation,
    }

    let crate_invite: OwnerInvitation = serde_json::from_str(&body).map_err(
        |_| human("invalid json request"),
    )?;

    let crate_invite = crate_invite.crate_owner_invitation;

    delete(crate_owner_invitations::table.filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id)))
        .execute(conn)?;

    #[derive(Serialize)]
    struct R {
        ok: bool,
    }

    Ok(req.json(&R { ok: true }))
}
<commit_msg>add filter statement for user_id - don't want to delete all occurrances of the crate_id, want crate_id for corresponding user_id<commit_after>use conduit::{Request, Response};
use diesel::prelude::*;
use time::Timespec;
use serde_json;

use db::RequestTransaction;
use schema::{crate_owner_invitations, users, crates, crate_owners};
use user::RequestUser;
use util::errors::{CargoResult, human};
use util::RequestUtils;
use owner::{CrateOwner, OwnerKind};

/// The model representing a row in the `crate_owner_invitations` database table.
#[derive(Clone, Copy, Debug, PartialEq, Eq, Identifiable, Queryable)]
#[primary_key(invited_user_id, crate_id)]
pub struct CrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
    pub created_at: Timespec,
}

#[derive(Insertable, Clone, Copy, Debug)]
#[table_name = "crate_owner_invitations"]
pub struct NewCrateOwnerInvitation {
    pub invited_user_id: i32,
    pub invited_by_user_id: i32,
    pub crate_id: i32,
}

impl CrateOwnerInvitation {
    pub fn invited_by_username(&self, conn: &PgConnection) -> String {
        users::table
            .find(self.invited_by_user_id)
            .select(users::gh_login)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown username)"))
    }

    pub fn crate_name(&self, conn: &PgConnection) -> String {
        crates::table
            .find(self.crate_id)
            .select(crates::name)
            .first(&*conn)
            .unwrap_or_else(|_| String::from("(unknown crate name)"))
    }

    pub fn encodable(self, conn: &PgConnection) -> EncodableCrateOwnerInvitation {
        EncodableCrateOwnerInvitation {
            invited_by_username: self.invited_by_username(conn),
            crate_name: self.crate_name(conn),
            crate_id: self.crate_id,
            created_at: ::encode_time(self.created_at),
        }
    }
}

/// The serialization format for the `CrateOwnerInvitation` model.
#[derive(Deserialize, Serialize, Debug)]
pub struct EncodableCrateOwnerInvitation {
    pub invited_by_username: String,
    pub crate_name: String,
    pub crate_id: i32,
    pub created_at: String,
}

/// Handles the `GET /me/crate_owner_invitations` route.
pub fn list(req: &mut Request) -> CargoResult<Response> {
    let conn = &*req.db_conn()?;
    let user_id = req.user()?.id;

    let crate_owner_invitations = crate_owner_invitations::table
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .load::<CrateOwnerInvitation>(&*conn)?
        .into_iter()
        .map(|i| i.encodable(conn))
        .collect();

    #[derive(Serialize)]
    struct R {
        crate_owner_invitations: Vec<EncodableCrateOwnerInvitation>,
    }
    Ok(req.json(&R { crate_owner_invitations }))
}

#[derive(Deserialize)]
struct OwnerInvitation {
    crate_owner_invite: InvitationResponse,
}

#[derive(Deserialize, Serialize, Debug, Copy, Clone)]
pub struct InvitationResponse {
    pub crate_id: i32,
    pub accepted: bool,
}

/// Handles the `PUT /me/crate_owner_invitations/:crate_id` route.
pub fn handle_invite(req: &mut Request) -> CargoResult<Response> {

    let conn = &*req.db_conn()?;

    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    let crate_invite: OwnerInvitation = serde_json::from_str(&body).map_err(|_| {
        human("invalid json request")
    })?;

    let crate_invite = crate_invite.crate_owner_invite;

    if crate_invite.accepted {
        accept_invite(req, conn, crate_invite)
    } else {
        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R { crate_owner_invitation: crate_invite }))
    }
}

fn accept_invite(
    req: &mut Request,
    conn: &PgConnection,
    crate_invite: InvitationResponse,
) -> CargoResult<Response> {
    let user_id = req.user()?.id;
    use diesel::{insert, delete};
    let pending_crate_owner = crate_owner_invitations::table
        .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
        .filter(crate_owner_invitations::invited_user_id.eq(user_id))
        .first::<CrateOwnerInvitation>(&*conn)?;

    let owner = CrateOwner {
        crate_id: crate_invite.crate_id,
        owner_id: user_id,
        created_by: pending_crate_owner.invited_by_user_id,
        owner_kind: OwnerKind::User as i32,
    };

    conn.transaction(|| {
        insert(&owner).into(crate_owners::table).execute(conn)?;
        delete(
            crate_owner_invitations::table
                .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
                .filter(crate_owner_invitations::invited_user_id.eq(user_id)),
        ).execute(conn)?;

        #[derive(Serialize)]
        struct R {
            crate_owner_invitation: InvitationResponse,
        }
        Ok(req.json(&R { crate_owner_invitation: crate_invite }))
    })
}

/// Handles the `PUT /me/decline_owner_invite` route.
pub fn decline_invite(req: &mut Request) -> CargoResult<Response> {
    use diesel::delete;
    let conn = &*req.db_conn()?;
    let user_id = req.user()?.id;

    let mut body = String::new();
    req.body().read_to_string(&mut body)?;

    #[derive(Deserialize)]
    struct OwnerInvitation {
        crate_owner_invitation: EncodableCrateOwnerInvitation,
    }

    let crate_invite: OwnerInvitation = serde_json::from_str(&body).map_err(
        |_| human("invalid json request"),
    )?;

    let crate_invite = crate_invite.crate_owner_invitation;

    delete(crate_owner_invitations::table
        .filter(crate_owner_invitations::crate_id.eq(crate_invite.crate_id))
        .filter(crate_owner_invitations::invited_user_id.eq(user_id)))
        .execute(conn)?;

    #[derive(Serialize)]
    struct R {
        ok: bool,
    }

    Ok(req.json(&R { ok: true }))
}
<|endoftext|>


<commit_before>mod swig_foreign_types_map {
    #![swig_foreigner_type = "void"]
    #![swig_rust_type = "()"]
    #![swig_foreigner_type = "int8_t"]
    #![swig_rust_type = "i8"]
    #![swig_foreigner_type = "uint8_t"]
    #![swig_rust_type = "u8"]
    #![swig_foreigner_type = "int16_t"]
    #![swig_rust_type = "i16"]
    #![swig_foreigner_type = "uint16_t"]
    #![swig_rust_type = "u16"]
    #![swig_foreigner_type = "int32_t"]
    #![swig_rust_type = "i32"]
    #![swig_foreigner_type = "uint32_t"]
    #![swig_rust_type = "u32"]
    #![swig_foreigner_type = "int64_t"]
    #![swig_rust_type = "i64"]
    #![swig_foreigner_type = "uint64_t"]
    #![swig_rust_type = "u64"]
    #![swig_foreigner_type = "uintptr_t"]
    #![swig_rust_type = "usize"]
    #![swig_foreigner_type = "float"]
    #![swig_rust_type = "f32"]
    #![swig_foreigner_type = "double"]
    #![swig_rust_type = "f64"]
    #![swig_foreigner_type = "char"]
    #![swig_rust_type = "::std::os::raw::c_char"]
    #![swig_foreigner_type = "const char *"]
    #![swig_rust_type = "*const ::std::os::raw::c_char"]
    #![swig_foreigner_type = "struct RustStrView"]
    #![swig_rust_type = "RustStrView"]
    #![swig_foreigner_type = "struct RustVecBytes"]
    #![swig_rust_type = "RustVecBytes"]
    #![swig_foreigner_type = "struct CRustString"]
    #![swig_rust_type = "CRustString"]
    #![swig_foreigner_type = "struct CResultObjectString"]
    #![swig_rust_type = "CResultObjectString"]
    #![swig_foreigner_type = "struct CRustSliceU32"]
    #![swig_rust_type = "CRustSliceU32"]
}

#[allow(unused_macros)]
macro_rules! swig_c_str {
    ($lit:expr) => {
        concat!($lit, "\0").as_ptr()
            as *const ::std::os::raw::c_char
    }
}

#[allow(dead_code)]
pub trait SwigForeignClass {
    fn c_class_name() -> *const ::std::os::raw::c_char;
    fn box_object(x: Self) -> *mut ::std::os::raw::c_void;
}

#[allow(dead_code)]
#[swig_code = "let mut {to_var}: {to_var_type} = {from_var}.swig_into();"]
trait SwigInto<T> {
    fn swig_into(self) -> T;
}

#[allow(dead_code)]
#[swig_code = "let mut {to_var}: {to_var_type} = <{to_var_type}>::swig_from({from_var});"]
trait SwigFrom<T> {
    fn swig_from(T) -> Self;
}

#[allow(dead_code)]
#[swig_code = "let mut {to_var}: {to_var_type} = {from_var}.swig_deref();"]
trait SwigDeref {
    type Target: ?Sized;
    fn swig_deref(&self) -> &Self::Target;
}

#[allow(dead_code)]
#[swig_code = "let mut {to_var}: {to_var_type} = {from_var}.swig_deref_mut();"]
trait SwigDerefMut {
    type Target: ?Sized;
    fn swig_deref_mut(&mut self) -> &mut Self::Target;
}

impl SwigInto<bool> for ::std::os::raw::c_char {
    fn swig_into(self) -> bool {
        self != 0
    }
}

impl SwigFrom<bool> for ::std::os::raw::c_char {
    fn swig_from(x: bool) -> Self {
        if x {
            1
        } else {
            0
        }
    }
}

impl<'a> SwigInto<&'a ::std::ffi::CStr> for *const ::std::os::raw::c_char {
    fn swig_into(self) -> &'a ::std::ffi::CStr {
        assert!(!self.is_null());
        unsafe { ::std::ffi::CStr::from_ptr(self) }
    }
}

impl<'a> SwigDeref for &'a ::std::ffi::CStr {
    type Target = str;
    fn swig_deref(&self) -> &Self::Target {
        self.to_str().expect("wrong utf-8")
    }
}

#[allow(dead_code)]
#[repr(C)]
pub struct RustStrView {
    data: *const ::std::os::raw::c_char,
    len: u32,
}

impl<'a> SwigFrom<&'a str> for RustStrView {
    fn swig_from(s: &'a str) -> RustStrView {
        assert!((s.len() as u64) <= (::std::u32::MAX as u64));
        RustStrView {
            data: s.as_ptr() as *const ::std::os::raw::c_char,
            len: s.len() as u32,
        }
    }
}
impl<T> SwigDeref for Arc<Mutex<T>> {
    type Target = Mutex<T>;
    fn swig_deref(&self) -> &Mutex<T> {
        self
    }
}

impl<'a, T> SwigFrom<&'a Mutex<T>> for MutexGuard<'a, T> {
    fn swig_from(m: &'a Mutex<T>) -> MutexGuard<'a, T> {
        m.lock().unwrap()
    }
}

impl<'a, T> SwigDeref for MutexGuard<'a, T> {
    type Target = T;
    fn swig_deref(&self) -> &T {
        self
    }
}

impl<'a, T> SwigDerefMut for MutexGuard<'a, T> {
    type Target = T;
    fn swig_deref_mut(&mut self) -> &mut T {
        self
    }
}

impl<T> SwigDeref for Rc<T> {
    type Target = T;
    fn swig_deref(&self) -> &T {
        self
    }
}

impl<'a, T> SwigDeref for &'a Rc<T> {
    type Target = T;
    fn swig_deref(&self) -> &T {
        self
    }
}

impl<'a, T> SwigFrom<&'a RefCell<T>> for Ref<'a, T> {
    fn swig_from(m: &'a RefCell<T>) -> Ref<'a, T> {
        m.borrow()
    }
}

impl<'a, T> SwigFrom<&'a RefCell<T>> for RefMut<'a, T> {
    fn swig_from(m: &'a RefCell<T>) -> RefMut<'a, T> {
        m.borrow_mut()
    }
}

impl<'a, T> SwigDeref for Ref<'a, T> {
    type Target = T;
    fn swig_deref(&self) -> &T {
        self
    }
}

impl<'a, T> SwigDerefMut for RefMut<'a, T> {
    type Target = T;
    fn swig_deref_mut(&mut self) -> &mut T {
        self
    }
}

impl<T: SwigForeignClass> SwigDeref for T {
    type Target = T;
    fn swig_deref(&self) -> &T {
        self
    }
}

impl<T: SwigForeignClass> SwigDerefMut for T {
    type Target = T;
    fn swig_deref_mut(&mut self) -> &mut T {
        self
    }
}

#[swig_to_foreigner_hint = "T"]
impl<T: SwigForeignClass> SwigFrom<T> for *mut ::std::os::raw::c_void {
    fn swig_from(x: T) -> Self {
        <T>::box_object(x)
    }
}

#[swig_to_foreigner_hint = "T"]
impl<'a, T: SwigForeignClass> SwigFrom<&'a T> for *const ::std::os::raw::c_void {
    fn swig_from(x: &'a T) -> Self {
        (x as *const T) as *const ::std::os::raw::c_void
    }
}

#[allow(dead_code)]
#[repr(C)]
pub struct RustVecBytes {
    data: *const u8,
    len: u32,
    capacity: u32,
}

impl SwigFrom<Vec<u8>> for RustVecBytes {
    fn swig_from(mut v: Vec<u8>) -> RustVecBytes {
        let p = v.as_mut_ptr();
        let len = v.len();
        let cap = v.capacity();
        ::std::mem::forget(v);
        //todo check that u32 <-> usize safe, or may be use u64?
        RustVecBytes {
            data: p,
            len: len as u32,
            capacity: cap as u32,
        }
    }
}

#[allow(private_no_mangle_fns)]
#[no_mangle]
pub extern "C" fn rust_vec_bytes_free(v: RustVecBytes) {
    //todo check that u32 <-> usize safe, or may be use u64?
    let v = unsafe { Vec::from_raw_parts(v.data as *mut u8, v.len as usize, v.capacity as usize) };
    drop(v);
}

// &str -> &Path
impl<'a> SwigInto<&'a Path> for &'a str {
    fn swig_into(self) -> &'a Path {
        Path::new(self)
    }
}

#[allow(dead_code)]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct CRustString {
    data: *const ::std::os::raw::c_char,
    len: u32,
    capacity: u32,
}

#[allow(private_no_mangle_fns)]
#[no_mangle]
pub extern "C" fn crust_string_free(x: CRustString) {
    let s =
        unsafe { String::from_raw_parts(x.data as *mut u8, x.len as usize, x.capacity as usize) };
    drop(s);
}

impl SwigFrom<String> for CRustString {
    fn swig_from(s: String) -> CRustString {
        let data = s.as_ptr() as *const ::std::os::raw::c_char;
        assert!((s.len() as u64) <= (::std::u32::MAX as u64));
        let len = s.len() as u32;
        assert!((s.capacity() as u64) <= (::std::u32::MAX as u64));
        let capacity = s.capacity() as u32;
        ::std::mem::forget(s);
        CRustString {
            data,
            len,
            capacity,
        }
    }
}

#[swig_to_foreigner_hint = "T"]
impl<T: SwigForeignClass> SwigFrom<Option<T>> for *mut ::std::os::raw::c_void {
    fn swig_from(x: Option<T>) -> Self {
        match x {
            Some(x) => <T>::box_object(x),
            None => ::std::ptr::null_mut(),
        }
    }
}

#[allow(dead_code)]
#[repr(C)]
pub struct CResultObjectString {
    is_ok: u8,
    data: CResultObjectStringUnion,
}

#[allow(dead_code)]
#[repr(C)]
#[derive(Copy, Clone)]
pub union CResultObjectStringUnion {
    pub ok: *mut ::std::os::raw::c_void,
    pub err: CRustString,
}

impl<T: SwigForeignClass> SwigFrom<Result<T, String>> for CResultObjectString {
    fn swig_from(x: Result<T, String>) -> Self {
        match x {
            Ok(v) => CResultObjectString {
                is_ok: 1,
                data: CResultObjectStringUnion {
                    ok: <T>::box_object(v),
                },
            },
            Err(err) => CResultObjectString {
                is_ok: 0,
                data: CResultObjectStringUnion {
                    err: <CRustString>::swig_from(err),
                },
            },
        }
    }
}

#[allow(dead_code)]
#[repr(C)]
pub struct CRustSliceU32 {
    data: *const u32,
    len: usize,
}

impl<'a> SwigInto<CRustSliceU32> for &'a [u32] {
    fn swig_into(self) -> CRustSliceU32 {
        CRustSliceU32 {
            data: self.as_ptr(),
            len: self.len(),
        }
    }
}
<commit_msg>fix/c++: no dependecy for CResultObjectString conversion<commit_after>mod swig_foreign_types_map {
    #![swig_foreigner_type = "void"]
    #![swig_rust_type = "()"]
    #![swig_foreigner_type = "int8_t"]
    #![swig_rust_type = "i8"]
    #![swig_foreigner_type = "uint8_t"]
    #![swig_rust_type = "u8"]
    #![swig_foreigner_type = "int16_t"]
    #![swig_rust_type = "i16"]
    #![swig_foreigner_type = "uint16_t"]
    #![swig_rust_type = "u16"]
    #![swig_foreigner_type = "int32_t"]
    #![swig_rust_type = "i32"]
    #![swig_foreigner_type = "uint32_t"]
    #![swig_rust_type = "u32"]
    #![swig_foreigner_type = "int64_t"]
    #![swig_rust_type = "i64"]
    #![swig_foreigner_type = "uint64_t"]
    #![swig_rust_type = "u64"]
    #![swig_foreigner_type = "uintptr_t"]
    #![swig_rust_type = "usize"]
    #![swig_foreigner_type = "float"]
    #![swig_rust_type = "f32"]
    #![swig_foreigner_type = "double"]
    #![swig_rust_type = "f64"]
    #![swig_foreigner_type = "char"]
    #![swig_rust_type = "::std::os::raw::c_char"]
    #![swig_foreigner_type = "const char *"]
    #![swig_rust_type = "*const ::std::os::raw::c_char"]
    #![swig_foreigner_type = "struct RustStrView"]
    #![swig_rust_type = "RustStrView"]
    #![swig_foreigner_type = "struct RustVecBytes"]
    #![swig_rust_type = "RustVecBytes"]
    #![swig_foreigner_type = "struct CRustString"]
    #![swig_rust_type = "CRustString"]
    #![swig_foreigner_type = "struct CResultObjectString"]
    #![swig_rust_type = "CResultObjectString"]
    #![swig_foreigner_type = "struct CRustSliceU32"]
    #![swig_rust_type = "CRustSliceU32"]
}

#[allow(unused_macros)]
macro_rules! swig_c_str {
    ($lit:expr) => {
        concat!($lit, "\0").as_ptr()
            as *const ::std::os::raw::c_char
    }
}

#[allow(dead_code)]
pub trait SwigForeignClass {
    fn c_class_name() -> *const ::std::os::raw::c_char;
    fn box_object(x: Self) -> *mut ::std::os::raw::c_void;
}

#[allow(dead_code)]
#[swig_code = "let mut {to_var}: {to_var_type} = {from_var}.swig_into();"]
trait SwigInto<T> {
    fn swig_into(self) -> T;
}

#[allow(dead_code)]
#[swig_code = "let mut {to_var}: {to_var_type} = <{to_var_type}>::swig_from({from_var});"]
trait SwigFrom<T> {
    fn swig_from(T) -> Self;
}

#[allow(dead_code)]
#[swig_code = "let mut {to_var}: {to_var_type} = {from_var}.swig_deref();"]
trait SwigDeref {
    type Target: ?Sized;
    fn swig_deref(&self) -> &Self::Target;
}

#[allow(dead_code)]
#[swig_code = "let mut {to_var}: {to_var_type} = {from_var}.swig_deref_mut();"]
trait SwigDerefMut {
    type Target: ?Sized;
    fn swig_deref_mut(&mut self) -> &mut Self::Target;
}

impl SwigInto<bool> for ::std::os::raw::c_char {
    fn swig_into(self) -> bool {
        self != 0
    }
}

impl SwigFrom<bool> for ::std::os::raw::c_char {
    fn swig_from(x: bool) -> Self {
        if x {
            1
        } else {
            0
        }
    }
}

impl<'a> SwigInto<&'a ::std::ffi::CStr> for *const ::std::os::raw::c_char {
    fn swig_into(self) -> &'a ::std::ffi::CStr {
        assert!(!self.is_null());
        unsafe { ::std::ffi::CStr::from_ptr(self) }
    }
}

impl<'a> SwigDeref for &'a ::std::ffi::CStr {
    type Target = str;
    fn swig_deref(&self) -> &Self::Target {
        self.to_str().expect("wrong utf-8")
    }
}

#[allow(dead_code)]
#[repr(C)]
pub struct RustStrView {
    data: *const ::std::os::raw::c_char,
    len: u32,
}

impl<'a> SwigFrom<&'a str> for RustStrView {
    fn swig_from(s: &'a str) -> RustStrView {
        assert!((s.len() as u64) <= (::std::u32::MAX as u64));
        RustStrView {
            data: s.as_ptr() as *const ::std::os::raw::c_char,
            len: s.len() as u32,
        }
    }
}
impl<T> SwigDeref for Arc<Mutex<T>> {
    type Target = Mutex<T>;
    fn swig_deref(&self) -> &Mutex<T> {
        self
    }
}

impl<'a, T> SwigFrom<&'a Mutex<T>> for MutexGuard<'a, T> {
    fn swig_from(m: &'a Mutex<T>) -> MutexGuard<'a, T> {
        m.lock().unwrap()
    }
}

impl<'a, T> SwigDeref for MutexGuard<'a, T> {
    type Target = T;
    fn swig_deref(&self) -> &T {
        self
    }
}

impl<'a, T> SwigDerefMut for MutexGuard<'a, T> {
    type Target = T;
    fn swig_deref_mut(&mut self) -> &mut T {
        self
    }
}

impl<T> SwigDeref for Rc<T> {
    type Target = T;
    fn swig_deref(&self) -> &T {
        self
    }
}

impl<'a, T> SwigDeref for &'a Rc<T> {
    type Target = T;
    fn swig_deref(&self) -> &T {
        self
    }
}

impl<'a, T> SwigFrom<&'a RefCell<T>> for Ref<'a, T> {
    fn swig_from(m: &'a RefCell<T>) -> Ref<'a, T> {
        m.borrow()
    }
}

impl<'a, T> SwigFrom<&'a RefCell<T>> for RefMut<'a, T> {
    fn swig_from(m: &'a RefCell<T>) -> RefMut<'a, T> {
        m.borrow_mut()
    }
}

impl<'a, T> SwigDeref for Ref<'a, T> {
    type Target = T;
    fn swig_deref(&self) -> &T {
        self
    }
}

impl<'a, T> SwigDerefMut for RefMut<'a, T> {
    type Target = T;
    fn swig_deref_mut(&mut self) -> &mut T {
        self
    }
}

impl<T: SwigForeignClass> SwigDeref for T {
    type Target = T;
    fn swig_deref(&self) -> &T {
        self
    }
}

impl<T: SwigForeignClass> SwigDerefMut for T {
    type Target = T;
    fn swig_deref_mut(&mut self) -> &mut T {
        self
    }
}

#[swig_to_foreigner_hint = "T"]
impl<T: SwigForeignClass> SwigFrom<T> for *mut ::std::os::raw::c_void {
    fn swig_from(x: T) -> Self {
        <T>::box_object(x)
    }
}

#[swig_to_foreigner_hint = "T"]
impl<'a, T: SwigForeignClass> SwigFrom<&'a T> for *const ::std::os::raw::c_void {
    fn swig_from(x: &'a T) -> Self {
        (x as *const T) as *const ::std::os::raw::c_void
    }
}

#[allow(dead_code)]
#[repr(C)]
pub struct RustVecBytes {
    data: *const u8,
    len: u32,
    capacity: u32,
}

impl SwigFrom<Vec<u8>> for RustVecBytes {
    fn swig_from(mut v: Vec<u8>) -> RustVecBytes {
        let p = v.as_mut_ptr();
        let len = v.len();
        let cap = v.capacity();
        ::std::mem::forget(v);
        //todo check that u32 <-> usize safe, or may be use u64?
        RustVecBytes {
            data: p,
            len: len as u32,
            capacity: cap as u32,
        }
    }
}

#[allow(private_no_mangle_fns)]
#[no_mangle]
pub extern "C" fn rust_vec_bytes_free(v: RustVecBytes) {
    //todo check that u32 <-> usize safe, or may be use u64?
    let v = unsafe { Vec::from_raw_parts(v.data as *mut u8, v.len as usize, v.capacity as usize) };
    drop(v);
}

// &str -> &Path
impl<'a> SwigInto<&'a Path> for &'a str {
    fn swig_into(self) -> &'a Path {
        Path::new(self)
    }
}

#[allow(dead_code)]
#[repr(C)]
#[derive(Copy, Clone)]
pub struct CRustString {
    data: *const ::std::os::raw::c_char,
    len: u32,
    capacity: u32,
}

#[allow(private_no_mangle_fns)]
#[no_mangle]
pub extern "C" fn crust_string_free(x: CRustString) {
    let s =
        unsafe { String::from_raw_parts(x.data as *mut u8, x.len as usize, x.capacity as usize) };
    drop(s);
}

#[allow(dead_code)]
impl CRustString {
    pub fn from_string(s: String) -> CRustString {
        let data = s.as_ptr() as *const ::std::os::raw::c_char;
        assert!((s.len() as u64) <= (::std::u32::MAX as u64));
        let len = s.len() as u32;
        assert!((s.capacity() as u64) <= (::std::u32::MAX as u64));
        let capacity = s.capacity() as u32;
        ::std::mem::forget(s);
        CRustString {
            data,
            len,
            capacity,
        }
    }
}

impl SwigFrom<String> for CRustString {
    fn swig_from(s: String) -> CRustString {
        CRustString::from_string(s)
    }
}

#[swig_to_foreigner_hint = "T"]
impl<T: SwigForeignClass> SwigFrom<Option<T>> for *mut ::std::os::raw::c_void {
    fn swig_from(x: Option<T>) -> Self {
        match x {
            Some(x) => <T>::box_object(x),
            None => ::std::ptr::null_mut(),
        }
    }
}

#[allow(dead_code)]
#[repr(C)]
pub struct CResultObjectString {
    is_ok: u8,
    data: CResultObjectStringUnion,
}

#[allow(dead_code)]
#[repr(C)]
#[derive(Copy, Clone)]
pub union CResultObjectStringUnion {
    pub ok: *mut ::std::os::raw::c_void,
    pub err: CRustString,
}

impl<T: SwigForeignClass> SwigFrom<Result<T, String>> for CResultObjectString {
    fn swig_from(x: Result<T, String>) -> Self {
        match x {
            Ok(v) => CResultObjectString {
                is_ok: 1,
                data: CResultObjectStringUnion {
                    ok: <T>::box_object(v),
                },
            },
            Err(err) => CResultObjectString {
                is_ok: 0,
                data: CResultObjectStringUnion {
                    err: CRustString::from_string(err),
                },
            },
        }
    }
}

#[allow(dead_code)]
#[repr(C)]
pub struct CRustSliceU32 {
    data: *const u32,
    len: usize,
}

impl<'a> SwigInto<CRustSliceU32> for &'a [u32] {
    fn swig_into(self) -> CRustSliceU32 {
        CRustSliceU32 {
            data: self.as_ptr(),
            len: self.len(),
        }
    }
}
<|endoftext|>