<commit_before>use std::{
    collections::{BTreeMap, VecDeque},
    fs::File,
    path::Path,
};

use swirl::PerformError;

pub fn gen_scripts(export_script: &Path, import_script: &Path) -> Result<(), PerformError> {
    let config: VisibilityConfig = toml::from_str(include_str!("dump-db.toml")).unwrap();
    let export_sql = File::create(export_script)?;
    let import_sql = File::create(import_script)?;
    config.gen_psql_scripts(export_sql, import_sql)
}

/// An enum indicating whether a column is included in the database dumps.
/// Public columns are included, private are not.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
enum ColumnVisibility {
    Private,
    Public,
}

/// Filtering information for a single table. The `dependencies` field is only
/// used to determine the order of the tables in the generated import script,
/// and should list all tables the current tables refers to with foreign key
/// constraints on public columns. The `filter` field is a valid SQL expression
/// used in a `WHERE` clause to filter the rows of the table. The `columns`
/// field maps column names to their respective visibilities.
#[derive(Clone, Debug, Deserialize)]
struct TableConfig {
    #[serde(default)]
    dependencies: Vec<String>,
    filter: Option<String>,
    columns: BTreeMap<String, ColumnVisibility>,
    #[serde(default)]
    column_defaults: BTreeMap<String, String>,
}

/// Subset of the configuration data to be passed on to the Handlbars template.
#[derive(Debug, Serialize)]
struct HandlebarsTableContext<'a> {
    name: &'a str,
    filter: Option<&'a str>,
    columns: String,
    column_defaults: BTreeMap<&'a str, &'a str>,
}

impl TableConfig {
    fn handlebars_context<'a>(&'a self, name: &'a str) -> Option<HandlebarsTableContext<'a>> {
        let columns = self
            .columns
            .iter()
            .filter(|&(_, &vis)| vis == ColumnVisibility::Public)
            .map(|(col, _)| format!("\"{}\"", col))
            .collect::<Vec<String>>()
            .join(", ");
        if columns.is_empty() {
            None
        } else {
            let filter = self.filter.as_ref().map(String::as_str);
            let column_defaults = self
                .column_defaults
                .iter()
                .map(|(k, v)| (k.as_str(), v.as_str()))
                .collect();
            Some(HandlebarsTableContext {
                name,
                filter,
                columns,
                column_defaults,
            })
        }
    }
}

/// Maps table names to the respective configurations. Used to load `dump_db.toml`.
#[derive(Clone, Debug, Deserialize)]
#[serde(transparent)]
struct VisibilityConfig(BTreeMap<String, TableConfig>);

/// Subset of the configuration data to be passed on to the Handlbars template.
#[derive(Debug, Serialize)]
struct HandlebarsContext<'a> {
    tables: Vec<HandlebarsTableContext<'a>>,
}

impl VisibilityConfig {
    /// Sort the tables in a way that dependencies come before dependent tables.
    ///
    /// Returns a vector of table names.
    fn topological_sort(&self) -> Vec<&str> {
        let mut result = Vec::new();
        let mut num_deps = BTreeMap::new();
        let mut rev_deps: BTreeMap<_, Vec<_>> = BTreeMap::new();
        for (table, config) in self.0.iter() {
            num_deps.insert(table.as_str(), config.dependencies.len());
            for dep in &config.dependencies {
                rev_deps
                    .entry(dep.as_str())
                    .or_default()
                    .push(table.as_str());
            }
        }
        let mut ready: VecDeque<&str> = num_deps
            .iter()
            .filter(|(_, &count)| count == 0)
            .map(|(&table, _)| table)
            .collect();
        while let Some(table) = ready.pop_front() {
            result.push(table);
            for dep in rev_deps.get(table).iter().copied().flatten() {
                *num_deps.get_mut(dep).unwrap() -= 1;
                if num_deps[dep] == 0 {
                    ready.push_back(dep);
                }
            }
        }
        assert_eq!(
            self.0.len(),
            result.len(),
            "circular dependencies in database dump configuration detected",
        );
        result
    }

    fn handlebars_context(&self) -> HandlebarsContext<'_> {
        let tables = self
            .topological_sort()
            .into_iter()
            .filter_map(|table| self.0[table].handlebars_context(table))
            .collect();
        HandlebarsContext { tables }
    }

    fn gen_psql_scripts<W>(&self, export_sql: W, import_sql: W) -> Result<(), PerformError>
    where
        W: std::io::Write,
    {
        let context = self.handlebars_context();
        let mut handlebars = handlebars::Handlebars::new();
        handlebars.register_escape_fn(handlebars::no_escape);
        handlebars.render_template_to_write(
            include_str!("dump-export.hbs"),
            &context,
            export_sql,
        )?;
        handlebars.render_template_to_write(
            include_str!("dump-import.hbs"),
            &context,
            import_sql,
        )?;
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::test_util::pg_connection;
    use diesel::prelude::*;
    use std::collections::HashSet;
    use std::iter::FromIterator;

    /// Test whether the visibility configuration matches the schema of the
    /// test database.
    #[test]
    fn check_visibility_config() {
        let conn = pg_connection();
        let db_columns = HashSet::<Column>::from_iter(get_db_columns(&conn));
        let vis_columns = toml::from_str::<VisibilityConfig>(include_str!("dump-db.toml"))
            .unwrap()
            .0
            .iter()
            .flat_map(|(table, config)| {
                config.columns.iter().map(move |(column, _)| Column {
                    table_name: table.clone(),
                    column_name: column.clone(),
                })
            })
            .collect();
        let mut errors = vec![];
        for Column {
            table_name,
            column_name,
        } in db_columns.difference(&vis_columns)
        {
            errors.push(format!(
                "No visibility information for columns {}.{}.",
                table_name, column_name
            ));
        }
        for Column {
            table_name,
            column_name,
        } in vis_columns.difference(&db_columns)
        {
            errors.push(format!(
                "Column {}.{} does not exist in the database.",
                table_name, column_name
            ));
        }
        assert!(
            errors.is_empty(),
            "The visibility configuration does not match the database schema:\n{}",
            errors.join("\n  - "),
        );
    }

    mod information_schema {
        table! {
            information_schema.columns (table_schema, table_name, column_name) {
                table_schema -> Text,
                table_name -> Text,
                column_name -> Text,
                ordinal_position -> Integer,
            }
        }
    }

    #[derive(Debug, Eq, Hash, PartialEq, Queryable)]
    struct Column {
        table_name: String,
        column_name: String,
    }

    fn get_db_columns(conn: &PgConnection) -> Vec<Column> {
        use information_schema::columns::dsl::*;
        columns
            .select((table_name, column_name))
            .filter(table_schema.eq("public"))
            .order_by((table_name, ordinal_position))
            .load(conn)
            .unwrap()
    }
}
<commit_msg>Add basic unit tests for topological sorting.<commit_after>use std::{
    collections::{BTreeMap, VecDeque},
    fs::File,
    path::Path,
};

use swirl::PerformError;

pub fn gen_scripts(export_script: &Path, import_script: &Path) -> Result<(), PerformError> {
    let config: VisibilityConfig = toml::from_str(include_str!("dump-db.toml")).unwrap();
    let export_sql = File::create(export_script)?;
    let import_sql = File::create(import_script)?;
    config.gen_psql_scripts(export_sql, import_sql)
}

/// An enum indicating whether a column is included in the database dumps.
/// Public columns are included, private are not.
#[derive(Clone, Copy, Debug, Deserialize, PartialEq)]
#[serde(rename_all = "lowercase")]
enum ColumnVisibility {
    Private,
    Public,
}

/// Filtering information for a single table. The `dependencies` field is only
/// used to determine the order of the tables in the generated import script,
/// and should list all tables the current tables refers to with foreign key
/// constraints on public columns. The `filter` field is a valid SQL expression
/// used in a `WHERE` clause to filter the rows of the table. The `columns`
/// field maps column names to their respective visibilities.
#[derive(Clone, Debug, Default, Deserialize)]
struct TableConfig {
    #[serde(default)]
    dependencies: Vec<String>,
    filter: Option<String>,
    columns: BTreeMap<String, ColumnVisibility>,
    #[serde(default)]
    column_defaults: BTreeMap<String, String>,
}

/// Subset of the configuration data to be passed on to the Handlbars template.
#[derive(Debug, Serialize)]
struct HandlebarsTableContext<'a> {
    name: &'a str,
    filter: Option<&'a str>,
    columns: String,
    column_defaults: BTreeMap<&'a str, &'a str>,
}

impl TableConfig {
    fn handlebars_context<'a>(&'a self, name: &'a str) -> Option<HandlebarsTableContext<'a>> {
        let columns = self
            .columns
            .iter()
            .filter(|&(_, &vis)| vis == ColumnVisibility::Public)
            .map(|(col, _)| format!("\"{}\"", col))
            .collect::<Vec<String>>()
            .join(", ");
        if columns.is_empty() {
            None
        } else {
            let filter = self.filter.as_ref().map(String::as_str);
            let column_defaults = self
                .column_defaults
                .iter()
                .map(|(k, v)| (k.as_str(), v.as_str()))
                .collect();
            Some(HandlebarsTableContext {
                name,
                filter,
                columns,
                column_defaults,
            })
        }
    }
}

/// Maps table names to the respective configurations. Used to load `dump_db.toml`.
#[derive(Clone, Debug, Default, Deserialize)]
#[serde(transparent)]
struct VisibilityConfig(BTreeMap<String, TableConfig>);

/// Subset of the configuration data to be passed on to the Handlbars template.
#[derive(Debug, Serialize)]
struct HandlebarsContext<'a> {
    tables: Vec<HandlebarsTableContext<'a>>,
}

impl VisibilityConfig {
    /// Sort the tables in a way that dependencies come before dependent tables.
    ///
    /// Returns a vector of table names.
    fn topological_sort(&self) -> Vec<&str> {
        let mut result = Vec::new();
        let mut num_deps = BTreeMap::new();
        let mut rev_deps: BTreeMap<_, Vec<_>> = BTreeMap::new();
        for (table, config) in self.0.iter() {
            num_deps.insert(table.as_str(), config.dependencies.len());
            for dep in &config.dependencies {
                rev_deps
                    .entry(dep.as_str())
                    .or_default()
                    .push(table.as_str());
            }
        }
        let mut ready: VecDeque<&str> = num_deps
            .iter()
            .filter(|(_, &count)| count == 0)
            .map(|(&table, _)| table)
            .collect();
        while let Some(table) = ready.pop_front() {
            result.push(table);
            for dep in rev_deps.get(table).iter().copied().flatten() {
                *num_deps.get_mut(dep).unwrap() -= 1;
                if num_deps[dep] == 0 {
                    ready.push_back(dep);
                }
            }
        }
        assert_eq!(
            self.0.len(),
            result.len(),
            "circular dependencies in database dump configuration detected",
        );
        result
    }

    fn handlebars_context(&self) -> HandlebarsContext<'_> {
        let tables = self
            .topological_sort()
            .into_iter()
            .filter_map(|table| self.0[table].handlebars_context(table))
            .collect();
        HandlebarsContext { tables }
    }

    fn gen_psql_scripts<W>(&self, export_sql: W, import_sql: W) -> Result<(), PerformError>
    where
        W: std::io::Write,
    {
        let context = self.handlebars_context();
        let mut handlebars = handlebars::Handlebars::new();
        handlebars.register_escape_fn(handlebars::no_escape);
        handlebars.render_template_to_write(
            include_str!("dump-export.hbs"),
            &context,
            export_sql,
        )?;
        handlebars.render_template_to_write(
            include_str!("dump-import.hbs"),
            &context,
            import_sql,
        )?;
        Ok(())
    }
}

#[cfg(test)]
mod tests {
    use super::*;
    use crate::test_util::pg_connection;
    use diesel::prelude::*;
    use std::collections::HashSet;
    use std::iter::FromIterator;

    /// Test whether the visibility configuration matches the schema of the
    /// test database.
    #[test]
    fn check_visibility_config() {
        let conn = pg_connection();
        let db_columns = HashSet::<Column>::from_iter(get_db_columns(&conn));
        let vis_columns = toml::from_str::<VisibilityConfig>(include_str!("dump-db.toml"))
            .unwrap()
            .0
            .iter()
            .flat_map(|(table, config)| {
                config.columns.iter().map(move |(column, _)| Column {
                    table_name: table.clone(),
                    column_name: column.clone(),
                })
            })
            .collect();
        let mut errors = vec![];
        for Column {
            table_name,
            column_name,
        } in db_columns.difference(&vis_columns)
        {
            errors.push(format!(
                "No visibility information for columns {}.{}.",
                table_name, column_name
            ));
        }
        for Column {
            table_name,
            column_name,
        } in vis_columns.difference(&db_columns)
        {
            errors.push(format!(
                "Column {}.{} does not exist in the database.",
                table_name, column_name
            ));
        }
        assert!(
            errors.is_empty(),
            "The visibility configuration does not match the database schema:\n{}",
            errors.join("\n"),
        );
    }

    mod information_schema {
        table! {
            information_schema.columns (table_schema, table_name, column_name) {
                table_schema -> Text,
                table_name -> Text,
                column_name -> Text,
                ordinal_position -> Integer,
            }
        }
    }

    #[derive(Debug, Eq, Hash, PartialEq, Queryable)]
    struct Column {
        table_name: String,
        column_name: String,
    }

    fn get_db_columns(conn: &PgConnection) -> Vec<Column> {
        use information_schema::columns::dsl::*;
        columns
            .select((table_name, column_name))
            .filter(table_schema.eq("public"))
            .order_by((table_name, ordinal_position))
            .load(conn)
            .unwrap()
    }

    fn table_config_with_deps(deps: &[&str]) -> TableConfig {
        TableConfig {
            dependencies: deps.iter().cloned().map(ToOwned::to_owned).collect(),
            ..Default::default()
        }
    }

    #[test]
    fn test_topological_sort() {
        let mut config = VisibilityConfig::default();
        let tables = &mut config.0;
        tables.insert("a".to_owned(), table_config_with_deps(&["b", "c"]));
        tables.insert("b".to_owned(), table_config_with_deps(&["c", "d"]));
        tables.insert("c".to_owned(), table_config_with_deps(&["d"]));
        config.0.insert("d".to_owned(), table_config_with_deps(&[]));
        assert_eq!(config.topological_sort(), ["d", "c", "b", "a"]);
    }

    #[test]
    #[should_panic]
    fn topological_sort_panics_for_cyclic_dependency() {
        let mut config = VisibilityConfig::default();
        let tables = &mut config.0;
        tables.insert("a".to_owned(), table_config_with_deps(&["b"]));
        tables.insert("b".to_owned(), table_config_with_deps(&["a"]));
        config.topological_sort();
    }
}
<|endoftext|>


<commit_before>use containers::hashset::Hash;
use containers::hashset::HashPrimeHelper;
use containers::array::Array;
use containers::list::List;
use containers::reference::Ref;
use containers::vector::Vector;
use memory::page::Page;
use memory::region::Region;

#[derive(Copy, Clone)]
pub struct KeyValuePair<K: Hash<K> + Copy, V: Copy> {
    key: K,
    value: V
}

#[derive(Copy, Clone)]
pub struct HashMap<K: Hash<K> + Copy, V: Copy> {
    slots: Ref<Vector<Ref<List<Slot<KeyValuePair<K, V>>>>>>,
}

impl<K: Hash<K> + Copy, V: Copy> HashMap<K, V> {
    pub fn from_vector(_pr: &Region, _rp: *mut Page, vector: Ref<Vector<KeyValuePair<K, V>>>) -> Ref<HashMap<K, V>> {
        let _r = Region::create(_pr);
        let hash_size = HashPrimeHelper::get_prime(vector.length);
        let mut array: Ref<Array<Ref<List<Slot<KeyValuePair<K, V>>>>>> = Ref::new(_r.page, Array::new());
        for _ in 0..hash_size {
            array.add(Ref::new(_r.page, List::new()));
        }
        let slots = Ref::new(_rp, Vector::from_array(_rp, array));
        let mut hash_map = Ref::new(_rp, HashMap { slots: slots });
        hash_map.initialize_from_vector(vector);
        hash_map
    }

    fn initialize_from_vector(&mut self, vector: Ref<Vector<KeyValuePair<K, V>>>) {
        for key_value_pair in vector.iter() {
            self.add(&key_value_pair.key, &key_value_pair.value);
        }
    }

    fn add(&mut self, key: &K, value: &V) {
        let hash_code = key.hash();
        let slot_number = hash_code % self.slots.length;
        let mut slot_list = self.slots[slot_number];
        for slot in slot_list.get_iterator() {
            if key.equals(&slot.value.key) {
                return;
            }
        }

        slot_list.add(Slot {
            hash_code: hash_code,
            value: KeyValuePair { key: *key, value: *value},
        });
    }

    pub fn contains(&self, value: K) -> bool {
        for slot in self.slots[value.hash() % self.slots.length].get_iterator() {
            if value.equals(&slot.value.key) {
                return true;
            }
        }

        false
    }
}

#[derive(Copy, Clone)]
struct Slot<K: Copy> {
    value: K,
    hash_code: usize,
}

#[test]
fn test_hash_map() {
    use containers::String;
    use memory::Heap;
    use memory::Page;
    use memory::Region;
    use memory::StackBucket;
    let mut heap = Heap::create();
    let root_stack_bucket = StackBucket::create(&mut heap);
    let root_page = Page::get(root_stack_bucket as usize);
    let _r = Region::create_from_page(root_page);
    let keywords = HashMap::from_vector(
        &_r,
        _r.page,
        Ref::new(
            _r.page,
            Vector::from_raw_array(
                _r.page,
                &[
                    String::from_string_slice(_r.page, "using"),
                    String::from_string_slice(_r.page, "namespace"),
                    String::from_string_slice(_r.page, "typedef"),
                ],
            ),
        ),
    );

    assert_eq!(
        (*keywords).contains(String::from_string_slice(_r.page, "using")),
        true
    );
    assert_eq!(
        (*keywords).contains(String::from_string_slice(_r.page, "namespace")),
        true
    );
    assert_eq!(
        (*keywords).contains(String::from_string_slice(_r.page, "typedef")),
        true
    );
    assert_eq!(
        (*keywords).contains(String::from_string_slice(_r.page, "nix")),
        false
    );
}
<commit_msg>Fixed hash_map_test<commit_after>use containers::array::Array;
use containers::hashset::Hash;
use containers::hashset::HashPrimeHelper;
use containers::list::List;
use containers::reference::Ref;
use containers::vector::Vector;
use memory::page::Page;
use memory::region::Region;

#[derive(Copy, Clone)]
pub struct KeyValuePair<K: Hash<K> + Copy, V: Copy> {
    key: K,
    value: V,
}

#[derive(Copy, Clone)]
pub struct HashMap<K: Hash<K> + Copy, V: Copy> {
    slots: Ref<Vector<Ref<List<Slot<KeyValuePair<K, V>>>>>>,
}

impl<K: Hash<K> + Copy, V: Copy> HashMap<K, V> {
    pub fn from_vector(
        _pr: &Region,
        _rp: *mut Page,
        vector: Ref<Vector<KeyValuePair<K, V>>>,
    ) -> Ref<HashMap<K, V>> {
        let _r = Region::create(_pr);
        let hash_size = HashPrimeHelper::get_prime(vector.length);
        let mut array: Ref<Array<Ref<List<Slot<KeyValuePair<K, V>>>>>> =
            Ref::new(_r.page, Array::new());
        for _ in 0..hash_size {
            array.add(Ref::new(_r.page, List::new()));
        }
        let slots = Ref::new(_rp, Vector::from_array(_rp, array));
        let mut hash_map = Ref::new(_rp, HashMap { slots: slots });
        hash_map.initialize_from_vector(vector);
        hash_map
    }

    fn initialize_from_vector(&mut self, vector: Ref<Vector<KeyValuePair<K, V>>>) {
        for key_value_pair in vector.iter() {
            self.add(&key_value_pair.key, &key_value_pair.value);
        }
    }

    fn add(&mut self, key: &K, value: &V) {
        let hash_code = key.hash();
        let slot_number = hash_code % self.slots.length;
        let mut slot_list = self.slots[slot_number];
        for slot in slot_list.get_iterator() {
            if key.equals(&slot.value.key) {
                return;
            }
        }

        slot_list.add(Slot {
            hash_code: hash_code,
            value: KeyValuePair {
                key: *key,
                value: *value,
            },
        });
    }

    pub fn contains(&self, value: K) -> bool {
        for slot in self.slots[value.hash() % self.slots.length].get_iterator() {
            if value.equals(&slot.value.key) {
                return true;
            }
        }

        false
    }
}

#[derive(Copy, Clone)]
struct Slot<K: Copy> {
    value: K,
    hash_code: usize,
}

#[test]
fn test_hash_map() {
    use containers::String;
    use memory::Heap;
    use memory::Page;
    use memory::Region;
    use memory::StackBucket;
    let mut heap = Heap::create();
    let root_stack_bucket = StackBucket::create(&mut heap);
    let root_page = Page::get(root_stack_bucket as usize);
    let _r = Region::create_from_page(root_page);
    let keywords = HashMap::from_vector(
        &_r,
        _r.page,
        Ref::new(
            _r.page,
            Vector::from_raw_array(
                _r.page,
                &[
                    KeyValuePair {
                        key: String::from_string_slice(_r.page, "using"),
                        value: 1,
                    },
                    KeyValuePair {
                        key: String::from_string_slice(_r.page, "namespace"),
                        value: 2,
                    },
                    KeyValuePair {
                        key: String::from_string_slice(_r.page, "typedef"),
                        value: 3,
                    },
                ],
            ),
        ),
    );

    assert_eq!(
        (*keywords).contains(String::from_string_slice(_r.page, "using")),
        true
    );
    assert_eq!(
        (*keywords).contains(String::from_string_slice(_r.page, "namespace")),
        true
    );
    assert_eq!(
        (*keywords).contains(String::from_string_slice(_r.page, "typedef")),
        true
    );
    assert_eq!(
        (*keywords).contains(String::from_string_slice(_r.page, "nix")),
        false
    );
}
<|endoftext|>


<commit_before>//! Traits and structures to aid consuming and writing HTTP payloads.

use std::task::Poll;

use actix_rt::pin;
use actix_utils::future::poll_fn;
use bytes::{Bytes, BytesMut};
use futures_core::ready;

#[allow(clippy::module_inception)]
mod body;
mod body_stream;
mod message_body;
mod size;
mod sized_stream;

#[allow(deprecated)]
pub use self::body::{AnyBody, Body, BoxBody};
pub use self::body_stream::BodyStream;
pub use self::message_body::MessageBody;
pub(crate) use self::message_body::MessageBodyMapErr;
pub use self::size::BodySize;
pub use self::sized_stream::SizedStream;

/// Collects the body produced by a `MessageBody` implementation into `Bytes`.
///
/// Any errors produced by the body stream are returned immediately.
///
/// # Examples
/// ```
/// use actix_http::body::{Body, to_bytes};
/// use bytes::Bytes;
///
/// # async fn test_to_bytes() {
/// let body = Body::None;
/// let bytes = to_bytes(body).await.unwrap();
/// assert!(bytes.is_empty());
///
/// let body = Body::Bytes(Bytes::from_static(b"123"));
/// let bytes = to_bytes(body).await.unwrap();
/// assert_eq!(bytes, b"123"[..]);
/// # }
/// ```
pub async fn to_bytes<B: MessageBody>(body: B) -> Result<Bytes, B::Error> {
    let cap = match body.size() {
        BodySize::None | BodySize::Sized(0) => return Ok(Bytes::new()),
        BodySize::Sized(size) => size as usize,
        // good enough first guess for chunk size
        BodySize::Stream => 32_768,
    };

    let mut buf = BytesMut::with_capacity(cap);

    pin!(body);

    poll_fn(|cx| loop {
        let body = body.as_mut();

        match ready!(body.poll_next(cx)) {
            Some(Ok(bytes)) => buf.extend_from_slice(&*bytes),
            None => return Poll::Ready(Ok(())),
            Some(Err(err)) => return Poll::Ready(Err(err)),
        }
    })
    .await?;

    Ok(buf.freeze())
}

#[cfg(test)]
mod tests {
    use std::pin::Pin;

    use actix_rt::pin;
    use actix_utils::future::poll_fn;
    use bytes::{Bytes, BytesMut};

    use super::*;

    impl AnyBody {
        pub(crate) fn get_ref(&self) -> &[u8] {
            match *self {
                AnyBody::Bytes(ref bin) => bin,
                _ => panic!(),
            }
        }
    }

    /// AnyBody alias because rustc does not (can not?) infer the default type parameter.
    type TestBody = AnyBody;

    #[actix_rt::test]
    async fn test_static_str() {
        assert_eq!(TestBody::from("").size(), BodySize::Sized(0));
        assert_eq!(TestBody::from("test").size(), BodySize::Sized(4));
        assert_eq!(TestBody::from("test").get_ref(), b"test");

        assert_eq!("test".size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| Pin::new(&mut "test").poll_next(cx))
                .await
                .unwrap()
                .ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_static_bytes() {
        assert_eq!(TestBody::from(b"test".as_ref()).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(b"test".as_ref()).get_ref(), b"test");
        assert_eq!(
            TestBody::copy_from_slice(b"test".as_ref()).size(),
            BodySize::Sized(4)
        );
        assert_eq!(
            TestBody::copy_from_slice(b"test".as_ref()).get_ref(),
            b"test"
        );
        let sb = Bytes::from(&b"test"[..]);
        pin!(sb);

        assert_eq!(sb.size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| sb.as_mut().poll_next(cx)).await.unwrap().ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_vec() {
        assert_eq!(TestBody::from(Vec::from("test")).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(Vec::from("test")).get_ref(), b"test");
        let test_vec = Vec::from("test");
        pin!(test_vec);

        assert_eq!(test_vec.size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| test_vec.as_mut().poll_next(cx))
                .await
                .unwrap()
                .ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_bytes() {
        let b = Bytes::from("test");
        assert_eq!(TestBody::from(b.clone()).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(b.clone()).get_ref(), b"test");
        pin!(b);

        assert_eq!(b.size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| b.as_mut().poll_next(cx)).await.unwrap().ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_bytes_mut() {
        let b = BytesMut::from("test");
        assert_eq!(TestBody::from(b.clone()).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(b.clone()).get_ref(), b"test");
        pin!(b);

        assert_eq!(b.size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| b.as_mut().poll_next(cx)).await.unwrap().ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_string() {
        let b = "test".to_owned();
        assert_eq!(TestBody::from(b.clone()).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(b.clone()).get_ref(), b"test");
        assert_eq!(TestBody::from(&b).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(&b).get_ref(), b"test");
        pin!(b);

        assert_eq!(b.size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| b.as_mut().poll_next(cx)).await.unwrap().ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_unit() {
        assert_eq!(().size(), BodySize::Sized(0));
        assert!(poll_fn(|cx| Pin::new(&mut ()).poll_next(cx))
            .await
            .is_none());
    }

    #[actix_rt::test]
    async fn test_box_and_pin() {
        let val = Box::new(());
        pin!(val);
        assert_eq!(val.size(), BodySize::Sized(0));
        assert!(poll_fn(|cx| val.as_mut().poll_next(cx)).await.is_none());

        let mut val = Box::pin(());
        assert_eq!(val.size(), BodySize::Sized(0));
        assert!(poll_fn(|cx| val.as_mut().poll_next(cx)).await.is_none());
    }

    #[actix_rt::test]
    async fn test_body_eq() {
        assert!(
            AnyBody::Bytes(Bytes::from_static(b"1"))
                == AnyBody::Bytes(Bytes::from_static(b"1"))
        );
        assert!(AnyBody::Bytes(Bytes::from_static(b"1")) != AnyBody::None);
    }

    #[actix_rt::test]
    async fn test_body_debug() {
        assert!(format!("{:?}", TestBody::None).contains("Body::None"));
        assert!(format!("{:?}", TestBody::from(Bytes::from_static(b"1"))).contains('1'));
    }

    #[actix_rt::test]
    async fn test_serde_json() {
        use serde_json::{json, Value};
        assert_eq!(
            TestBody::from(
                serde_json::to_vec(&Value::String("test".to_owned())).unwrap()
            )
            .size(),
            BodySize::Sized(6)
        );
        assert_eq!(
            TestBody::from(
                serde_json::to_vec(&json!({"test-key":"test-value"})).unwrap()
            )
            .size(),
            BodySize::Sized(25)
        );
    }

    // down-casting used to be done with a method on MessageBody trait
    // test is kept to demonstrate equivalence of Any trait
    #[actix_rt::test]
    async fn test_body_casting() {
        let mut body = String::from("hello cast");
        // let mut resp_body: &mut dyn MessageBody<Error = Error> = &mut body;
        let resp_body: &mut dyn std::any::Any = &mut body;
        let body = resp_body.downcast_ref::<String>().unwrap();
        assert_eq!(body, "hello cast");
        let body = &mut resp_body.downcast_mut::<String>().unwrap();
        body.push('!');
        let body = resp_body.downcast_ref::<String>().unwrap();
        assert_eq!(body, "hello cast!");
        let not_body = resp_body.downcast_ref::<()>();
        assert!(not_body.is_none());
    }

    #[actix_rt::test]
    async fn test_to_bytes() {
        let body = AnyBody::empty();
        let bytes = to_bytes(body).await.unwrap();
        assert!(bytes.is_empty());

        let body = AnyBody::copy_from_slice(b"123");
        let bytes = to_bytes(body).await.unwrap();
        assert_eq!(bytes, b"123"[..]);
    }
}
<commit_msg>use anybody in doc test<commit_after>//! Traits and structures to aid consuming and writing HTTP payloads.

use std::task::Poll;

use actix_rt::pin;
use actix_utils::future::poll_fn;
use bytes::{Bytes, BytesMut};
use futures_core::ready;

#[allow(clippy::module_inception)]
mod body;
mod body_stream;
mod message_body;
mod size;
mod sized_stream;

#[allow(deprecated)]
pub use self::body::{AnyBody, Body, BoxBody};
pub use self::body_stream::BodyStream;
pub use self::message_body::MessageBody;
pub(crate) use self::message_body::MessageBodyMapErr;
pub use self::size::BodySize;
pub use self::sized_stream::SizedStream;

/// Collects the body produced by a `MessageBody` implementation into `Bytes`.
///
/// Any errors produced by the body stream are returned immediately.
///
/// # Examples
/// ```
/// use actix_http::body::{AnyBody, to_bytes};
/// use bytes::Bytes;
///
/// # async fn test_to_bytes() {
/// let body = AnyBody::None;
/// let bytes = to_bytes(body).await.unwrap();
/// assert!(bytes.is_empty());
///
/// let body = AnyBody::Bytes(Bytes::from_static(b"123"));
/// let bytes = to_bytes(body).await.unwrap();
/// assert_eq!(bytes, b"123"[..]);
/// # }
/// ```
pub async fn to_bytes<B: MessageBody>(body: B) -> Result<Bytes, B::Error> {
    let cap = match body.size() {
        BodySize::None | BodySize::Sized(0) => return Ok(Bytes::new()),
        BodySize::Sized(size) => size as usize,
        // good enough first guess for chunk size
        BodySize::Stream => 32_768,
    };

    let mut buf = BytesMut::with_capacity(cap);

    pin!(body);

    poll_fn(|cx| loop {
        let body = body.as_mut();

        match ready!(body.poll_next(cx)) {
            Some(Ok(bytes)) => buf.extend_from_slice(&*bytes),
            None => return Poll::Ready(Ok(())),
            Some(Err(err)) => return Poll::Ready(Err(err)),
        }
    })
    .await?;

    Ok(buf.freeze())
}

#[cfg(test)]
mod tests {
    use std::pin::Pin;

    use actix_rt::pin;
    use actix_utils::future::poll_fn;
    use bytes::{Bytes, BytesMut};

    use super::*;

    impl AnyBody {
        pub(crate) fn get_ref(&self) -> &[u8] {
            match *self {
                AnyBody::Bytes(ref bin) => bin,
                _ => panic!(),
            }
        }
    }

    /// AnyBody alias because rustc does not (can not?) infer the default type parameter.
    type TestBody = AnyBody;

    #[actix_rt::test]
    async fn test_static_str() {
        assert_eq!(TestBody::from("").size(), BodySize::Sized(0));
        assert_eq!(TestBody::from("test").size(), BodySize::Sized(4));
        assert_eq!(TestBody::from("test").get_ref(), b"test");

        assert_eq!("test".size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| Pin::new(&mut "test").poll_next(cx))
                .await
                .unwrap()
                .ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_static_bytes() {
        assert_eq!(TestBody::from(b"test".as_ref()).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(b"test".as_ref()).get_ref(), b"test");
        assert_eq!(
            TestBody::copy_from_slice(b"test".as_ref()).size(),
            BodySize::Sized(4)
        );
        assert_eq!(
            TestBody::copy_from_slice(b"test".as_ref()).get_ref(),
            b"test"
        );
        let sb = Bytes::from(&b"test"[..]);
        pin!(sb);

        assert_eq!(sb.size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| sb.as_mut().poll_next(cx)).await.unwrap().ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_vec() {
        assert_eq!(TestBody::from(Vec::from("test")).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(Vec::from("test")).get_ref(), b"test");
        let test_vec = Vec::from("test");
        pin!(test_vec);

        assert_eq!(test_vec.size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| test_vec.as_mut().poll_next(cx))
                .await
                .unwrap()
                .ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_bytes() {
        let b = Bytes::from("test");
        assert_eq!(TestBody::from(b.clone()).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(b.clone()).get_ref(), b"test");
        pin!(b);

        assert_eq!(b.size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| b.as_mut().poll_next(cx)).await.unwrap().ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_bytes_mut() {
        let b = BytesMut::from("test");
        assert_eq!(TestBody::from(b.clone()).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(b.clone()).get_ref(), b"test");
        pin!(b);

        assert_eq!(b.size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| b.as_mut().poll_next(cx)).await.unwrap().ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_string() {
        let b = "test".to_owned();
        assert_eq!(TestBody::from(b.clone()).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(b.clone()).get_ref(), b"test");
        assert_eq!(TestBody::from(&b).size(), BodySize::Sized(4));
        assert_eq!(TestBody::from(&b).get_ref(), b"test");
        pin!(b);

        assert_eq!(b.size(), BodySize::Sized(4));
        assert_eq!(
            poll_fn(|cx| b.as_mut().poll_next(cx)).await.unwrap().ok(),
            Some(Bytes::from("test"))
        );
    }

    #[actix_rt::test]
    async fn test_unit() {
        assert_eq!(().size(), BodySize::Sized(0));
        assert!(poll_fn(|cx| Pin::new(&mut ()).poll_next(cx))
            .await
            .is_none());
    }

    #[actix_rt::test]
    async fn test_box_and_pin() {
        let val = Box::new(());
        pin!(val);
        assert_eq!(val.size(), BodySize::Sized(0));
        assert!(poll_fn(|cx| val.as_mut().poll_next(cx)).await.is_none());

        let mut val = Box::pin(());
        assert_eq!(val.size(), BodySize::Sized(0));
        assert!(poll_fn(|cx| val.as_mut().poll_next(cx)).await.is_none());
    }

    #[actix_rt::test]
    async fn test_body_eq() {
        assert!(
            AnyBody::Bytes(Bytes::from_static(b"1"))
                == AnyBody::Bytes(Bytes::from_static(b"1"))
        );
        assert!(AnyBody::Bytes(Bytes::from_static(b"1")) != AnyBody::None);
    }

    #[actix_rt::test]
    async fn test_body_debug() {
        assert!(format!("{:?}", TestBody::None).contains("Body::None"));
        assert!(format!("{:?}", TestBody::from(Bytes::from_static(b"1"))).contains('1'));
    }

    #[actix_rt::test]
    async fn test_serde_json() {
        use serde_json::{json, Value};
        assert_eq!(
            TestBody::from(
                serde_json::to_vec(&Value::String("test".to_owned())).unwrap()
            )
            .size(),
            BodySize::Sized(6)
        );
        assert_eq!(
            TestBody::from(
                serde_json::to_vec(&json!({"test-key":"test-value"})).unwrap()
            )
            .size(),
            BodySize::Sized(25)
        );
    }

    // down-casting used to be done with a method on MessageBody trait
    // test is kept to demonstrate equivalence of Any trait
    #[actix_rt::test]
    async fn test_body_casting() {
        let mut body = String::from("hello cast");
        // let mut resp_body: &mut dyn MessageBody<Error = Error> = &mut body;
        let resp_body: &mut dyn std::any::Any = &mut body;
        let body = resp_body.downcast_ref::<String>().unwrap();
        assert_eq!(body, "hello cast");
        let body = &mut resp_body.downcast_mut::<String>().unwrap();
        body.push('!');
        let body = resp_body.downcast_ref::<String>().unwrap();
        assert_eq!(body, "hello cast!");
        let not_body = resp_body.downcast_ref::<()>();
        assert!(not_body.is_none());
    }

    #[actix_rt::test]
    async fn test_to_bytes() {
        let body = AnyBody::empty();
        let bytes = to_bytes(body).await.unwrap();
        assert!(bytes.is_empty());

        let body = AnyBody::copy_from_slice(b"123");
        let bytes = to_bytes(body).await.unwrap();
        assert_eq!(bytes, b"123"[..]);
    }
}
<|endoftext|>


<commit_before>extern crate core;

use core::option::Option;
use core::iter::Iterator;
use core::str::StrExt;

use asm;
use interrupt;

pub struct Console {
    position:u32
}

#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum Color {
    Black      = 0,
    Blue       = 1,
    Green      = 2,
    Cyan       = 3,
    Red        = 4,
    Pink       = 5,
    Brown      = 6,
    LightGray  = 7,
    DarkGray   = 8,
    LightBlue  = 9,
    LightGreen = 10,
    LightCyan  = 11,
    LightRed   = 12,
    LightPink  = 13,
    Yellow     = 14,
    White      = 15,
}

static mut console: Console = Console {position: 0};

impl Console {
    pub fn init() -> &'static mut Console {
        interrupt::register_handler(on_keyboard_interrupt);
        unsafe {
            return &mut console;
        }
    }

    pub fn clear_screen(&self,background: Color) {
        let mut r = 0..80 * 25;
        loop {
            match r.next() {
                Option::Some(x) => {
                    unsafe {
                        *((0xb8000 + x * 2) as *mut u16) = (background as u16) << 12;
                    }
                },
                Option::None =>{break}
            }
        }
        self.move_cursor(0);
    }

    #[no_stack_check]
    pub fn print_string(&mut self,string: &str) {
        let mut bytes = string.chars();
        loop {
            match bytes.next() {
                Option::Some(x) => {
                    self.print_char(x);
                },
                Option::None =>{break}
            }
        }
    }

    #[no_stack_check]
    pub fn print_char(&mut self,c: char) {
        if c == '\n' {
            let col = self.position % 80;
            self.position -= col;
            let current_row = self.current_row();
            if (current_row < 24) {
                self.position += 80;
            } else {
                // Scroll everything one row up.
                let mut r = 0..80 * 25;
                loop {
                    match r.next() {
                        Option::Some(x) => {
                            unsafe {
                                *((0xb8000 + x*2) as *mut u16) = *((0xb8000 + (x+80)*2) as *mut u16)
                            }
                        },
                        Option::None =>{break}
                    }
                }
            }
        } else {
            unsafe {
                *((0xb8000 + self.position*2) as *mut u8) = c as u8;
                *((0xb8000 + self.position*2 + 1) as *mut u8) = 0x0f;
            }
            self.position += 1;
        }
        self.update_cursor();
    }

    #[no_stack_check]
    pub fn print_int(&mut self, number: u32) {
        let mut length = 0;
        let output:[u8;64] = [0;64];
        let mut left = number;
        loop {
            //TODO: Must be a better way to write to vector without bounds checking
            let output_addr:*const u8 = &output[0];
            let output_addr_u32:u32=output_addr as u32;
            unsafe {
                *((output_addr_u32 + length) as *mut u8) = (left % 10) as u8;
            }
            length += 1;
            left = left / 10;
            if left == 0 {
                break;
            }
        }
        loop {
            let c:char = (output[(length-1) as usize] + 0x30) as char;
            self.print_char(c);
            length -= 1;
            if length == 0 {
                break;
            }
        }
    }

    fn update_cursor(&self) {
        self.move_cursor(self.position);
    }

    fn move_cursor(&self,pos: u32) {
        asm::out8(0x3D4,15);
        asm::out8(0x3D5,(pos & 0xff) as u8);
        asm::out8(0x3D4,14);
        asm::out8(0x3D5,((pos >> 8) & 0xff) as u8);
    }

    fn current_row(&self) -> u32 {
        return self.position / 80;
    }
}

#[no_stack_check]
fn on_keyboard_interrupt() {
    let scancode = asm::in8(0x60);
    // Keydown
    if scancode & 0b10000000 == 0 {
        let c = scancode_to_char(scancode);
        unsafe {
            console.print_char(c);
        }
    }
}

fn scancode_to_char(scancode: u8) -> char {
    let mut charmap:[char;256] = ['?';256];
    charmap[0x2] = '1';
    charmap[0x3] = '2';
    charmap[0x4] = '3';
    charmap[0x5] = '4';
    charmap[0x6] = '5';
    charmap[0x7] = '6';
    charmap[0x8] = '7';
    charmap[0x9] = '8';
    charmap[0xA] = '9';
    charmap[0xB] = '0';
    charmap[0x1C] = '\n';

    return charmap[scancode as usize];
}
<commit_msg>Add some keyboard op codes<commit_after>extern crate core;

use core::option::Option;
use core::iter::Iterator;
use core::str::StrExt;

use asm;
use interrupt;

pub struct Console {
    position:u32
}

#[allow(dead_code)]
#[derive(Copy, Clone)]
pub enum Color {
    Black      = 0,
    Blue       = 1,
    Green      = 2,
    Cyan       = 3,
    Red        = 4,
    Pink       = 5,
    Brown      = 6,
    LightGray  = 7,
    DarkGray   = 8,
    LightBlue  = 9,
    LightGreen = 10,
    LightCyan  = 11,
    LightRed   = 12,
    LightPink  = 13,
    Yellow     = 14,
    White      = 15,
}

static mut console: Console = Console {position: 0};

impl Console {
    pub fn init() -> &'static mut Console {
        interrupt::register_handler(on_keyboard_interrupt);
        unsafe {
            return &mut console;
        }
    }

    pub fn clear_screen(&self,background: Color) {
        let mut r = 0..80 * 25;
        loop {
            match r.next() {
                Option::Some(x) => {
                    unsafe {
                        *((0xb8000 + x * 2) as *mut u16) = (background as u16) << 12;
                    }
                },
                Option::None =>{break}
            }
        }
        self.move_cursor(0);
    }

    #[no_stack_check]
    pub fn print_string(&mut self,string: &str) {
        let mut bytes = string.chars();
        loop {
            match bytes.next() {
                Option::Some(x) => {
                    self.print_char(x);
                },
                Option::None =>{break}
            }
        }
    }

    #[no_stack_check]
    pub fn print_char(&mut self,c: char) {
        if c == '\n' {
            let col = self.position % 80;
            self.position -= col;
            let current_row = self.current_row();
            if (current_row < 24) {
                self.position += 80;
            } else {
                // Scroll everything one row up.
                let mut r = 0..80 * 25;
                loop {
                    match r.next() {
                        Option::Some(x) => {
                            unsafe {
                                *((0xb8000 + x*2) as *mut u16) = *((0xb8000 + (x+80)*2) as *mut u16)
                            }
                        },
                        Option::None =>{break}
                    }
                }
            }
        } else {
            unsafe {
                *((0xb8000 + self.position*2) as *mut u8) = c as u8;
                *((0xb8000 + self.position*2 + 1) as *mut u8) = 0x0f;
            }
            self.position += 1;
        }
        self.update_cursor();
    }

    #[no_stack_check]
    pub fn print_int(&mut self, number: u32) {
        let mut length = 0;
        let output:[u8;64] = [0;64];
        let mut left = number;
        loop {
            //TODO: Must be a better way to write to vector without bounds checking
            let output_addr:*const u8 = &output[0];
            let output_addr_u32:u32=output_addr as u32;
            unsafe {
                *((output_addr_u32 + length) as *mut u8) = (left % 10) as u8;
            }
            length += 1;
            left = left / 10;
            if left == 0 {
                break;
            }
        }
        loop {
            let c:char = (output[(length-1) as usize] + 0x30) as char;
            self.print_char(c);
            length -= 1;
            if length == 0 {
                break;
            }
        }
    }

    fn update_cursor(&self) {
        self.move_cursor(self.position);
    }

    fn move_cursor(&self,pos: u32) {
        asm::out8(0x3D4,15);
        asm::out8(0x3D5,(pos & 0xff) as u8);
        asm::out8(0x3D4,14);
        asm::out8(0x3D5,((pos >> 8) & 0xff) as u8);
    }

    fn current_row(&self) -> u32 {
        return self.position / 80;
    }
}

#[no_stack_check]
fn on_keyboard_interrupt() {
    let scancode = asm::in8(0x60);
    // Keydown
    if scancode & 0b10000000 == 0 {
        let c = scancode_to_char(scancode);
        unsafe {
            console.print_char(c);
        }
    }
}

fn scancode_to_char(scancode: u8) -> char {
    let mut charmap:[char;256] = ['?';256];
    charmap[0x2] = '1';
    charmap[0x3] = '2';
    charmap[0x4] = '3';
    charmap[0x5] = '4';
    charmap[0x6] = '5';
    charmap[0x7] = '6';
    charmap[0x8] = '7';
    charmap[0x9] = '8';
    charmap[0xA] = '9';
    charmap[0xB] = '0';
    charmap[0xC] = '-';
    charmap[0xD] = '=';
    charmap[0xE] = 'f';
    charmap[0xF] = '\t';
    charmap[0x10] = 'q';
    charmap[0x11] = 'w';
    charmap[0x12] = 'e';
    charmap[0x13] = 'r';
    charmap[0x14] = 't';
    charmap[0x15] = 'y';
    charmap[0x16] = 'u';
    charmap[0x17] = 'i';
    charmap[0x18] = 'o';
    charmap[0x19] = 'p';
    charmap[0x1a] = '[';
    charmap[0x1B] = ']';
    charmap[0x1C] = '\n';
    charmap[0x1D] = 'L'; // left control
    charmap[0x1E] = 'a';
    charmap[0x1F] = 's';
    charmap[0x20] = 'd';
    charmap[0x21] = 'f';
    charmap[0x22] = 'g';
    charmap[0x23] = 'h';
    charmap[0x24] = 'j';
    charmap[0x25] = 'k';
    charmap[0x26] = 'l';
    charmap[0x27] = ';';
    charmap[0x28] = '\'';
    charmap[0x29] = '`';
    charmap[0x2a] = 'L'; // Left shift
    charmap[0x2b] = '\\';
    charmap[0x2c] = 'z';
    charmap[0x2d] = 'x';
    charmap[0x2e] = 'c';
    charmap[0x2f] = 'v';
    charmap[0x30] = 'b';
    charmap[0x31] = 'n';
    charmap[0x32] = 'm';
    charmap[0x33] = ',';
    charmap[0x34] = '.';
    charmap[0x35] = '/';
    charmap[0x36] = 'R'; // Right shift
    charmap[0x37] = '*';
    charmap[0x38] = 'L'; // Left Alt
    charmap[0x39] = ' ';

    return charmap[scancode as usize];
}
<|endoftext|>


<commit_before>use std::sync::Arc;

use base_db::SourceDatabaseExt;

use super::*;

fn check_def_map_is_not_recomputed(ra_fixture_initial: &str, ra_fixture_change: &str) {
    let (mut db, pos) = TestDB::with_position(ra_fixture_initial);
    let krate = db.test_crate();
    {
        let events = db.log_executed(|| {
            db.crate_def_map(krate);
        });
        assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
    }
    db.set_file_text(pos.file_id, Arc::new(ra_fixture_change.to_string()));

    {
        let events = db.log_executed(|| {
            db.crate_def_map(krate);
        });
        assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
    }
}

#[test]
fn typing_inside_a_function_should_not_invalidate_def_map() {
    check_def_map_is_not_recomputed(
        r"
        //- /lib.rs
        mod foo;$0

        use crate::foo::bar::Baz;

        enum E { A, B }
        use E::*;

        fn foo() -> i32 {
            1 + 1
        }

        #[cfg(never)]
        fn no() {}
        //- /foo/mod.rs
        pub mod bar;

        //- /foo/bar.rs
        pub struct Baz;
        ",
        r"
        mod foo;

        use crate::foo::bar::Baz;

        enum E { A, B }
        use E::*;

        fn foo() -> i32 { 92 }

        #[cfg(never)]
        fn no() {}
        ",
    );
}

#[test]
fn typing_inside_a_macro_should_not_invalidate_def_map() {
    let (mut db, pos) = TestDB::with_position(
        r"
        //- /lib.rs
        macro_rules! m {
            ($ident:ident) => {
                fn f() {
                    $ident + $ident;
                };
            }
        }
        mod foo;

        //- /foo/mod.rs
        pub mod bar;

        //- /foo/bar.rs
        $0
        m!(X);
        ",
    );
    let krate = db.test_crate();
    {
        let events = db.log_executed(|| {
            let crate_def_map = db.crate_def_map(krate);
            let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
            assert_eq!(module_data.scope.resolutions().count(), 1);
        });
        assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
    }
    db.set_file_text(pos.file_id, Arc::new("m!(Y);".to_string()));

    {
        let events = db.log_executed(|| {
            let crate_def_map = db.crate_def_map(krate);
            let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
            assert_eq!(module_data.scope.resolutions().count(), 1);
        });
        assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
    }
}

#[test]
fn typing_inside_a_function_should_not_invalidate_expansions() {
    let (mut db, pos) = TestDB::with_position(
        r#"
//- /lib.rs
macro_rules! m {
    ($ident:ident) => {
        fn $ident() { };
    }
}
mod foo;

//- /foo/mod.rs
pub mod bar;

//- /foo/bar.rs
m!(X);
fn quux() { 1$0 }
m!(Y);
m!(Z);
"#,
    );
    let krate = db.test_crate();
    {
        let events = db.log_executed(|| {
            let crate_def_map = db.crate_def_map(krate);
            let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
            assert_eq!(module_data.scope.resolutions().count(), 4);
        });
        let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count();
        assert_eq!(n_recalculated_item_trees, 6);
    }

    let new_text = r#"
m!(X);
fn quux() { 92 }
m!(Y);
m!(Z);
"#;
    db.set_file_text(pos.file_id, Arc::new(new_text.to_string()));

    {
        let events = db.log_executed(|| {
            let crate_def_map = db.crate_def_map(krate);
            let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
            assert_eq!(module_data.scope.resolutions().count(), 4);
        });
        let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count();
        assert_eq!(n_recalculated_item_trees, 1);
    }
}
<commit_msg>Test that none of the macros are reparsed<commit_after>use std::sync::Arc;

use base_db::SourceDatabaseExt;

use super::*;

fn check_def_map_is_not_recomputed(ra_fixture_initial: &str, ra_fixture_change: &str) {
    let (mut db, pos) = TestDB::with_position(ra_fixture_initial);
    let krate = db.test_crate();
    {
        let events = db.log_executed(|| {
            db.crate_def_map(krate);
        });
        assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
    }
    db.set_file_text(pos.file_id, Arc::new(ra_fixture_change.to_string()));

    {
        let events = db.log_executed(|| {
            db.crate_def_map(krate);
        });
        assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
    }
}

#[test]
fn typing_inside_a_function_should_not_invalidate_def_map() {
    check_def_map_is_not_recomputed(
        r"
        //- /lib.rs
        mod foo;$0

        use crate::foo::bar::Baz;

        enum E { A, B }
        use E::*;

        fn foo() -> i32 {
            1 + 1
        }

        #[cfg(never)]
        fn no() {}
        //- /foo/mod.rs
        pub mod bar;

        //- /foo/bar.rs
        pub struct Baz;
        ",
        r"
        mod foo;

        use crate::foo::bar::Baz;

        enum E { A, B }
        use E::*;

        fn foo() -> i32 { 92 }

        #[cfg(never)]
        fn no() {}
        ",
    );
}

#[test]
fn typing_inside_a_macro_should_not_invalidate_def_map() {
    let (mut db, pos) = TestDB::with_position(
        r"
        //- /lib.rs
        macro_rules! m {
            ($ident:ident) => {
                fn f() {
                    $ident + $ident;
                };
            }
        }
        mod foo;

        //- /foo/mod.rs
        pub mod bar;

        //- /foo/bar.rs
        $0
        m!(X);
        ",
    );
    let krate = db.test_crate();
    {
        let events = db.log_executed(|| {
            let crate_def_map = db.crate_def_map(krate);
            let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
            assert_eq!(module_data.scope.resolutions().count(), 1);
        });
        assert!(format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
    }
    db.set_file_text(pos.file_id, Arc::new("m!(Y);".to_string()));

    {
        let events = db.log_executed(|| {
            let crate_def_map = db.crate_def_map(krate);
            let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
            assert_eq!(module_data.scope.resolutions().count(), 1);
        });
        assert!(!format!("{:?}", events).contains("crate_def_map"), "{:#?}", events)
    }
}

#[test]
fn typing_inside_a_function_should_not_invalidate_expansions() {
    let (mut db, pos) = TestDB::with_position(
        r#"
//- /lib.rs
macro_rules! m {
    ($ident:ident) => {
        fn $ident() { };
    }
}
mod foo;

//- /foo/mod.rs
pub mod bar;

//- /foo/bar.rs
m!(X);
fn quux() { 1$0 }
m!(Y);
m!(Z);
"#,
    );
    let krate = db.test_crate();
    {
        let events = db.log_executed(|| {
            let crate_def_map = db.crate_def_map(krate);
            let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
            assert_eq!(module_data.scope.resolutions().count(), 4);
        });
        let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count();
        assert_eq!(n_recalculated_item_trees, 6);
        let n_reparsed_macros =
            events.iter().filter(|it| it.contains("parse_macro_expansion")).count();
        assert_eq!(n_reparsed_macros, 3);
    }

    let new_text = r#"
m!(X);
fn quux() { 92 }
m!(Y);
m!(Z);
"#;
    db.set_file_text(pos.file_id, Arc::new(new_text.to_string()));

    {
        let events = db.log_executed(|| {
            let crate_def_map = db.crate_def_map(krate);
            let (_, module_data) = crate_def_map.modules.iter().last().unwrap();
            assert_eq!(module_data.scope.resolutions().count(), 4);
        });
        let n_recalculated_item_trees = events.iter().filter(|it| it.contains("item_tree")).count();
        assert_eq!(n_recalculated_item_trees, 1);
        let n_reparsed_macros =
            events.iter().filter(|it| it.contains("parse_macro_expansion")).count();
        assert_eq!(n_reparsed_macros, 0);
    }
}
<|endoftext|>


<commit_before>extern crate crossbeam;
extern crate crossbeam_deque as deque;

use deque::{Deque, Steal};
use std::thread;

mod message;

const MESSAGES: usize = 5_000_000;

fn seq() {
    let tx = Deque::new();
    let rx = tx.stealer();

    for i in 0..MESSAGES {
        tx.push(message::new(i));
    }

    for _ in 0..MESSAGES {
        match rx.steal() {
            Steal::Data(_) => break,
            Steal::Retry => panic!(),
            Steal::Empty => panic!(),
        }
    }
}

fn spsc() {
    let tx = Deque::new();
    let rx = tx.stealer();

    crossbeam::scope(|scope| {
        scope.spawn(move |_| {
            for i in 0..MESSAGES {
                tx.push(message::new(i));
            }
        });

        scope.spawn(move |_| {
            for _ in 0..MESSAGES {
                loop {
                    match rx.steal() {
                        Steal::Data(_) => break,
                        Steal::Retry | Steal::Empty => thread::yield_now(),
                    }
                }
            }
        });
    }).unwrap();
}

fn main() {
    macro_rules! run {
        ($name:expr, $f:expr) => {
            let now = ::std::time::Instant::now();
            $f;
            let elapsed = now.elapsed();
            println!(
                "{:25} {:15} {:7.3} sec",
                $name,
                "Rust crossbeam-deque",
                elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 / 1e9
            );
        };
    }

    run!("unbounded_seq", seq());
    run!("unbounded_spsc", spsc());
}
<commit_msg>Update crossbeam-deque.rs<commit_after>extern crate crossbeam;
extern crate crossbeam_deque as deque;

use deque::{Deque, Steal};
use std::thread;

mod message;

const MESSAGES: usize = 5_000_000;

fn seq() {
    let tx = Deque::new();
    let rx = tx.stealer();

    for i in 0..MESSAGES {
        tx.push(message::new(i));
    }

    for _ in 0..MESSAGES {
        match rx.steal() {
            Steal::Data(_) => {},
            Steal::Retry => panic!(),
            Steal::Empty => panic!(),
        }
    }
}

fn spsc() {
    let tx = Deque::new();
    let rx = tx.stealer();

    crossbeam::scope(|scope| {
        scope.spawn(move |_| {
            for i in 0..MESSAGES {
                tx.push(message::new(i));
            }
        });

        scope.spawn(move |_| {
            for _ in 0..MESSAGES {
                loop {
                    match rx.steal() {
                        Steal::Data(_) => break,
                        Steal::Retry | Steal::Empty => thread::yield_now(),
                    }
                }
            }
        });
    }).unwrap();
}

fn main() {
    macro_rules! run {
        ($name:expr, $f:expr) => {
            let now = ::std::time::Instant::now();
            $f;
            let elapsed = now.elapsed();
            println!(
                "{:25} {:15} {:7.3} sec",
                $name,
                "Rust crossbeam-deque",
                elapsed.as_secs() as f64 + elapsed.subsec_nanos() as f64 / 1e9
            );
        };
    }

    run!("unbounded_seq", seq());
    run!("unbounded_spsc", spsc());
}
<|endoftext|>


<commit_before>/* kernel::sgash.rs */

use core::*;
use core::str::*;
use core::option::{Some, Option, None}; // Match statement
use core::iter::Iterator;
use core::vec::Vec;
use core::mem::Allocator;
use kernel::*;
use super::super::platform::*;

pub static mut buffer: cstr = cstr {
				p: 0 as *mut u8,
				p_cstr_i: 0,
				max: 0
			      };
pub fn putchar(key: char) {
    unsafe {
	/*
	 * We need to include a blank asm call to prevent rustc
	 * from optimizing this part out
	 */
	asm!("");
	io::write_char(key, io::UART0);
    }
}

#[lang = "exchange_free"]
fn putstr(msg: &str) {
    for c in slice::iter(as_bytes(msg)) {
	putchar(*c as char);
    }
}

pub unsafe fn drawstr(msg: &str) {
    let mut old_fg = super::super::io::FG_COLOR;
    let mut x: u32 = 0x6699AAFF;
    for c in slice::iter(as_bytes(msg)) {
	x = (x << 8) + (x >> 24);
	super::super::io::set_fg(x);
	drawchar(*c as char);
    }
    super::super::io::set_fg(old_fg);
}

pub unsafe fn putcstr(s: cstr)
{
    let mut p = s.p as uint;
    while *(p as *char) != '\0'
    {
	putchar(*(p as *char));
	p += 1;
    }
}

pub unsafe fn parsekey(x: char) {
	let x = x as u8;
	// Set this to false to learn the keycodes of various keys!
	// Key codes are printed backwards because life is hard

	if (true) {
		match x {
			13		=>	{
						parse();
						prompt(false);
			}
			127		=>	{
				if (buffer.delete_char()) {
					putchar('');
					putchar(' ');
					putchar('');
					backspace();
				}
			}
			_		=>	{
				if (buffer.add_char(x)) {
					putchar(x as char);
					drawchar(x as char);
				}
			}
		}
	}
	else {
		keycode(x);
	}
}

unsafe fn drawchar(x: char)
{
	if x == '\n' {
		io::CURSOR_Y += io::CURSOR_HEIGHT;
		io::CURSOR_X = 0u32;
		return;
	}

    io::restore();
    io::draw_char(x);
    io::CURSOR_X += io::CURSOR_WIDTH;
    if io::CURSOR_X >= io::SCREEN_WIDTH {io::CURSOR_X -= io::SCREEN_WIDTH; io::CURSOR_Y += io::CURSOR_HEIGHT}
    io::backup();
    io::draw_cursor();
}

unsafe fn backspace()
{
    io::restore();
    io::CURSOR_X -= io::CURSOR_WIDTH;
    io::draw_char(' ');
    io::backup();
    io::draw_cursor();
}

fn keycode(x: u8) {
	let mut x = x;
	while  x != 0 {
		putchar((x%10+ ('0' as u8) ) as char);
		x = x/10;
	}
	putchar(' ');
}
fn screen() {

	putstr(&"\n                                                               ");
	putstr(&"\n                                                               ");
	putstr(&"\n                       7=..~$=..:7                             ");
	putstr(&"\n                  +$: =$$$+$$$?$$$+ ,7?                        ");
	putstr(&"\n                  $$$$$$$$$$$$$$$$$$Z$$                        ");
	putstr(&"\n              7$$$$$$$$$$$$. .Z$$$$$Z$$$$$$                    ");
	putstr(&"\n           ~..7$$Z$$$$$7+7$+.?Z7=7$$Z$$Z$$$..:                 ");
	putstr(&"\n          ~$$$$$$$$7:     :ZZZ,     :7ZZZZ$$$$=                ");
	putstr(&"\n           Z$$$$$?                    .+ZZZZ$$                 ");
	putstr(&"\n       +$ZZ$$$Z7                         7ZZZ$Z$$I.            ");
	putstr(&"\n        $$$$ZZZZZZZZZZZZZZZZZZZZZZZZI,    ,ZZZ$$Z              ");
	putstr(&"\n      :+$$$$ZZZZZZZZZZZZZZZZZZZZZZZZZZZ=    $ZZ$$+~,           ");
	putstr(&"\n     ?$Z$$$$ZZZZZZZZZZZZZZZZZZZZZZZZZZZZI   7ZZZ$ZZI           ");
	putstr(&"\n      =Z$$+7Z$$7ZZZZZZZZ$$$$$$$ZZZZZZZZZZ  ~Z$?$ZZ?            ");
	putstr(&"\n    :$Z$Z...$Z  $ZZZZZZZ~       ~ZZZZZZZZ,.ZZ...Z$Z$~          ");
	putstr(&"\n    7ZZZZZI$ZZ  $ZZZZZZZ~       =ZZZZZZZ7..ZZ$?$ZZZZ$          ");
	putstr(&"\n      ZZZZ$:    $ZZZZZZZZZZZZZZZZZZZZZZ=     ~$ZZZ$:           ");
	putstr(&"\n    7Z$ZZ$,     $ZZZZZZZZZZZZZZZZZZZZ7         ZZZ$Z$          ");
	putstr(&"\n   =ZZZZZZ,     $ZZZZZZZZZZZZZZZZZZZZZZ,       ZZZ$ZZ+         ");
	putstr(&"\n     ,ZZZZ,     $ZZZZZZZ:     =ZZZZZZZZZ     ZZZZZ$:           ");
	putstr(&"\n    =$ZZZZ+     ZZZZZZZZ~       ZZZZZZZZ~   =ZZZZZZZI          ");
	putstr(&"\n    $ZZ$ZZZ$$Z$$ZZZZZZZZZ$$$$   IZZZZZZZZZ$ZZZZZZZZZ$          ");
	putstr(&"\n      :ZZZZZZZZZZZZZZZZZZZZZZ   ~ZZZZZZZZZZZZZZZZZ~            ");
	putstr(&"\n     ,Z$$ZZZZZZZZZZZZZZZZZZZZ    ZZZZZZZZZZZZZZZZZZ~           ");
	putstr(&"\n     =$ZZZZZZZZZZZZZZZZZZZZZZ     $ZZZZZZZZZZZZZZZ$+           ");
	putstr(&"\n        IZZZZZ:.                        . ,ZZZZZ$              ");
	putstr(&"\n       ~$ZZZZZZZZZZZ                 ZZZZ$ZZZZZZZ+             ");
	putstr(&"\n           Z$ZZZ. ,Z~               =Z:.,ZZZ$Z                 ");
	putstr(&"\n          ,ZZZZZ..~Z$.             .7Z:..ZZZZZ:                ");
	putstr(&"\n          ~7+:$ZZZZZZZZI=:.   .,=IZZZZZZZ$Z:=7=                ");
	putstr(&"\n              $$ZZZZZZZZZZZZZZZZZZZZZZ$ZZZZ                    ");
	putstr(&"\n              ==..$ZZZ$ZZZZZZZZZZZ$ZZZZ .~+                    ");
	putstr(&"\n                  I$?.?ZZZ$ZZZ$ZZZI =$7                        ");
	putstr(&"\n                       $7..I$7..I$,                            ");
	putstr(&"\n");
	putstr(&"\n _                     _     _                         _  ");
	putstr(&"\n| |                   (_)   | |                       | | ");
	putstr(&"\n| | ____ ___  ____     _____| |_____  ____ ____  _____| | ");
	putstr(&"\n| |/ ___) _ \\|  _ \\   |  _   _) ___ |/ ___)  _ \\| ___ | | ");
	putstr(&"\n| | |  | |_| | | | |  | |  \\ \\| ____| |   | | | | ____| | ");
	putstr(&"\n|_|_|  \\____/|_| |_|  |_|   \\_\\_____)_|   |_| |_|_____)__)\n\n");

}

pub unsafe fn init() {
    buffer = cstr::new(256);
    screen();
    prompt(true);
}

unsafe fn prompt(startup: bool) {
	putstr(&"\nsgash > ");
	if !startup {drawstr(&"\nsgash > ");}

	buffer.reset();
}

unsafe fn parse() {
	if buffer.streq(&"open") {
		putstr(&"\nTEST YO");
		drawstr(&"\nTEST YO");
	}
	buffer.reset();
}

/* BUFFER MODIFICATION FUNCTIONS */

struct cstr {
	p: *mut u8,
	p_cstr_i: uint,
	max: uint
}

impl cstr {
	pub unsafe fn new(size: uint) -> cstr {
		// Sometimes this doesn't allocate enough memory and gets stuck...
		let (x, y) = memory::allocator.alloc(size);
		let this = cstr {
			p: x,
			p_cstr_i: 0,
			max: y
		};
		*(((this.p as uint)+this.p_cstr_i) as *mut char) = '\0';
		this
	}

	unsafe fn from_str(s: &str) -> cstr {
		let mut this = cstr::new(256);
		for c in slice::iter(as_bytes(s)) {
			this.add_char(*c);
		};
		this
	}

	fn len(&self) -> uint { self.p_cstr_i }

	// HELP THIS DOESN'T WORK THERE IS NO GARBAGE COLLECTION!!!
	unsafe fn destroy(&self) { memory::allocator.free(self.p); }

	unsafe fn add_char(&mut self, x: u8) -> bool{
		if (self.p_cstr_i == self.max) { return false; }
		*(((self.p as uint)+self.p_cstr_i) as *mut u8) = x;
		self.p_cstr_i += 1;
		*(((self.p as uint)+self.p_cstr_i) as *mut char) = '\0';
		true
	}

	unsafe fn delete_char(&mut self) -> bool {
		if (self.p_cstr_i == 0) { return false; }
		self.p_cstr_i -= 1;
		*(((self.p as uint)+self.p_cstr_i) as *mut char) = '\0';
		true
	}

	unsafe fn reset(&mut self) {
		self.p_cstr_i = 0;
		*(self.p as *mut char) = '\0';
	}

	unsafe fn eq(&self, other: &cstr) -> bool {
		if (self.len() != other.len()) { return false; }
		else {
			let mut x = 0;
			let mut selfp: uint = self.p as uint;
			let mut otherp: uint = other.p as uint;
			while x < self.len() {
				if (*(selfp as *char) != *(otherp as *char)) { return false; }
				selfp += 1;
				otherp += 1;
				x += 1;
			}
			true
		}
	}

	unsafe fn streq(&self, other: &str) -> bool {
		let mut x = 0;
		let mut selfp: uint = self.p as uint;
		for c in slice::iter(as_bytes(other)) {
			if( *c != *(selfp as *u8) ) { return false; }
			selfp += 1;
		};
		*(selfp as *char) == '\0'
	}

	unsafe fn getarg(&self, delim: char, mut k: uint) -> Option<cstr> {
		let mut ind: uint = 0;
		let mut found = k == 0;
		let mut selfp: uint = self.p as uint;
		let mut s = cstr::new(256);
		loop {
			if (*(selfp as *char) == '\0') {
				// End of string
				if (found) { return Some(s); }
				else { return None; }
			};
			if (*(selfp as *u8) == delim as u8) {
				if (found) { return Some(s); }
				k -= 1;
			};
			if (found) {
				s.add_char(*(selfp as *u8));
			};
			found = k == 0;
			selfp += 1;
			ind += 1;
			if (ind == self.max) {
				putstr(&"\nSomething broke!");
				return None;
			}
		}
	}

	unsafe fn split(&self, delim: char) -> (cstr, cstr) {
		let mut selfp: uint = self.p as uint;
		let mut beg = cstr::new(256);
		let mut end = cstr::new(256);
		let mut found = false;
		loop {
			if (*(selfp as *char) == '\0') {
				return (beg, end);
			}
			else if (*(selfp as *u8) == delim as u8) {
				found = true;
			}
			else if (!found) {
				beg.add_char(*(selfp as *u8));
			}
			else if (found) {
				end.add_char(*(selfp as *u8));
			};
			selfp += 1;
		}
	}

}

<commit_msg>Added my fake fs back in<commit_after>/* kernel::sgash.rs */

use core::*;
use core::str::*;
use core::option::{Some, Option, None}; // Match statement
use core::iter::Iterator;
use core::vec::Vec;
use core::mem::Allocator;
use kernel::*;
use super::super::platform::*;

pub static mut buffer: cstr = cstr {
				p: 0 as *mut u8,
				p_cstr_i: 0,
				max: 0
			      };
pub fn putchar(key: char) {
    unsafe {
	/*
	 * We need to include a blank asm call to prevent rustc
	 * from optimizing this part out
	 */
	asm!("");
	io::write_char(key, io::UART0);
    }
}

#[lang = "exchange_free"]
fn putstr(msg: &str) {
    for c in slice::iter(as_bytes(msg)) {
	putchar(*c as char);
    }
}

pub unsafe fn drawstr(msg: &str) {
    let mut old_fg = super::super::io::FG_COLOR;
    let mut x: u32 = 0x6699AAFF;
    for c in slice::iter(as_bytes(msg)) {
	x = (x << 8) + (x >> 24);
	super::super::io::set_fg(x);
	drawchar(*c as char);
    }
    super::super::io::set_fg(old_fg);
}

pub unsafe fn putcstr(s: cstr)
{
    let mut p = s.p as uint;
    while *(p as *char) != '\0'
    {
	putchar(*(p as *char));
	p += 1;
    }
}

pub unsafe fn parsekey(x: char) {
	let x = x as u8;
	// Set this to false to learn the keycodes of various keys!
	// Key codes are printed backwards because life is hard

	if (true) {
		match x {
			13		=>	{
						parse();
						prompt(false);
			}
			127		=>	{
				if (buffer.delete_char()) {
					putchar('');
					putchar(' ');
					putchar('');
					backspace();
				}
			}
			_		=>	{
				if (buffer.add_char(x)) {
					putchar(x as char);
					drawchar(x as char);
				}
			}
		}
	}
	else {
		keycode(x);
	}
}

unsafe fn drawchar(x: char)
{
	if x == '\n' {
		io::CURSOR_Y += io::CURSOR_HEIGHT;
		io::CURSOR_X = 0u32;
		return;
	}

    io::restore();
    io::draw_char(x);
    io::CURSOR_X += io::CURSOR_WIDTH;
    if io::CURSOR_X >= io::SCREEN_WIDTH {io::CURSOR_X -= io::SCREEN_WIDTH; io::CURSOR_Y += io::CURSOR_HEIGHT}
    io::backup();
    io::draw_cursor();
}

unsafe fn backspace()
{
    io::restore();
    io::CURSOR_X -= io::CURSOR_WIDTH;
    io::draw_char(' ');
    io::backup();
    io::draw_cursor();
}

fn keycode(x: u8) {
	let mut x = x;
	while  x != 0 {
		putchar((x%10+ ('0' as u8) ) as char);
		x = x/10;
	}
	putchar(' ');
}
fn screen() {

	putstr(&"\n                                                               ");
	putstr(&"\n                                                               ");
	putstr(&"\n                       7=..~$=..:7                             ");
	putstr(&"\n                  +$: =$$$+$$$?$$$+ ,7?                        ");
	putstr(&"\n                  $$$$$$$$$$$$$$$$$$Z$$                        ");
	putstr(&"\n              7$$$$$$$$$$$$. .Z$$$$$Z$$$$$$                    ");
	putstr(&"\n           ~..7$$Z$$$$$7+7$+.?Z7=7$$Z$$Z$$$..:                 ");
	putstr(&"\n          ~$$$$$$$$7:     :ZZZ,     :7ZZZZ$$$$=                ");
	putstr(&"\n           Z$$$$$?                    .+ZZZZ$$                 ");
	putstr(&"\n       +$ZZ$$$Z7                         7ZZZ$Z$$I.            ");
	putstr(&"\n        $$$$ZZZZZZZZZZZZZZZZZZZZZZZZI,    ,ZZZ$$Z              ");
	putstr(&"\n      :+$$$$ZZZZZZZZZZZZZZZZZZZZZZZZZZZ=    $ZZ$$+~,           ");
	putstr(&"\n     ?$Z$$$$ZZZZZZZZZZZZZZZZZZZZZZZZZZZZI   7ZZZ$ZZI           ");
	putstr(&"\n      =Z$$+7Z$$7ZZZZZZZZ$$$$$$$ZZZZZZZZZZ  ~Z$?$ZZ?            ");
	putstr(&"\n    :$Z$Z...$Z  $ZZZZZZZ~       ~ZZZZZZZZ,.ZZ...Z$Z$~          ");
	putstr(&"\n    7ZZZZZI$ZZ  $ZZZZZZZ~       =ZZZZZZZ7..ZZ$?$ZZZZ$          ");
	putstr(&"\n      ZZZZ$:    $ZZZZZZZZZZZZZZZZZZZZZZ=     ~$ZZZ$:           ");
	putstr(&"\n    7Z$ZZ$,     $ZZZZZZZZZZZZZZZZZZZZ7         ZZZ$Z$          ");
	putstr(&"\n   =ZZZZZZ,     $ZZZZZZZZZZZZZZZZZZZZZZ,       ZZZ$ZZ+         ");
	putstr(&"\n     ,ZZZZ,     $ZZZZZZZ:     =ZZZZZZZZZ     ZZZZZ$:           ");
	putstr(&"\n    =$ZZZZ+     ZZZZZZZZ~       ZZZZZZZZ~   =ZZZZZZZI          ");
	putstr(&"\n    $ZZ$ZZZ$$Z$$ZZZZZZZZZ$$$$   IZZZZZZZZZ$ZZZZZZZZZ$          ");
	putstr(&"\n      :ZZZZZZZZZZZZZZZZZZZZZZ   ~ZZZZZZZZZZZZZZZZZ~            ");
	putstr(&"\n     ,Z$$ZZZZZZZZZZZZZZZZZZZZ    ZZZZZZZZZZZZZZZZZZ~           ");
	putstr(&"\n     =$ZZZZZZZZZZZZZZZZZZZZZZ     $ZZZZZZZZZZZZZZZ$+           ");
	putstr(&"\n        IZZZZZ:.                        . ,ZZZZZ$              ");
	putstr(&"\n       ~$ZZZZZZZZZZZ                 ZZZZ$ZZZZZZZ+             ");
	putstr(&"\n           Z$ZZZ. ,Z~               =Z:.,ZZZ$Z                 ");
	putstr(&"\n          ,ZZZZZ..~Z$.             .7Z:..ZZZZZ:                ");
	putstr(&"\n          ~7+:$ZZZZZZZZI=:.   .,=IZZZZZZZ$Z:=7=                ");
	putstr(&"\n              $$ZZZZZZZZZZZZZZZZZZZZZZ$ZZZZ                    ");
	putstr(&"\n              ==..$ZZZ$ZZZZZZZZZZZ$ZZZZ .~+                    ");
	putstr(&"\n                  I$?.?ZZZ$ZZZ$ZZZI =$7                        ");
	putstr(&"\n                       $7..I$7..I$,                            ");
	putstr(&"\n");
	putstr(&"\n _                     _     _                         _  ");
	putstr(&"\n| |                   (_)   | |                       | | ");
	putstr(&"\n| | ____ ___  ____     _____| |_____  ____ ____  _____| | ");
	putstr(&"\n| |/ ___) _ \\|  _ \\   |  _   _) ___ |/ ___)  _ \\| ___ | | ");
	putstr(&"\n| | |  | |_| | | | |  | |  \\ \\| ____| |   | | | | ____| | ");
	putstr(&"\n|_|_|  \\____/|_| |_|  |_|   \\_\\_____)_|   |_| |_|_____)__)\n\n");

}

pub unsafe fn init() {
    buffer = cstr::new(256);
    screen();
    prompt(true);
}

unsafe fn prompt(startup: bool) {
	putstr(&"\nsgash > ");
	if !startup {drawstr(&"\nsgash > ");}

	buffer.reset();
}

unsafe fn parse() {
	if (buffer.streq(&"ls")) {
	    putstr( &"\na\tb") ;
	    drawstr( &"\na    b") ;
	};
	match buffer.getarg(' ', 0) {
	    Some(y)        => {
		if(y.streq(&"cat")) {
		    match buffer.getarg(' ', 1) {
			Some(x)        => {
			    if(x.streq(&"a")) {
				putstr( &"\nHello");
				drawstr( &"\nHello");
			    }
			    if(x.streq(&"b")) {
				putstr( &"\nworld!");
				drawstr( &"\nworld!");
			    }
			}
			None        => { }
		    };
		}
		if(y.streq(&"open")) {
		    putstr(&"\nTEST YO");
		    drawstr(&"\nTEST YO");
		}
	    }
	    None        => { }
	};
	buffer.reset();
}

/* BUFFER MODIFICATION FUNCTIONS */

struct cstr {
	p: *mut u8,
	p_cstr_i: uint,
	max: uint
}

impl cstr {
	pub unsafe fn new(size: uint) -> cstr {
		// Sometimes this doesn't allocate enough memory and gets stuck...
		let (x, y) = memory::allocator.alloc(size);
		let this = cstr {
			p: x,
			p_cstr_i: 0,
			max: y
		};
		*(((this.p as uint)+this.p_cstr_i) as *mut char) = '\0';
		this
	}

	unsafe fn from_str(s: &str) -> cstr {
		let mut this = cstr::new(256);
		for c in slice::iter(as_bytes(s)) {
			this.add_char(*c);
		};
		this
	}

	fn len(&self) -> uint { self.p_cstr_i }

	// HELP THIS DOESN'T WORK THERE IS NO GARBAGE COLLECTION!!!
	unsafe fn destroy(&self) { memory::allocator.free(self.p); }

	unsafe fn add_char(&mut self, x: u8) -> bool{
		if (self.p_cstr_i == self.max) { return false; }
		*(((self.p as uint)+self.p_cstr_i) as *mut u8) = x;
		self.p_cstr_i += 1;
		*(((self.p as uint)+self.p_cstr_i) as *mut char) = '\0';
		true
	}

	unsafe fn delete_char(&mut self) -> bool {
		if (self.p_cstr_i == 0) { return false; }
		self.p_cstr_i -= 1;
		*(((self.p as uint)+self.p_cstr_i) as *mut char) = '\0';
		true
	}

	unsafe fn reset(&mut self) {
		self.p_cstr_i = 0;
		*(self.p as *mut char) = '\0';
	}

	unsafe fn eq(&self, other: &cstr) -> bool {
		if (self.len() != other.len()) { return false; }
		else {
			let mut x = 0;
			let mut selfp: uint = self.p as uint;
			let mut otherp: uint = other.p as uint;
			while x < self.len() {
				if (*(selfp as *char) != *(otherp as *char)) { return false; }
				selfp += 1;
				otherp += 1;
				x += 1;
			}
			true
		}
	}

	unsafe fn streq(&self, other: &str) -> bool {
		let mut x = 0;
		let mut selfp: uint = self.p as uint;
		for c in slice::iter(as_bytes(other)) {
			if( *c != *(selfp as *u8) ) { return false; }
			selfp += 1;
		};
		*(selfp as *char) == '\0'
	}

	unsafe fn getarg(&self, delim: char, mut k: uint) -> Option<cstr> {
		let mut ind: uint = 0;
		let mut found = k == 0;
		let mut selfp: uint = self.p as uint;
		let mut s = cstr::new(256);
		loop {
			if (*(selfp as *char) == '\0') {
				// End of string
				if (found) { return Some(s); }
				else { return None; }
			};
			if (*(selfp as *u8) == delim as u8) {
				if (found) { return Some(s); }
				k -= 1;
			};
			if (found) {
				s.add_char(*(selfp as *u8));
			};
			found = k == 0;
			selfp += 1;
			ind += 1;
			if (ind == self.max) {
				putstr(&"\nSomething broke!");
				return None;
			}
		}
	}

	unsafe fn split(&self, delim: char) -> (cstr, cstr) {
		let mut selfp: uint = self.p as uint;
		let mut beg = cstr::new(256);
		let mut end = cstr::new(256);
		let mut found = false;
		loop {
			if (*(selfp as *char) == '\0') {
				return (beg, end);
			}
			else if (*(selfp as *u8) == delim as u8) {
				found = true;
			}
			else if (!found) {
				beg.add_char(*(selfp as *u8));
			}
			else if (found) {
				end.add_char(*(selfp as *u8));
			};
			selfp += 1;
		}
	}

}

<|endoftext|>


<commit_before>extern crate sendgrid;
extern crate time;

use sendgrid::mail::Mail;
use sendgrid::sg_client::SGClient;

fn main() {
    let mut env_vars = std::env::vars();
    let api_key_check = env_vars.find(|var| var.0 == "SENDGRID_API_KEY");
    let api_key: String;
    match api_key_check {
        Some(key) => api_key = key.1,
        None => panic!("Must supply API key in environment variables to use!"),
    }

    let sg = SGClient::new(api_key);

    let mut mail_info = Mail::new();
    mail_info.add_to("you@example.com");
    mail_info.add_from("some@some.com"):
    mail_info.add_subject("Rust is rad");
    mail_info.add_html("
Hello from SendGrid!
");
    mail_info.add_from_name("Test");
    mail_info.add_header("x-cool", "indeed");

    let mut x_smtpapi = String::new();
    x_smtpapi.push_str("{\"unique_args\":{\"test\":7}}");
    mail_info.add_x_smtpapi(x_smtpapi);

    sg.send(mail_info);
}
<commit_msg>fix erroneous example<commit_after>extern crate sendgrid;
extern crate time;

use sendgrid::mail::Mail;
use sendgrid::sg_client::SGClient;

fn main() {
    let mut env_vars = std::env::vars();
    let api_key_check = env_vars.find(|var| var.0 == "SENDGRID_API_KEY");
    let api_key: String;
    match api_key_check {
        Some(key) => api_key = key.1,
        None => panic!("Must supply API key in environment variables to use!"),
    }

    let sg = SGClient::new(api_key);

    let mut mail_info = Mail::new();
    mail_info.add_to("you@example.com");
    mail_info.add_from("some@some.com");
    mail_info.add_subject("Rust is rad");
    mail_info.add_html("
Hello from SendGrid!
");
    mail_info.add_from_name("Test");
    mail_info.add_header("x-cool", "indeed");

    let mut x_smtpapi = String::new();
    x_smtpapi.push_str("{\"unique_args\":{\"test\":7}}");
    mail_info.add_x_smtpapi(x_smtpapi);

    sg.send(mail_info);
}
<|endoftext|>


<commit_before><commit_msg>tune diagonalization-tweak so it's fast on SSE2 too<commit_after><|endoftext|>


<commit_before>// This file was generated by gir (15fe1aa) from gir-files (11e0e6d)
// DO NOT EDIT

use Bin;
use Buildable;
use Container;
use Dialog;
use License;
use Widget;
use Window;
use ffi;
use gdk_pixbuf;
use glib::object::Downcast;
use glib::translate::*;

glib_wrapper! {
    pub struct AboutDialog(Object<ffi::GtkAboutDialog>): Widget, Container, Bin, Window, Dialog, Buildable;

    match fn {
        get_type => || ffi::gtk_about_dialog_get_type(),
    }
}

impl AboutDialog {
    pub fn new() -> AboutDialog {
        assert_initialized_main_thread!();
        unsafe {
            Widget::from_glib_none(ffi::gtk_about_dialog_new()).downcast_unchecked()
        }
    }

    #[cfg(gtk_3_4)]
    pub fn add_credit_section(&self, section_name: &str, people: &[&str]) {
        unsafe {
            ffi::gtk_about_dialog_add_credit_section(self.to_glib_none().0, section_name.to_glib_none().0, people.to_glib_none().0);
        }
    }

    pub fn get_artists(&self) -> Vec<String> {
        unsafe {
            FromGlibPtrContainer::from_glib_none(ffi::gtk_about_dialog_get_artists(self.to_glib_none().0))
        }
    }

    pub fn get_authors(&self) -> Vec<String> {
        unsafe {
            FromGlibPtrContainer::from_glib_none(ffi::gtk_about_dialog_get_authors(self.to_glib_none().0))
        }
    }

    pub fn get_comments(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_comments(self.to_glib_none().0))
        }
    }

    pub fn get_copyright(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_copyright(self.to_glib_none().0))
        }
    }

    pub fn get_documenters(&self) -> Vec<String> {
        unsafe {
            FromGlibPtrContainer::from_glib_none(ffi::gtk_about_dialog_get_documenters(self.to_glib_none().0))
        }
    }

    pub fn get_license(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_license(self.to_glib_none().0))
        }
    }

    pub fn get_license_type(&self) -> License {
        unsafe {
            ffi::gtk_about_dialog_get_license_type(self.to_glib_none().0)
        }
    }

    pub fn get_logo(&self) -> Option<gdk_pixbuf::Pixbuf> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_logo(self.to_glib_none().0))
        }
    }

    pub fn get_logo_icon_name(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_logo_icon_name(self.to_glib_none().0))
        }
    }

    pub fn get_program_name(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_program_name(self.to_glib_none().0))
        }
    }

    pub fn get_translator_credits(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_translator_credits(self.to_glib_none().0))
        }
    }

    pub fn get_version(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_version(self.to_glib_none().0))
        }
    }

    pub fn get_website(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_website(self.to_glib_none().0))
        }
    }

    pub fn get_website_label(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_website_label(self.to_glib_none().0))
        }
    }

    pub fn get_wrap_license(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_about_dialog_get_wrap_license(self.to_glib_none().0))
        }
    }

    pub fn set_artists(&self, artists: &[&str]) {
        unsafe {
            ffi::gtk_about_dialog_set_artists(self.to_glib_none().0, artists.to_glib_none().0);
        }
    }

    pub fn set_authors(&self, authors: &[&str]) {
        unsafe {
            ffi::gtk_about_dialog_set_authors(self.to_glib_none().0, authors.to_glib_none().0);
        }
    }

    pub fn set_comments(&self, comments: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_comments(self.to_glib_none().0, comments.to_glib_none().0);
        }
    }

    pub fn set_copyright(&self, copyright: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_copyright(self.to_glib_none().0, copyright.to_glib_none().0);
        }
    }

    pub fn set_documenters(&self, documenters: &[&str]) {
        unsafe {
            ffi::gtk_about_dialog_set_documenters(self.to_glib_none().0, documenters.to_glib_none().0);
        }
    }

    pub fn set_license(&self, license: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_license(self.to_glib_none().0, license.to_glib_none().0);
        }
    }

    pub fn set_license_type(&self, license_type: License) {
        unsafe {
            ffi::gtk_about_dialog_set_license_type(self.to_glib_none().0, license_type);
        }
    }

    pub fn set_logo(&self, logo: Option<&gdk_pixbuf::Pixbuf>) {
        unsafe {
            ffi::gtk_about_dialog_set_logo(self.to_glib_none().0, logo.to_glib_none().0);
        }
    }

    pub fn set_logo_icon_name(&self, icon_name: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_logo_icon_name(self.to_glib_none().0, icon_name.to_glib_none().0);
        }
    }

    pub fn set_program_name(&self, name: &str) {
        unsafe {
            ffi::gtk_about_dialog_set_program_name(self.to_glib_none().0, name.to_glib_none().0);
        }
    }

    pub fn set_translator_credits(&self, translator_credits: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_translator_credits(self.to_glib_none().0, translator_credits.to_glib_none().0);
        }
    }

    pub fn set_version(&self, version: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_version(self.to_glib_none().0, version.to_glib_none().0);
        }
    }

    pub fn set_website(&self, website: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_website(self.to_glib_none().0, website.to_glib_none().0);
        }
    }

    pub fn set_website_label(&self, website_label: &str) {
        unsafe {
            ffi::gtk_about_dialog_set_website_label(self.to_glib_none().0, website_label.to_glib_none().0);
        }
    }

    pub fn set_wrap_license(&self, wrap_license: bool) {
        unsafe {
            ffi::gtk_about_dialog_set_wrap_license(self.to_glib_none().0, wrap_license.to_glib());
        }
    }

}
<commit_msg>Regen<commit_after>// This file was generated by gir (15fe1aa) from gir-files (11e0e6d)
// DO NOT EDIT

use Bin;
use Buildable;
use Container;
use Dialog;
use License;
use Widget;
use Window;
use ffi;
use gdk_pixbuf;
use glib::object::Downcast;
use glib::translate::*;

glib_wrapper! {
    pub struct AboutDialog(Object<ffi::GtkAboutDialog>): Widget, Container, Bin, Window, Dialog, Buildable;

    match fn {
        get_type => || ffi::gtk_about_dialog_get_type(),
    }
}

impl AboutDialog {
    pub fn new() -> AboutDialog {
        assert_initialized_main_thread!();
        unsafe {
            Widget::from_glib_none(ffi::gtk_about_dialog_new()).downcast_unchecked()
        }
    }

    #[cfg(gtk_3_4)]
    pub fn add_credit_section(&self, section_name: &str, people: &[&str]) {
        unsafe {
            ffi::gtk_about_dialog_add_credit_section(self.to_glib_none().0, section_name.to_glib_none().0, people.to_glib_none().0);
        }
    }

    pub fn get_artists(&self) -> Vec<String> {
        unsafe {
            FromGlibPtrContainer::from_glib_none(ffi::gtk_about_dialog_get_artists(self.to_glib_none().0))
        }
    }

    pub fn get_authors(&self) -> Vec<String> {
        unsafe {
            FromGlibPtrContainer::from_glib_none(ffi::gtk_about_dialog_get_authors(self.to_glib_none().0))
        }
    }

    pub fn get_comments(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_comments(self.to_glib_none().0))
        }
    }

    pub fn get_copyright(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_copyright(self.to_glib_none().0))
        }
    }

    pub fn get_documenters(&self) -> Vec<String> {
        unsafe {
            FromGlibPtrContainer::from_glib_none(ffi::gtk_about_dialog_get_documenters(self.to_glib_none().0))
        }
    }

    pub fn get_license(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_license(self.to_glib_none().0))
        }
    }

    pub fn get_license_type(&self) -> License {
        unsafe {
            ffi::gtk_about_dialog_get_license_type(self.to_glib_none().0)
        }
    }

    pub fn get_logo(&self) -> Option<gdk_pixbuf::Pixbuf> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_logo(self.to_glib_none().0))
        }
    }

    pub fn get_logo_icon_name(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_logo_icon_name(self.to_glib_none().0))
        }
    }

    pub fn get_program_name(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_program_name(self.to_glib_none().0))
        }
    }

    pub fn get_translator_credits(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_translator_credits(self.to_glib_none().0))
        }
    }

    pub fn get_version(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_version(self.to_glib_none().0))
        }
    }

    pub fn get_website(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_website(self.to_glib_none().0))
        }
    }

    pub fn get_website_label(&self) -> Option<String> {
        unsafe {
            from_glib_none(ffi::gtk_about_dialog_get_website_label(self.to_glib_none().0))
        }
    }

    pub fn get_wrap_license(&self) -> bool {
        unsafe {
            from_glib(ffi::gtk_about_dialog_get_wrap_license(self.to_glib_none().0))
        }
    }

    pub fn set_artists(&self, artists: &[&str]) {
        unsafe {
            ffi::gtk_about_dialog_set_artists(self.to_glib_none().0, artists.to_glib_none().0);
        }
    }

    pub fn set_authors(&self, authors: &[&str]) {
        unsafe {
            ffi::gtk_about_dialog_set_authors(self.to_glib_none().0, authors.to_glib_none().0);
        }
    }

    pub fn set_comments(&self, comments: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_comments(self.to_glib_none().0, comments.to_glib_none().0);
        }
    }

    pub fn set_copyright(&self, copyright: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_copyright(self.to_glib_none().0, copyright.to_glib_none().0);
        }
    }

    pub fn set_documenters(&self, documenters: &[&str]) {
        unsafe {
            ffi::gtk_about_dialog_set_documenters(self.to_glib_none().0, documenters.to_glib_none().0);
        }
    }

    pub fn set_license(&self, license: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_license(self.to_glib_none().0, license.to_glib_none().0);
        }
    }

    pub fn set_license_type(&self, license_type: License) {
        unsafe {
            ffi::gtk_about_dialog_set_license_type(self.to_glib_none().0, license_type);
        }
    }

    pub fn set_logo(&self, logo: Option<&gdk_pixbuf::Pixbuf>) {
        unsafe {
            ffi::gtk_about_dialog_set_logo(self.to_glib_none().0, logo.to_glib_none().0);
        }
    }

    pub fn set_logo_icon_name(&self, icon_name: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_logo_icon_name(self.to_glib_none().0, icon_name.to_glib_none().0);
        }
    }

    pub fn set_program_name(&self, name: &str) {
        unsafe {
            ffi::gtk_about_dialog_set_program_name(self.to_glib_none().0, name.to_glib_none().0);
        }
    }

    pub fn set_translator_credits(&self, translator_credits: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_translator_credits(self.to_glib_none().0, translator_credits.to_glib_none().0);
        }
    }

    pub fn set_version(&self, version: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_version(self.to_glib_none().0, version.to_glib_none().0);
        }
    }

    pub fn set_website(&self, website: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_website(self.to_glib_none().0, website.to_glib_none().0);
        }
    }

    pub fn set_website_label(&self, website_label: Option<&str>) {
        unsafe {
            ffi::gtk_about_dialog_set_website_label(self.to_glib_none().0, website_label.to_glib_none().0);
        }
    }

    pub fn set_wrap_license(&self, wrap_license: bool) {
        unsafe {
            ffi::gtk_about_dialog_set_wrap_license(self.to_glib_none().0, wrap_license.to_glib());
        }
    }

}
<|endoftext|>