<commit_before>use std::fmt::{
    Display,
    Formatter,
    Result as FmtResult,
    Write as FmtWrite
};
use crate::model::id::{EmojiId, RoleId};

#[cfg(all(feature = "cache", feature = "model"))]
use serde_json::json;
#[cfg(all(feature = "cache", feature = "model"))]
use crate::internal::prelude::*;
#[cfg(all(feature = "cache", feature = "model"))]
use crate::model::ModelError;
#[cfg(all(feature = "cache", feature = "model"))]
use crate::model::id::GuildId;
#[cfg(all(feature = "cache", feature = "model"))]
use crate::cache::Cache;
#[cfg(all(feature = "cache", feature = "model"))]
use crate::http::CacheHttp;

/// Represents a custom guild emoji, which can either be created using the API,
/// or via an integration. Emojis created using the API only work within the
/// guild it was created in.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct Emoji {
    /// Whether the emoji is animated.
    #[serde(default)]
    pub animated: bool,
    /// The Id of the emoji.
    pub id: EmojiId,
    /// The name of the emoji. It must be at least 2 characters long and can
    /// only contain alphanumeric characters and underscores.
    pub name: String,
    /// Whether the emoji is managed via an [`Integration`] service.
    ///
    /// [`Integration`]: super::Integration
    pub managed: bool,
    /// Whether the emoji name needs to be surrounded by colons in order to be
    /// used by the client.
    pub require_colons: bool,
    /// A list of [`Role`]s that are allowed to use the emoji. If there are no
    /// roles specified, then usage is unrestricted.
    ///
    /// [`Role`]: super::Role
    pub roles: Vec<RoleId>,
}

#[cfg(feature = "model")]
impl Emoji {
    /// Deletes the emoji.
    ///
    /// **Note**: The [Manage Emojis] permission is required.
    ///
    /// **Note**: Only user accounts may use this method.
    ///
    /// [Manage Emojis]: crate::model::permissions::Permissions::MANAGE_EMOJIS
    ///
    /// # Examples
    ///
    /// Delete a given emoji:
    ///
    /// ```rust,no_run
    /// # use serde_json::json;
    /// # use serenity::framework::standard::{CommandResult, macros::command};
    /// # use serenity::client::Context;
    /// # use serenity::model::prelude::{EmojiId, Emoji, Role};
    /// #
    /// # #[command]
    /// # async fn example(ctx: &Context) -> CommandResult {
    /// #     let mut emoji = serde_json::from_value::<Emoji>(json!({
    /// #         "animated": false,
    /// #         "id": EmojiId(7),
    /// #         "name": "blobface",
    /// #         "managed": false,
    /// #         "require_colons": false,
    /// #         "roles": Vec::<Role>::new(),
    /// #     }))?;
    /// #
    /// // assuming emoji has been set already
    /// match emoji.delete(&ctx).await {
    ///     Ok(()) => println!("Emoji deleted."),
    ///     Err(_) => println!("Could not delete emoji.")
    /// }
    /// #    Ok(())
    /// # }
    /// ```
    #[cfg(feature = "cache")]
    #[inline]
    pub async fn delete(&self, cache_http: impl CacheHttp) -> Result<()> {
        let cache = cache_http.cache().ok_or(Error::Model(ModelError::ItemMissing))?;

        match self.find_guild_id(&cache).await {
            Some(guild_id) => cache_http.http().delete_emoji(guild_id.0, self.id.0).await,
            None => Err(Error::Model(ModelError::ItemMissing)),
        }
    }

    /// Edits the emoji by updating it with a new name.
    ///
    /// **Note**: The [Manage Emojis] permission is required.
    ///
    /// **Note**: Only user accounts may use this method.
    ///
    /// [Manage Emojis]: crate::model::permissions::Permissions::MANAGE_EMOJIS
    #[cfg(feature = "cache")]
    pub async fn edit(&mut self, cache_http: impl CacheHttp, name: &str) -> Result<()> {
        let cache = cache_http.cache().ok_or(Error::Model(ModelError::ItemMissing))?;

        match self.find_guild_id(&cache).await {
            Some(guild_id) => {
                let map = json!({
                    "name": name,
                });

                *self = cache_http
                    .http()
                    .edit_emoji(guild_id.0, self.id.0, &map)
                    .await?;

                Ok(())
            },
            None => Err(Error::Model(ModelError::ItemMissing)),
        }
    }

    /// Finds the [`Guild`] that owns the emoji by looking through the Cache.
    ///
    /// [`Guild`]: super::Guild
    ///
    /// # Examples
    ///
    /// Print the guild id that owns this emoji:
    ///
    /// ```rust,no_run
    /// # use serde_json::json;
    /// # use serenity::{cache::Cache, model::{guild::{Emoji, Role}, id::EmojiId}};
    /// # use tokio::sync::RwLock;
    /// # use std::sync::Arc;
    /// #
    /// # async fn run() {
    /// # let cache = Cache::default();
    /// #
    /// # let mut emoji = serde_json::from_value::<Emoji>(json!({
    /// #     "animated": false,
    /// #     "id": EmojiId(7),
    /// #     "name": "blobface",
    /// #     "managed": false,
    /// #     "require_colons": false,
    /// #     "roles": Vec::<Role>::new(),
    /// # })).unwrap();
    /// #
    /// // assuming emoji has been set already
    /// if let Some(guild_id) = emoji.find_guild_id(&cache).await {
    ///     println!("{} is owned by {}", emoji.name, guild_id);
    /// }
    /// # }
    /// ```
    #[cfg(feature = "cache")]
    pub async fn find_guild_id(&self, cache: impl AsRef<Cache>) -> Option<GuildId> {
        for guild in cache.as_ref().guilds.read().await.values() {
            if guild.emojis.contains_key(&self.id) {
                return Some(guild.id);
            }
        }

        None
    }

    /// Generates a URL to the emoji's image.
    ///
    /// # Examples
    ///
    /// Print the direct link to the given emoji:
    ///
    /// ```rust,no_run
    /// # extern crate serde_json;
    /// # extern crate serenity;
    /// #
    /// # use serde_json::json;
    /// # use serenity::model::{guild::{Emoji, Role}, id::EmojiId};
    /// #
    /// # fn main() {
    /// # let mut emoji = serde_json::from_value::<Emoji>(json!({
    /// #     "animated": false,
    /// #     "id": EmojiId(7),
    /// #     "name": "blobface",
    /// #     "managed": false,
    /// #     "require_colons": false,
    /// #     "roles": Vec::<Role>::new(),
    /// # })).unwrap();
    /// #
    /// // assuming emoji has been set already
    /// println!("Direct link to emoji image: {}", emoji.url());
    /// # }
    /// ```
    #[inline]
    pub fn url(&self) -> String {
        let extension = if self.animated {"gif"} else {"png"};
        format!(cdn!("/emojis/{}.{}"), self.id, extension)
    }
}

impl Display for Emoji {
    /// Formats the emoji into a string that will cause Discord clients to
    /// render the emoji.
    ///
    /// This is in the format of either `<:NAME:EMOJI_ID>` for normal emojis,
    /// or `<a:NAME:EMOJI_ID>` for animated emojis.
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        if self.animated {
            f.write_str("<a:")?;
        } else {
            f.write_str("<:")?;
        }
        f.write_str(&self.name)?;
        FmtWrite::write_char(f, ':')?;
        Display::fmt(&self.id, f)?;
        FmtWrite::write_char(f, '>')
    }
}

impl From<Emoji> for EmojiId {
    /// Gets the Id of an `Emoji`.
    fn from(emoji: Emoji) -> EmojiId { emoji.id }
}

impl<'a> From<&'a Emoji> for EmojiId {
    /// Gets the Id of an `Emoji`.
    fn from(emoji: &Emoji) -> EmojiId { emoji.id }
}
<commit_msg>Change signatures of `Emoji` methods to require `Cache` and `Http`. (#1140)<commit_after>use std::fmt::{
    Display,
    Formatter,
    Result as FmtResult,
    Write as FmtWrite
};
use crate::{http::Http, model::id::{EmojiId, RoleId}};

#[cfg(all(feature = "cache", feature = "model"))]
use serde_json::json;
#[cfg(all(feature = "cache", feature = "model"))]
use crate::internal::prelude::*;
#[cfg(all(feature = "cache", feature = "model"))]
use crate::model::ModelError;
#[cfg(all(feature = "cache", feature = "model"))]
use crate::model::id::GuildId;
#[cfg(all(feature = "cache", feature = "model"))]
use crate::cache::Cache;

/// Represents a custom guild emoji, which can either be created using the API,
/// or via an integration. Emojis created using the API only work within the
/// guild it was created in.
#[derive(Clone, Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct Emoji {
    /// Whether the emoji is animated.
    #[serde(default)]
    pub animated: bool,
    /// The Id of the emoji.
    pub id: EmojiId,
    /// The name of the emoji. It must be at least 2 characters long and can
    /// only contain alphanumeric characters and underscores.
    pub name: String,
    /// Whether the emoji is managed via an [`Integration`] service.
    ///
    /// [`Integration`]: super::Integration
    pub managed: bool,
    /// Whether the emoji name needs to be surrounded by colons in order to be
    /// used by the client.
    pub require_colons: bool,
    /// A list of [`Role`]s that are allowed to use the emoji. If there are no
    /// roles specified, then usage is unrestricted.
    ///
    /// [`Role`]: super::Role
    pub roles: Vec<RoleId>,
}

#[cfg(feature = "model")]
impl Emoji {
    /// Deletes the emoji.
    /// This method requires the cache to fetch the guild ID.
    ///
    /// **Note**: The [Manage Emojis] permission is required.
    ///
    /// **Note**: Only user accounts may use this method.
    ///
    /// [Manage Emojis]: crate::model::permissions::Permissions::MANAGE_EMOJIS
    ///
    /// # Examples
    ///
    /// Delete a given emoji:
    ///
    /// ```rust,no_run
    /// # use serde_json::json;
    /// # use serenity::framework::standard::{CommandResult, macros::command};
    /// # use serenity::client::Context;
    /// # use serenity::model::prelude::{EmojiId, Emoji, Role};
    /// #
    /// # #[command]
    /// # async fn example(ctx: &Context) -> CommandResult {
    /// #     let mut emoji = serde_json::from_value::<Emoji>(json!({
    /// #         "animated": false,
    /// #         "id": EmojiId(7),
    /// #         "name": "blobface",
    /// #         "managed": false,
    /// #         "require_colons": false,
    /// #         "roles": Vec::<Role>::new(),
    /// #     }))?;
    /// #
    /// // assuming emoji has been set already
    /// match emoji.delete(&ctx).await {
    ///     Ok(()) => println!("Emoji deleted."),
    ///     Err(_) => println!("Could not delete emoji.")
    /// }
    /// #    Ok(())
    /// # }
    /// ```
    #[cfg(feature = "cache")]
    #[inline]
    pub async fn delete<T: AsRef<Cache> + AsRef<Http>>(&self, cache_http: T) -> Result<()> {
        match self.find_guild_id(&cache_http).await {
            Some(guild_id) => AsRef::<Http>::as_ref(&cache_http)
                .delete_emoji(guild_id.0, self.id.0).await,
            None => Err(Error::Model(ModelError::ItemMissing)),
        }
    }

    /// Edits the emoji by updating it with a new name.
    /// This method requires the cache to fetch the guild ID.
    ///
    /// **Note**: The [Manage Emojis] permission is required.
    ///
    /// **Note**: Only user accounts may use this method.
    ///
    /// [Manage Emojis]: crate::model::permissions::Permissions::MANAGE_EMOJIS
    #[cfg(feature = "cache")]
    pub async fn edit<T: AsRef<Cache> + AsRef<Http>>(&mut self, cache_http: T, name: &str) -> Result<()> {
        match self.find_guild_id(&cache_http).await {
            Some(guild_id) => {
                let map = json!({
                    "name": name,
                });

                *self = AsRef::<Http>::as_ref(&cache_http)
                    .edit_emoji(guild_id.0, self.id.0, &map)
                    .await?;

                Ok(())
            },
            None => Err(Error::Model(ModelError::ItemMissing)),
        }
    }

    /// Finds the [`Guild`] that owns the emoji by looking through the Cache.
    ///
    /// [`Guild`]: super::Guild
    ///
    /// # Examples
    ///
    /// Print the guild id that owns this emoji:
    ///
    /// ```rust,no_run
    /// # use serde_json::json;
    /// # use serenity::{cache::Cache, model::{guild::{Emoji, Role}, id::EmojiId}};
    /// # use tokio::sync::RwLock;
    /// # use std::sync::Arc;
    /// #
    /// # async fn run() {
    /// # let cache = Cache::default();
    /// #
    /// # let mut emoji = serde_json::from_value::<Emoji>(json!({
    /// #     "animated": false,
    /// #     "id": EmojiId(7),
    /// #     "name": "blobface",
    /// #     "managed": false,
    /// #     "require_colons": false,
    /// #     "roles": Vec::<Role>::new(),
    /// # })).unwrap();
    /// #
    /// // assuming emoji has been set already
    /// if let Some(guild_id) = emoji.find_guild_id(&cache).await {
    ///     println!("{} is owned by {}", emoji.name, guild_id);
    /// }
    /// # }
    /// ```
    #[cfg(feature = "cache")]
    pub async fn find_guild_id(&self, cache: impl AsRef<Cache>) -> Option<GuildId> {
        for guild in cache.as_ref().guilds.read().await.values() {
            if guild.emojis.contains_key(&self.id) {
                return Some(guild.id);
            }
        }

        None
    }

    /// Generates a URL to the emoji's image.
    ///
    /// # Examples
    ///
    /// Print the direct link to the given emoji:
    ///
    /// ```rust,no_run
    /// # extern crate serde_json;
    /// # extern crate serenity;
    /// #
    /// # use serde_json::json;
    /// # use serenity::model::{guild::{Emoji, Role}, id::EmojiId};
    /// #
    /// # fn main() {
    /// # let mut emoji = serde_json::from_value::<Emoji>(json!({
    /// #     "animated": false,
    /// #     "id": EmojiId(7),
    /// #     "name": "blobface",
    /// #     "managed": false,
    /// #     "require_colons": false,
    /// #     "roles": Vec::<Role>::new(),
    /// # })).unwrap();
    /// #
    /// // assuming emoji has been set already
    /// println!("Direct link to emoji image: {}", emoji.url());
    /// # }
    /// ```
    #[inline]
    pub fn url(&self) -> String {
        let extension = if self.animated {"gif"} else {"png"};
        format!(cdn!("/emojis/{}.{}"), self.id, extension)
    }
}

impl Display for Emoji {
    /// Formats the emoji into a string that will cause Discord clients to
    /// render the emoji.
    ///
    /// This is in the format of either `<:NAME:EMOJI_ID>` for normal emojis,
    /// or `<a:NAME:EMOJI_ID>` for animated emojis.
    fn fmt(&self, f: &mut Formatter<'_>) -> FmtResult {
        if self.animated {
            f.write_str("<a:")?;
        } else {
            f.write_str("<:")?;
        }
        f.write_str(&self.name)?;
        FmtWrite::write_char(f, ':')?;
        Display::fmt(&self.id, f)?;
        FmtWrite::write_char(f, '>')
    }
}

impl From<Emoji> for EmojiId {
    /// Gets the Id of an `Emoji`.
    fn from(emoji: Emoji) -> EmojiId { emoji.id }
}

impl<'a> From<&'a Emoji> for EmojiId {
    /// Gets the Id of an `Emoji`.
    fn from(emoji: &Emoji) -> EmojiId { emoji.id }
}
<|endoftext|>


<commit_before>use websocket::{client,Client,stream,Message,Sender,Receiver};
use hyper::Url;
use std::thread;
use rustc_serialize::json::*;

use value::Value;
use server::Event;
use relation::Change;

pub fn open_websocket(url_string: &str) -> Result<client::sender::Sender<stream::WebSocketStream>,String> {

	//let mut context = SslContext::new(SslMethod::Tlsv1).unwrap();
	//let _ = context.set_certificate_file(&(Path::new("server.crt")), X509FileType::PEM);
	//let _ = context.set_private_key_file(&(Path::new("server.key")), X509FileType::PEM);

	let url = Url::parse(url_string).unwrap();
	println!("Connecting to {}", url);

	let request = match Client::connect(url) {
		Ok(t) => t,
		Err(e) => {
			return Err(format!("{}", e).to_string());
		}
	};

	let response = match request.send() {
		Ok(t) => t,
		Err(e) => {
			return Err(format!("{}", e).to_string());
		}
	};

	match response.validate() {
		Ok(_) => println!("Response valid. Start sending/receiving..."),
		Err(e) => {
			return Err(format!("{}", e).to_string());
		}
	};

	let (sender, mut receiver) = response.begin().split();

	thread::spawn(move || {
		for message in receiver.incoming_messages() {
	        let message = match message {
	            Ok(m) => m,
	            Err(_) => return,
	        };
	        match message {
	            Message::Text(_) => {
	           		//let json = Json::from_str(&text).unwrap();
                    //let event: Event = FromJson::from_json(&json);
	        	},
	            Message::Close(_) => {
	                println!("Received close message");
	                return;
	            }
	            _ => println!("Unknown message: {:?}", message)
	        }
        }
	});

	Ok(sender)
}

pub fn send_event(event: &Event,sender: &mut client::sender::Sender<stream::WebSocketStream>) {

	sender.send_message(Message::Text(event.to_json().to_string())).unwrap();
}

pub fn create_table(table_name: &&str, table_fields: &Vec<&str>) -> Event {

	let table_string = Value::String(table_name.to_string());

	// Creates a vector of names of the form: "table_name: field_name"
	let concat_field_names = table_fields.iter()
										 .map(|field_name| Value::String(table_name.to_string() + ": " + field_name))
										 .collect::<Vec<_>>();

	// Concats a vector of display names of the form: (display name: id, display name: name)
	let display_name_fields = concat_field_names.iter()
												.zip(table_fields.iter())
												.map(|(concat_name,field_name)| vec![concat_name.clone(),Value::String(field_name.to_string())])
												.collect::<Vec<_>>();

	// Creates the display name insert
	let display_name_inserts = vec![vec![table_string.clone(),table_string.clone()]];
	display_name_inserts.iter().chain(display_name_fields.iter()).collect::<Vec<_>>();

	let display_name = ("display name".to_string(),Change {
												fields: vec!["display name: id".to_string(),"display name: name".to_string()],
												insert: display_name_inserts,
												remove: vec![],
											}
						);

	let view = ("view".to_string(),Change   {
												fields: vec!["view: view".to_string(),"view: kind".to_string()],
												insert: vec![
																vec![table_string.clone(),Value::String("table".to_string())],
															],
												remove: vec![],
											}
				);

	// Create field insert vector of the from: [field: view, field: field, "output"]
	let field_inserts = concat_field_names.iter()
										  .map(|concat_field| vec![table_string.clone(), concat_field.clone(), Value::String("output".to_string())])
										  .collect::<Vec<_>>();

	let field = ("field".to_string(),Change {
												fields: vec!["field: view".to_string(),"field: field".to_string(),"field: kind".to_string()],
												insert: field_inserts,
												remove: vec![],
											}
				);

	Event{changes: vec![display_name,view,field] }
}

// TODO make sure table exists before trying to insert a fact into it
pub fn insert_fact(table_name: &&str, table_fields: &Vec<&str>, row_data: &Vec<Value>) -> Event {

	assert_eq!(table_fields.len(),row_data.len());

	// Creates a vector of names of the form: "table_name: field_name"
	let concat_field_names = table_fields.iter()
										 .map(|field_name| table_name.to_string() + ": " + field_name)
										 .collect();

	Event{changes: vec![(table_name.to_string(),Change{
														fields: concat_field_names,
												    	insert: vec![row_data.clone()],
												      	remove: vec![],
												      }
						)]
		 }
}<commit_msg>Send events from client as CBOR<commit_after>use websocket::{client,Client,stream,Message,Sender,Receiver};
use hyper::Url;
use std::thread;
use rustc_serialize::json::*;
use cbor::ToCbor;
use cbor;

use value::Value;
use server::Event;
use relation::Change;

pub fn open_websocket(url_string: &str) -> Result<client::sender::Sender<stream::WebSocketStream>,String> {

	//let mut context = SslContext::new(SslMethod::Tlsv1).unwrap();
	//let _ = context.set_certificate_file(&(Path::new("server.crt")), X509FileType::PEM);
	//let _ = context.set_private_key_file(&(Path::new("server.key")), X509FileType::PEM);

	let url = Url::parse(url_string).unwrap();
	println!("Connecting to {}", url);

	let request = match Client::connect(url) {
		Ok(t) => t,
		Err(e) => {
			return Err(format!("{}", e).to_string());
		}
	};

	let response = match request.send() {
		Ok(t) => t,
		Err(e) => {
			return Err(format!("{}", e).to_string());
		}
	};

	match response.validate() {
		Ok(_) => println!("Response valid. Start sending/receiving..."),
		Err(e) => {
			return Err(format!("{}", e).to_string());
		}
	};

	let (sender, mut receiver) = response.begin().split();

	thread::spawn(move || {
		for message in receiver.incoming_messages() {
	        let message = match message {
	            Ok(m) => m,
	            Err(_) => return,
	        };
	        match message {
	            Message::Text(_) => {
	           		//let json = Json::from_str(&text).unwrap();
                    //let event: Event = FromJson::from_json(&json);
	        	},
	            Message::Close(_) => {
	                println!("Received close message");
	                return;
	            }
	            _ => println!("Unknown message: {:?}", message)
	        }
        }
	});

	Ok(sender)
}

pub fn send_event(event: &Event,sender: &mut client::sender::Sender<stream::WebSocketStream>) {

	let mut e = cbor::Encoder::from_memory();
	let json = event.to_json();
	let cbor = json.to_cbor();
	e.encode(vec![cbor]).unwrap();
	sender.send_message(Message::Binary(e.into_bytes())).unwrap();
}

pub fn create_table(table_name: &&str, table_fields: &Vec<&str>) -> Event {

	let table_string = Value::String(table_name.to_string());

	// Creates a vector of names of the form: "table_name: field_name"
	let concat_field_names = table_fields.iter()
										 .map(|field_name| Value::String(table_name.to_string() + ": " + field_name))
										 .collect::<Vec<_>>();

	// Concats a vector of display names of the form: (display name: id, display name: name)
	let display_name_fields = concat_field_names.iter()
												.zip(table_fields.iter())
												.map(|(concat_name,field_name)| vec![concat_name.clone(),Value::String(field_name.to_string())])
												.collect::<Vec<_>>();

	// Creates the display name insert
	let display_name_inserts = vec![vec![table_string.clone(),table_string.clone()]];
	display_name_inserts.iter().chain(display_name_fields.iter()).collect::<Vec<_>>();

	let display_name = ("display name".to_string(),Change {
												fields: vec!["display name: id".to_string(),"display name: name".to_string()],
												insert: display_name_inserts,
												remove: vec![],
											}
						);

	let view = ("view".to_string(),Change   {
												fields: vec!["view: view".to_string(),"view: kind".to_string()],
												insert: vec![
																vec![table_string.clone(),Value::String("table".to_string())],
															],
												remove: vec![],
											}
				);

	// Create field insert vector of the from: [field: view, field: field, "output"]
	let field_inserts = concat_field_names.iter()
										  .map(|concat_field| vec![table_string.clone(), concat_field.clone(), Value::String("output".to_string())])
										  .collect::<Vec<_>>();

	let field = ("field".to_string(),Change {
												fields: vec!["field: view".to_string(),"field: field".to_string(),"field: kind".to_string()],
												insert: field_inserts,
												remove: vec![],
											}
				);

	Event{changes: vec![display_name,view,field] }
}

// TODO make sure table exists before trying to insert a fact into it
pub fn insert_fact(table_name: &&str, table_fields: &Vec<&str>, row_data: &Vec<Value>) -> Event {

	assert_eq!(table_fields.len(),row_data.len());

	// Creates a vector of names of the form: "table_name: field_name"
	let concat_field_names = table_fields.iter()
										 .map(|field_name| table_name.to_string() + ": " + field_name)
										 .collect();

	Event{changes: vec![(table_name.to_string(),Change{
														fields: concat_field_names,
												    	insert: vec![row_data.clone()],
												      	remove: vec![],
												      }
						)]
		 }
}<|endoftext|>


<commit_before>pub fn primes_up_to(limit: u32) -> Vec<u32> {
    if limit < 2 {
        return Vec::new();
    }

    let upper = (limit as f64).sqrt().ceil() as usize;

    let mut board = vec![true; limit as usize - 1];

    for i in 2..upper {
        if !board[i - 2] {
            continue;
        }

        let mut v = i * i;

        while v <= limit as usize {
            board[v - 2] = false;

            v += i;
        }
    }

    (2..limit + 1)
        .filter(|&x| board[x as usize - 2])
        .collect::<Vec<u32>>()
}
<commit_msg>Simplify code<commit_after>pub fn primes_up_to(limit: u32) -> Vec<u32> {
    if limit < 2 {
        return Vec::new();
    }

    let upper = (limit as f64).sqrt().ceil() as usize;

    let mut board = vec![true; limit as usize - 1];

    for i in 2..upper {
        if !board[i - 2] {
            continue;
        }

        let mut v = i * i;

        while v <= limit as usize {
            board[v - 2] = false;

            v += i;
        }
    }

    (2..limit + 1).filter(|&x| board[x as usize - 2]).collect()
}
<|endoftext|>


<commit_before>extern crate rayon_core;

use rayon_core::ThreadPoolBuilder;

use std::env;
use std::process::Command;

#[cfg(target_os = "linux")]
use std::os::unix::process::ExitStatusExt;

fn force_stack_overflow(depth: u32) {
    let _buffer = [0u8; 1024 * 1024];
    if depth > 0 {
        force_stack_overflow(depth - 1);
    }
}

fn main() {
    if env::args().len() == 1 {
        // first check that the recursivecall actually causes a stack overflow, and does not get optimized away
        {
            let status = Command::new(env::current_exe().unwrap())
                .arg("8")
                .status()
                .unwrap();

            #[cfg(windows)]
            assert_eq!(status.code(), Some(0xc00000fd /*STATUS_STACK_OVERFLOW*/));

            #[cfg(unix)]
            assert_eq!(status.code(), None);

            #[cfg(target_os = "linux")]
            assert!(
                status.signal() == Some(11 /*SIGABRT*/) || status.signal() == Some(6 /*SIGSEGV*/)
            );
        }

        // now run with a larger stack and verify correct operation
        {
            let status = Command::new(env::current_exe().unwrap())
                .arg("48")
                .status()
                .unwrap();
            assert_eq!(status.code(), Some(0));
            #[cfg(target_os = "linux")]
            assert_eq!(status.signal(), None);
        }
    } else {
        let stack_size_in_mb: usize = env::args().nth(1).unwrap().parse().unwrap();
        let pool = ThreadPoolBuilder::new()
            .stack_size(stack_size_in_mb * 1024 * 1024)
            .build()
            .unwrap();
        pool.install(|| {
            force_stack_overflow(32);
        });
    }
}
<commit_msg>[windows] avoid overflowing literal STATUS_STACK_OVERFLOW as i32<commit_after>extern crate rayon_core;

use rayon_core::ThreadPoolBuilder;

use std::env;
use std::process::Command;

#[cfg(target_os = "linux")]
use std::os::unix::process::ExitStatusExt;

fn force_stack_overflow(depth: u32) {
    let _buffer = [0u8; 1024 * 1024];
    if depth > 0 {
        force_stack_overflow(depth - 1);
    }
}

#[cfg(unix)]
fn overflow_code() -> Option<i32> {
    None
}

#[cfg(windows)]
fn overflow_code() -> Option<i32> {
    use std::os::windows::process::ExitStatusExt;
    use std::process::ExitStatus;

    ExitStatus::from_raw(0xc00000fd /*STATUS_STACK_OVERFLOW*/).code()
}

fn main() {
    if env::args().len() == 1 {
        // first check that the recursivecall actually causes a stack overflow, and does not get optimized away
        {
            let status = Command::new(env::current_exe().unwrap())
                .arg("8")
                .status()
                .unwrap();

            #[cfg(any(unix, windows))]
            assert_eq!(status.code(), overflow_code());

            #[cfg(target_os = "linux")]
            assert!(
                status.signal() == Some(11 /*SIGABRT*/) || status.signal() == Some(6 /*SIGSEGV*/)
            );
        }

        // now run with a larger stack and verify correct operation
        {
            let status = Command::new(env::current_exe().unwrap())
                .arg("48")
                .status()
                .unwrap();
            assert_eq!(status.code(), Some(0));
            #[cfg(target_os = "linux")]
            assert_eq!(status.signal(), None);
        }
    } else {
        let stack_size_in_mb: usize = env::args().nth(1).unwrap().parse().unwrap();
        let pool = ThreadPoolBuilder::new()
            .stack_size(stack_size_in_mb * 1024 * 1024)
            .build()
            .unwrap();
        pool.install(|| {
            force_stack_overflow(32);
        });
    }
}
<|endoftext|>


<commit_before>//
//
//
/// Returns true if the passed exppression matches the pattern
#[macro_export]
macro_rules! is
{
	($val:expr, $p:pat) => ( match $val { $p => true, _ => false } );
}

#[doc(hidden)]
#[macro_export]
macro_rules! _count
{
	() => {0};
	($a:expr) => {1};
	($a:expr, $($b:expr)+) => {1+_count!($($b),+)};
}

/// Define a kernel module (creates the module header, containg the name and dependency strings)
#[macro_export]
macro_rules! module_define
{
	($name:ident, [$($deps:ident),*], $init:path) => (
		//#[assume_reachable]
		#[doc(hidden)]
		#[link_section = ".MODULE_LIST"]
		pub static _S_MODULE: $crate::modules::ModuleInfo = $crate::modules::ModuleInfo {
			name: stringify!($name),
			init: $init,
			deps: &S_DEPS,
			_rsvd: 0,
		};
		#[doc(hidden)]
		static S_DEPS: [&'static str; _count!($($deps),*)] = [$(stringify!($deps)),*];
	);
}

/// Ensure that a type implments the provided trait
///
/// Useful for "Send" and "Sync"
#[macro_export]
macro_rules! assert_trait
{
	($t:ty : $tr:ident) => { #[allow(warnings)] fn assert_trait<T: $tr>() { assert_trait::<$t>() } }
}

/// A safe wrapper around the `type_name` intrinsic
#[macro_export]
macro_rules! type_name
{
	($t:ty) => ( unsafe { ::core::intrinsics::type_name::<$t>() } )
}

/// Provides a short and noticable "TODO: " message
#[macro_export]
macro_rules! todo
{
	( $s:expr ) => ( panic!( concat!("TODO: ",$s) ) );
	( $s:expr, $($v:tt)* ) => ( panic!( concat!("TODO: ",$s), $($v)* ) );
}

/// Provides a less boiler-plate way to implement fmt traits for simple types
///
/// Only supports non-generic types and unbounded types (due to challenges in matching generic definitions)
///
/// ```
/// impl_fmt! {
///     Debug(self, f) for Type {
///         write!(f, "Hello world!")
///     }
///     <T> Display(self, f) for Container {
///         write!(f, "Hello world!")
///     }
/// }
/// ```
#[macro_export]
macro_rules! impl_fmt
{
	( $( <$($g:ident),+> $tr:ident ($s:ident, $f:ident) for $ty:ty { $code:expr } )+ ) => { $(
		impl<$($g),+> ::core::fmt::$tr for $ty {
			fn fmt(&$s, $f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
				$code
			}
		}
		)+
		};

	( $( $tr:ident ($s:ident, $f:ident) for $ty:ty { $code:expr } )+ ) => { $(
		impl ::core::fmt::$tr for $ty {
			fn fmt(&$s, $f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
				$code
			}
		}
		)+
		};
}

// NOTE: This should really be in ::threads::wait_queue, but it also needs to be early in parse
/// Wait on a wait queue contained within a spinlock
///
/// Due to lifetime issues, the more erganomical `lock.queue.wait(lock)` does not pass borrow checking.
macro_rules! waitqueue_wait_ext {
	($lock:expr, $field:ident) => ({
		let mut lock: $crate::arch::sync::HeldSpinlock<_> = $lock;
		let irql = lock.$field.wait_int();
		::core::mem::drop(lock);
		::core::mem::drop(irql);
		$crate::threads::reschedule();
		});
}

// vim: ft=rust
<commit_msg>Macros - Fix minor error in _count! macro<commit_after>//
//
//
/// Returns true if the passed exppression matches the pattern
#[macro_export]
macro_rules! is
{
	($val:expr, $p:pat) => ( match $val { $p => true, _ => false } );
}

#[doc(hidden)]
#[macro_export]
macro_rules! _count
{
	() => {0};
	($a:expr) => {1};
	($a:expr, $($b:expr),+) => {1+_count!($($b),+)};
}

/// Define a kernel module (creates the module header, containg the name and dependency strings)
#[macro_export]
macro_rules! module_define
{
	($name:ident, [$($deps:ident),*], $init:path) => (
		//#[assume_reachable]
		#[doc(hidden)]
		#[link_section = ".MODULE_LIST"]
		pub static _S_MODULE: $crate::modules::ModuleInfo = $crate::modules::ModuleInfo {
			name: stringify!($name),
			init: $init,
			deps: &S_DEPS,
			_rsvd: 0,
		};
		#[doc(hidden)]
		static S_DEPS: [&'static str; _count!($($deps),*)] = [$(stringify!($deps)),*];
	);
}

/// Ensure that a type implments the provided trait
///
/// Useful for "Send" and "Sync"
#[macro_export]
macro_rules! assert_trait
{
	($t:ty : $tr:ident) => { #[allow(warnings)] fn assert_trait<T: $tr>() { assert_trait::<$t>() } }
}

/// A safe wrapper around the `type_name` intrinsic
#[macro_export]
macro_rules! type_name
{
	($t:ty) => ( unsafe { ::core::intrinsics::type_name::<$t>() } )
}

/// Provides a short and noticable "TODO: " message
#[macro_export]
macro_rules! todo
{
	( $s:expr ) => ( panic!( concat!("TODO: ",$s) ) );
	( $s:expr, $($v:tt)* ) => ( panic!( concat!("TODO: ",$s), $($v)* ) );
}

/// Provides a less boiler-plate way to implement fmt traits for simple types
///
/// Only supports non-generic types and unbounded types (due to challenges in matching generic definitions)
///
/// ```
/// impl_fmt! {
///     Debug(self, f) for Type {
///         write!(f, "Hello world!")
///     }
///     <T> Display(self, f) for Container {
///         write!(f, "Hello world!")
///     }
/// }
/// ```
#[macro_export]
macro_rules! impl_fmt
{
	( $( <$($g:ident),+> $tr:ident ($s:ident, $f:ident) for $ty:ty { $code:expr } )+ ) => { $(
		impl<$($g),+> ::core::fmt::$tr for $ty {
			fn fmt(&$s, $f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
				$code
			}
		}
		)+
		};

	( $( $tr:ident ($s:ident, $f:ident) for $ty:ty { $code:expr } )+ ) => { $(
		impl ::core::fmt::$tr for $ty {
			fn fmt(&$s, $f: &mut ::core::fmt::Formatter) -> ::core::fmt::Result {
				$code
			}
		}
		)+
		};
}

// NOTE: This should really be in ::threads::wait_queue, but it also needs to be early in parse
/// Wait on a wait queue contained within a spinlock
///
/// Due to lifetime issues, the more erganomical `lock.queue.wait(lock)` does not pass borrow checking.
macro_rules! waitqueue_wait_ext {
	($lock:expr, $field:ident) => ({
		let mut lock: $crate::arch::sync::HeldSpinlock<_> = $lock;
		let irql = lock.$field.wait_int();
		::core::mem::drop(lock);
		::core::mem::drop(irql);
		$crate::threads::reschedule();
		});
}

// vim: ft=rust
<|endoftext|>


<commit_before>//! Lints concerned with the grouping of digits with underscores in integral or
//! floating-point literal expressions.

use rustc::lint::*;
use syntax::ast::*;
use syntax_pos;
use utils::{span_help_and_lint, snippet_opt, in_external_macro};

/// **What it does:** Warns if a long integral or floating-point constant does
/// not contain underscores.
///
/// **Why is this bad?** Reading long numbers is difficult without separators.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// 61864918973511
/// ```
declare_lint! {
    pub UNREADABLE_LITERAL,
    Warn,
    "long integer literal without underscores"
}

/// **What it does:** Warns if an integral or floating-point constant is
/// grouped inconsistently with underscores.
///
/// **Why is this bad?** Readers may incorrectly interpret inconsistently
/// grouped digits.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// 618_64_9189_73_511
/// ```
declare_lint! {
    pub INCONSISTENT_DIGIT_GROUPING,
    Warn,
    "integer literals with digits grouped inconsistently"
}

/// **What it does:** Warns if the digits of an integral or floating-point
/// constant are grouped into groups that
/// are too large.
///
/// **Why is this bad?** Negatively impacts readability.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// 6186491_8973511
/// ```
declare_lint! {
    pub LARGE_DIGIT_GROUPS,
    Warn,
    "grouping digits into groups that are too large"
}

#[derive(Debug)]
enum Radix {
    Binary,
    Octal,
    Decimal,
    Hexadecimal,
}

impl Radix {
    /// Return a reasonable digit group size for this radix.
    pub fn suggest_grouping(&self) -> usize {
        match *self {
            Radix::Binary | Radix::Hexadecimal => 4,
            Radix::Octal | Radix::Decimal => 3,
        }
    }
}

#[derive(Debug)]
struct DigitInfo<'a> {
    /// Characters of a literal between the radix prefix and type suffix.
    pub digits: &'a str,
    /// Which radix the literal was represented in.
    pub radix: Radix,
    /// The radix prefix, if present.
    pub prefix: Option<&'a str>,
    /// The type suffix, including preceding underscore if present.
    pub suffix: Option<&'a str>,
    /// True for floating-point literals.
    pub float: bool,
}

impl<'a> DigitInfo<'a> {
    pub fn new(lit: &str, float: bool) -> DigitInfo {
        // Determine delimiter for radix prefix, if present, and radix.
        let radix = if lit.starts_with("0x") {
            Radix::Hexadecimal
        } else if lit.starts_with("0b") {
            Radix::Binary
        } else if lit.starts_with("0o") {
            Radix::Octal
        } else {
            Radix::Decimal
        };

        // Grab part of the literal after prefix, if present.
        let (prefix, sans_prefix) = if let Radix::Decimal = radix {
            (None, lit)
        } else {
            let (p, s) = lit.split_at(2);
            (Some(p), s)
        };

        let mut last_d = '\0';
        for (d_idx, d) in sans_prefix.char_indices() {
            if !float && (d == 'i' || d == 'u') || float && d == 'f' {
                let suffix_start = if last_d == '_' { d_idx - 1 } else { d_idx };
                let (digits, suffix) = sans_prefix.split_at(suffix_start);
                return DigitInfo {
                    digits: digits,
                    radix: radix,
                    prefix: prefix,
                    suffix: Some(suffix),
                    float: float,
                };
            }
            last_d = d
        }

        // No suffix found
        DigitInfo {
            digits: sans_prefix,
            radix: radix,
            prefix: prefix,
            suffix: None,
            float: float,
        }
    }

    /// Returns digits grouped in a sensible way.
    fn grouping_hint(&self) -> String {
        let group_size = self.radix.suggest_grouping();
        if self.digits.contains('.') {
            let mut parts = self.digits.split(".");
            let int_part_hint = parts
                .next()
                .unwrap()
                .chars()
                .rev()
                .filter(|&c| c != '_')
                .collect::<Vec<_>>()
                .chunks(group_size)
                .map(|chunk| chunk.into_iter().rev().collect())
                .rev()
                .collect::<Vec<String>>()
                .join("_");
            let frac_part_hint = parts
                .next()
                .unwrap()
                .chars()
                .filter(|&c| c != '_')
                .collect::<Vec<_>>()
                .chunks(group_size)
                .map(|chunk| chunk.into_iter().collect())
                .collect::<Vec<String>>()
                .join("_");
            format!("{}.{}{}", int_part_hint, frac_part_hint, self.suffix.unwrap_or(""))
        } else {
            let hint = self.digits
                .chars()
                .rev()
                .filter(|&c| c != '_')
                .collect::<Vec<_>>()
                .chunks(group_size)
                .map(|chunk| chunk.into_iter().rev().collect())
                .rev()
                .collect::<Vec<String>>()
                .join("_");
            format!("{}{}{}", self.prefix.unwrap_or(""), hint, self.suffix.unwrap_or(""))
        }
    }
}

enum WarningType {
    UnreadableLiteral,
    InconsistentDigitGrouping,
    LargeDigitGroups,
}

impl WarningType {
    pub fn display(&self, grouping_hint: &str, cx: &EarlyContext, span: &syntax_pos::Span) {
        match *self {
            WarningType::UnreadableLiteral => {
                span_help_and_lint(
                    cx,
                    UNREADABLE_LITERAL,
                    *span,
                    "long literal lacking separators",
                    &format!("consider: {}", grouping_hint),
                )
            },
            WarningType::LargeDigitGroups => {
                span_help_and_lint(
                    cx,
                    LARGE_DIGIT_GROUPS,
                    *span,
                    "digit groups should be smaller",
                    &format!("consider: {}", grouping_hint),
                )
            },
            WarningType::InconsistentDigitGrouping => {
                span_help_and_lint(
                    cx,
                    INCONSISTENT_DIGIT_GROUPING,
                    *span,
                    "digits grouped inconsistently by underscores",
                    &format!("consider: {}", grouping_hint),
                )
            },
        };
    }
}

#[derive(Copy, Clone)]
pub struct LiteralDigitGrouping;

impl LintPass for LiteralDigitGrouping {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNREADABLE_LITERAL, INCONSISTENT_DIGIT_GROUPING, LARGE_DIGIT_GROUPS)
    }
}

impl EarlyLintPass for LiteralDigitGrouping {
    fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
        if in_external_macro(cx, expr.span) {
            return;
        }

        if let ExprKind::Lit(ref lit) = expr.node {
            self.check_lit(cx, lit)
        }
    }
}

impl LiteralDigitGrouping {
    fn check_lit(&self, cx: &EarlyContext, lit: &Lit) {
        // Lint integral literals.
        if_let_chain! {[
            let LitKind::Int(..) = lit.node,
            let Some(src) = snippet_opt(cx, lit.span),
            let Some(firstch) = src.chars().next(),
            char::to_digit(firstch, 10).is_some()
        ], {
            let digit_info = DigitInfo::new(&src, false);
            let _ = LiteralDigitGrouping::do_lint(digit_info.digits).map_err(|warning_type| {
                warning_type.display(&digit_info.grouping_hint(), cx, &lit.span)
            });
        }}

        // Lint floating-point literals.
        if_let_chain! {[
            let LitKind::Float(..) = lit.node,
            let Some(src) = snippet_opt(cx, lit.span),
            let Some(firstch) = src.chars().next(),
            char::to_digit(firstch, 10).is_some()
        ], {
            let digit_info = DigitInfo::new(&src, true);
            // Separate digits into integral and fractional parts.
            let parts: Vec<&str> = digit_info
                .digits
                .split_terminator('.')
                .collect();

            // Lint integral and fractional parts separately, and then check consistency of digit
            // groups if both pass.
            if let Some(integral_group_size) = LiteralDigitGrouping::do_lint(digits[0], cx, &lit.span) {
                if digits.len() > 1 {
                    // Lint the fractional part of literal just like integral part, but reversed.
                    let fractional_part = &digits[1].chars().rev().collect::<String>();
                    if let Some(fractional_group_size) = LiteralDigitGrouping::do_lint(fractional_part, cx, &lit.span) {
                        let consistent = match (integral_group_size, fractional_group_size) {
                            // No groups on either side of decimal point - good to go.
                            (0, 0) => true,
                            // Integral part has grouped digits, fractional part does not.
                            (_, 0) => digits[1].len() <= integral_group_size,
                            // Fractional part has grouped digits, integral part does not.
                            (0, _) => digits[0].len() <= fractional_group_size,
                            // Both parts have grouped digits. Groups should be the same size.
                            (_, _) => integral_group_size == fractional_group_size,
                        };

                        if !consistent {
                            span_help_and_lint(cx, INCONSISTENT_DIGIT_GROUPING, lit.span,
                                           "digits grouped inconsistently by underscores",
                                           "consider making each group three or four digits");
                        }
                    }
                }
            }
        }}
    }

        }
    }

    /// Performs lint on `digits` (no decimal point) and returns the group
    /// size on success or `WarningType` when emitting a warning.
    fn do_lint(digits: &str) -> Result<usize, WarningType> {
        // Grab underscore indices with respect to the units digit.
        let underscore_positions: Vec<usize> = digits
            .chars()
            .rev()
            .enumerate()
            .filter_map(|(idx, digit)| if digit == '_' { Some(idx) } else { None })
            .collect();

        if underscore_positions.is_empty() {
            // Check if literal needs underscores.
            if digits.len() > 4 {
                return Err(WarningType::UnreadableLiteral);
            } else {
                return Ok(0);
            }
        } else {
            // Check consistency and the sizes of the groups.
            let group_size = underscore_positions[0];
            let consistent = underscore_positions
                .windows(2)
                .all(|ps| ps[1] - ps[0] == group_size + 1)
                // number of digits to the left of the last group cannot be bigger than group size.
                && (digits.len() - underscore_positions.last().unwrap() <= group_size + 1);

            if !consistent {
                return Err(WarningType::InconsistentDigitGrouping);
            } else if group_size > 4 {
                return Err(WarningType::LargeDigitGroups);
            }
            return Ok(group_size);
        }
    }
}
<commit_msg>Loose ends and factor out consistency logic.<commit_after>//! Lints concerned with the grouping of digits with underscores in integral or
//! floating-point literal expressions.

use rustc::lint::*;
use syntax::ast::*;
use syntax_pos;
use utils::{span_help_and_lint, snippet_opt, in_external_macro};

/// **What it does:** Warns if a long integral or floating-point constant does
/// not contain underscores.
///
/// **Why is this bad?** Reading long numbers is difficult without separators.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// 61864918973511
/// ```
declare_lint! {
    pub UNREADABLE_LITERAL,
    Warn,
    "long integer literal without underscores"
}

/// **What it does:** Warns if an integral or floating-point constant is
/// grouped inconsistently with underscores.
///
/// **Why is this bad?** Readers may incorrectly interpret inconsistently
/// grouped digits.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// 618_64_9189_73_511
/// ```
declare_lint! {
    pub INCONSISTENT_DIGIT_GROUPING,
    Warn,
    "integer literals with digits grouped inconsistently"
}

/// **What it does:** Warns if the digits of an integral or floating-point
/// constant are grouped into groups that
/// are too large.
///
/// **Why is this bad?** Negatively impacts readability.
///
/// **Known problems:** None.
///
/// **Example:**
///
/// ```rust
/// 6186491_8973511
/// ```
declare_lint! {
    pub LARGE_DIGIT_GROUPS,
    Warn,
    "grouping digits into groups that are too large"
}

#[derive(Debug)]
enum Radix {
    Binary,
    Octal,
    Decimal,
    Hexadecimal,
}

impl Radix {
    /// Return a reasonable digit group size for this radix.
    pub fn suggest_grouping(&self) -> usize {
        match *self {
            Radix::Binary | Radix::Hexadecimal => 4,
            Radix::Octal | Radix::Decimal => 3,
        }
    }
}

#[derive(Debug)]
struct DigitInfo<'a> {
    /// Characters of a literal between the radix prefix and type suffix.
    pub digits: &'a str,
    /// Which radix the literal was represented in.
    pub radix: Radix,
    /// The radix prefix, if present.
    pub prefix: Option<&'a str>,
    /// The type suffix, including preceding underscore if present.
    pub suffix: Option<&'a str>,
    /// True for floating-point literals.
    pub float: bool,
}

impl<'a> DigitInfo<'a> {
    pub fn new(lit: &str, float: bool) -> DigitInfo {
        // Determine delimiter for radix prefix, if present, and radix.
        let radix = if lit.starts_with("0x") {
            Radix::Hexadecimal
        } else if lit.starts_with("0b") {
            Radix::Binary
        } else if lit.starts_with("0o") {
            Radix::Octal
        } else {
            Radix::Decimal
        };

        // Grab part of the literal after prefix, if present.
        let (prefix, sans_prefix) = if let Radix::Decimal = radix {
            (None, lit)
        } else {
            let (p, s) = lit.split_at(2);
            (Some(p), s)
        };

        let mut last_d = '\0';
        for (d_idx, d) in sans_prefix.char_indices() {
            if !float && (d == 'i' || d == 'u') || float && d == 'f' {
                let suffix_start = if last_d == '_' { d_idx - 1 } else { d_idx };
                let (digits, suffix) = sans_prefix.split_at(suffix_start);
                return DigitInfo {
                    digits: digits,
                    radix: radix,
                    prefix: prefix,
                    suffix: Some(suffix),
                    float: float,
                };
            }
            last_d = d
        }

        // No suffix found
        DigitInfo {
            digits: sans_prefix,
            radix: radix,
            prefix: prefix,
            suffix: None,
            float: float,
        }
    }

    /// Returns digits grouped in a sensible way.
    fn grouping_hint(&self) -> String {
        let group_size = self.radix.suggest_grouping();
        if self.digits.contains('.') {
            let mut parts = self.digits.split(".");
            let int_part_hint = parts
                .next()
                .unwrap()
                .chars()
                .rev()
                .filter(|&c| c != '_')
                .collect::<Vec<_>>()
                .chunks(group_size)
                .map(|chunk| chunk.into_iter().rev().collect())
                .rev()
                .collect::<Vec<String>>()
                .join("_");
            let frac_part_hint = parts
                .next()
                .unwrap()
                .chars()
                .filter(|&c| c != '_')
                .collect::<Vec<_>>()
                .chunks(group_size)
                .map(|chunk| chunk.into_iter().collect())
                .collect::<Vec<String>>()
                .join("_");
            format!("{}.{}{}", int_part_hint, frac_part_hint, self.suffix.unwrap_or(""))
        } else {
            let hint = self.digits
                .chars()
                .rev()
                .filter(|&c| c != '_')
                .collect::<Vec<_>>()
                .chunks(group_size)
                .map(|chunk| chunk.into_iter().rev().collect())
                .rev()
                .collect::<Vec<String>>()
                .join("_");
            format!("{}{}{}", self.prefix.unwrap_or(""), hint, self.suffix.unwrap_or(""))
        }
    }
}

enum WarningType {
    UnreadableLiteral,
    InconsistentDigitGrouping,
    LargeDigitGroups,
}

impl WarningType {
    pub fn display(&self, grouping_hint: &str, cx: &EarlyContext, span: &syntax_pos::Span) {
        match *self {
            WarningType::UnreadableLiteral => {
                span_help_and_lint(
                    cx,
                    UNREADABLE_LITERAL,
                    *span,
                    "long literal lacking separators",
                    &format!("consider: {}", grouping_hint),
                )
            },
            WarningType::LargeDigitGroups => {
                span_help_and_lint(
                    cx,
                    LARGE_DIGIT_GROUPS,
                    *span,
                    "digit groups should be smaller",
                    &format!("consider: {}", grouping_hint),
                )
            },
            WarningType::InconsistentDigitGrouping => {
                span_help_and_lint(
                    cx,
                    INCONSISTENT_DIGIT_GROUPING,
                    *span,
                    "digits grouped inconsistently by underscores",
                    &format!("consider: {}", grouping_hint),
                )
            },
        };
    }
}

#[derive(Copy, Clone)]
pub struct LiteralDigitGrouping;

impl LintPass for LiteralDigitGrouping {
    fn get_lints(&self) -> LintArray {
        lint_array!(UNREADABLE_LITERAL, INCONSISTENT_DIGIT_GROUPING, LARGE_DIGIT_GROUPS)
    }
}

impl EarlyLintPass for LiteralDigitGrouping {
    fn check_expr(&mut self, cx: &EarlyContext, expr: &Expr) {
        if in_external_macro(cx, expr.span) {
            return;
        }

        if let ExprKind::Lit(ref lit) = expr.node {
            self.check_lit(cx, lit)
        }
    }
}

impl LiteralDigitGrouping {
    fn check_lit(&self, cx: &EarlyContext, lit: &Lit) {
        // Lint integral literals.
        if_let_chain! {[
            let LitKind::Int(..) = lit.node,
            let Some(src) = snippet_opt(cx, lit.span),
            let Some(firstch) = src.chars().next(),
            char::to_digit(firstch, 10).is_some()
        ], {
            let digit_info = DigitInfo::new(&src, false);
            let _ = LiteralDigitGrouping::do_lint(digit_info.digits).map_err(|warning_type| {
                warning_type.display(&digit_info.grouping_hint(), cx, &lit.span)
            });
        }}

        // Lint floating-point literals.
        if_let_chain! {[
            let LitKind::Float(..) = lit.node,
            let Some(src) = snippet_opt(cx, lit.span),
            let Some(firstch) = src.chars().next(),
            char::to_digit(firstch, 10).is_some()
        ], {
            let digit_info = DigitInfo::new(&src, true);
            // Separate digits into integral and fractional parts.
            let parts: Vec<&str> = digit_info
                .digits
                .split_terminator('.')
                .collect();

            // Lint integral and fractional parts separately, and then check consistency of digit
            // groups if both pass.
            let _ = LiteralDigitGrouping::do_lint(parts[0])
                .map(|integral_group_size| {
                    if parts.len() > 1 {
                        // Lint the fractional part of literal just like integral part, but reversed.
                        let fractional_part = &parts[1].chars().rev().collect::<String>();
                        let _ = LiteralDigitGrouping::do_lint(fractional_part)
                            .map(|fractional_group_size| {
                                let consistent = LiteralDigitGrouping::parts_consistent(integral_group_size, fractional_group_size, parts[0].len(), parts[1].len());
                                if !consistent {
                                    WarningType::InconsistentDigitGrouping.display(&digit_info.grouping_hint(), cx, &lit.span);
                                }
                            })
                            .map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(), cx, &lit.span));
                    }
                })
                .map_err(|warning_type| warning_type.display(&digit_info.grouping_hint(), cx, &lit.span));
        }}
    }

    /// Given the sizes of the digit groups of both integral and fractional
    /// parts, and the length
    /// of both parts, determine if the digits have been grouped consistently.
    fn parts_consistent(int_group_size: usize, frac_group_size: usize, int_size: usize, frac_size: usize) -> bool {
        match (int_group_size, frac_group_size) {
            // No groups on either side of decimal point - trivially consistent.
            (0, 0) => true,
            // Integral part has grouped digits, fractional part does not.
            (_, 0) => frac_size <= int_group_size,
            // Fractional part has grouped digits, integral part does not.
            (0, _) => int_size <= frac_group_size,
            // Both parts have grouped digits. Groups should be the same size.
            (_, _) => int_group_size == frac_group_size,
        }
    }

    /// Performs lint on `digits` (no decimal point) and returns the group
    /// size on success or `WarningType` when emitting a warning.
    fn do_lint(digits: &str) -> Result<usize, WarningType> {
        // Grab underscore indices with respect to the units digit.
        let underscore_positions: Vec<usize> = digits
            .chars()
            .rev()
            .enumerate()
            .filter_map(|(idx, digit)| if digit == '_' { Some(idx) } else { None })
            .collect();

        if underscore_positions.is_empty() {
            // Check if literal needs underscores.
            if digits.len() > 4 {
                return Err(WarningType::UnreadableLiteral);
            } else {
                return Ok(0);
            }
        } else {
            // Check consistency and the sizes of the groups.
            let group_size = underscore_positions[0];
            let consistent = underscore_positions
                .windows(2)
                .all(|ps| ps[1] - ps[0] == group_size + 1)
                // number of digits to the left of the last group cannot be bigger than group size.
                && (digits.len() - underscore_positions.last().unwrap() <= group_size + 1);

            if !consistent {
                return Err(WarningType::InconsistentDigitGrouping);
            } else if group_size > 4 {
                return Err(WarningType::LargeDigitGroups);
            }
            return Ok(group_size);
        }
    }
}
<|endoftext|>


<commit_before>pub enum Expiration {
    Never,
    TenMinutes,
    OneHour,
    OneDay,
    OneWeek,
    TwoWeeks,
    OneMonth,
}

pub fn get_expiration(expiration: &Expiration) -> &str {
    match expiration {
        &Expiration::Never => "N",
        &Expiration::TenMinutes => "10M",
        &Expiration::OneHour => "1H",
        &Expiration::OneDay => "1D",
        &Expiration::OneWeek => "1W",
        &Expiration::TwoWeeks => "2W",
        &Expiration::OneMonth => "1M",
    }
}
<commit_msg>added missing doc to expiration<commit_after>/// Represents an enum of all possible expiration times.
pub enum Expiration {
    Never,
    TenMinutes,
    OneHour,
    OneDay,
    OneWeek,
    TwoWeeks,
    OneMonth,
}

pub fn get_expiration(expiration: &Expiration) -> &str {
    match expiration {
        &Expiration::Never => "N",
        &Expiration::TenMinutes => "10M",
        &Expiration::OneHour => "1H",
        &Expiration::OneDay => "1D",
        &Expiration::OneWeek => "1W",
        &Expiration::TwoWeeks => "2W",
        &Expiration::OneMonth => "1M",
    }
}
<|endoftext|>


<commit_before>use std::env;
use std::ffi::OsStr;
use std::fs;

use anyhow::Result;
use clap::{Arg, ArgMatches, Command};
use console::style;
use if_chain::if_chain;
use log::info;

use crate::api::{Api, NewRelease};
use crate::config::Config;
use crate::utils::appcenter::{get_appcenter_package, get_react_native_appcenter_release};
use crate::utils::args::ArgExt;
use crate::utils::file_search::ReleaseFileSearch;
use crate::utils::file_upload::UploadContext;
use crate::utils::sourcemaps::SourceMapProcessor;

pub fn make_command(command: Command) -> Command {
    command
        .about("Upload react-native projects for AppCenter.")
        .org_arg()
        .project_arg(false)
        .arg(
            Arg::new("deployment")
                .long("deployment")
                .value_name("DEPLOYMENT")
                .help("The name of the deployment. [Production, Staging]"),
        )
        .arg(
            Arg::new("bundle_id")
                .value_name("BUNDLE_ID")
                .long("bundle-id")
                .help(
                    "Explicitly provide the bundle ID instead of \
                     parsing the source projects.  This allows you to push \
                     codepush releases for iOS on platforms without Xcode or \
                     codepush releases for Android when you use different \
                     bundle IDs for release and debug etc.",
                ),
        )
        .arg(
            Arg::new("version_name")
                .value_name("VERSION_NAME")
                .long("version-name")
                .help("Override version name in release name"),
        )
        .arg(
            Arg::new("dist")
                .long("dist")
                .value_name("DISTRIBUTION")
                .multiple_occurrences(true)
                .help("The names of the distributions to publish. Can be supplied multiple times."),
        )
        .arg(
            Arg::new("print_release_name")
                .long("print-release-name")
                .help("Print the release name instead."),
        )
        .arg(
            Arg::new("release_name")
                .value_name("RELEASE_NAME")
                .long("release-name")
                .conflicts_with_all(&["bundle_id", "version_name"])
                .help("Override the entire release-name"),
        )
        .arg(
            Arg::new("app_name")
                .value_name("APP_NAME")
                .required(true)
                .help("The name of the AppCenter application."),
        )
        .arg(
            Arg::new("platform")
                .value_name("PLATFORM")
                .required(true)
                .help("The name of the app platform. [ios, android]"),
        )
        .arg(
            Arg::new("paths")
                .value_name("PATH")
                .required(true)
                .multiple_occurrences(true)
                .help("A list of folders with assets that should be processed."),
        )
        .arg(
            Arg::new("wait")
                .long("wait")
                .help("Wait for the server to fully process uploaded files."),
        )
}

pub fn execute(matches: &ArgMatches) -> Result<()> {
    let config = Config::current();
    let here = env::current_dir()?;
    let here_str: &str = &here.to_string_lossy();
    let (org, project) = config.get_org_and_project(matches)?;
    let app = matches.value_of("app_name").unwrap();
    let platform = matches.value_of("platform").unwrap();
    let deployment = matches.value_of("deployment").unwrap_or("Staging");
    let api = Api::current();
    let print_release_name = matches.is_present("print_release_name");

    info!(
        "Issuing a command for Organization: {} Project: {}",
        org, project
    );

    if !print_release_name {
        println!(
            "{} Fetching latest AppCenter deployment info",
            style(">").dim()
        );
    }

    let package = get_appcenter_package(app, deployment)?;
    let release = get_react_native_appcenter_release(
        &package,
        platform,
        matches.value_of("bundle_id"),
        matches.value_of("version_name"),
        matches.value_of("release_name"),
    )?;
    if print_release_name {
        println!("{}", release);
        return Ok(());
    }

    println!(
        "{} Processing react-native AppCenter sourcemaps",
        style(">").dim()
    );

    let mut processor = SourceMapProcessor::new();

    for path in matches.values_of("paths").unwrap() {
        for entry in (fs::read_dir(path)?).flatten() {
            if_chain! {
                if let Some(filename) = entry.file_name().to_str();
                if let Some(ext) = entry.path().extension();
                if ext == OsStr::new("jsbundle") ||
                   ext == OsStr::new("map") ||
                   ext == OsStr::new("bundle");
                then {
                    let url = format!("~/{}", filename);
                    processor.add(&url, ReleaseFileSearch::collect_file(entry.path())?)?;
                }
            }
        }
    }

    processor.rewrite(&[here_str])?;
    processor.add_sourcemap_references()?;

    let release = api.new_release(
        &org,
        &NewRelease {
            version: (*release).to_string(),
            projects: vec![project.to_string()],
            ..Default::default()
        },
    )?;

    match matches.values_of("dist") {
        None => {
            println!(
                "Uploading sourcemaps for release {} (no distribution value given; use --dist to set distribution value)",
                &release.version
            );

            processor.upload(&UploadContext {
                org: &org,
                project: Some(&project),
                release: &release.version,
                dist: None,
                wait: matches.is_present("wait"),
            })?;
        }
        Some(dists) => {
            for dist in dists {
                println!(
                    "Uploading sourcemaps for release {} distribution {}",
                    &release.version, dist
                );

                processor.upload(&UploadContext {
                    org: &org,
                    project: Some(&project),
                    release: &release.version,
                    dist: Some(dist),
                    wait: matches.is_present("wait"),
                })?;
            }
        }
    }

    Ok(())
}
<commit_msg>ref: Print better error when processing appcenter paths (#1287)<commit_after>use std::env;
use std::ffi::OsStr;
use std::fs;

use anyhow::{anyhow, Result};
use clap::{Arg, ArgMatches, Command};
use console::style;
use if_chain::if_chain;
use log::info;

use crate::api::{Api, NewRelease};
use crate::config::Config;
use crate::utils::appcenter::{get_appcenter_package, get_react_native_appcenter_release};
use crate::utils::args::ArgExt;
use crate::utils::file_search::ReleaseFileSearch;
use crate::utils::file_upload::UploadContext;
use crate::utils::sourcemaps::SourceMapProcessor;

pub fn make_command(command: Command) -> Command {
    command
        .about("Upload react-native projects for AppCenter.")
        .org_arg()
        .project_arg(false)
        .arg(
            Arg::new("deployment")
                .long("deployment")
                .value_name("DEPLOYMENT")
                .help("The name of the deployment. [Production, Staging]"),
        )
        .arg(
            Arg::new("bundle_id")
                .value_name("BUNDLE_ID")
                .long("bundle-id")
                .help(
                    "Explicitly provide the bundle ID instead of \
                     parsing the source projects.  This allows you to push \
                     codepush releases for iOS on platforms without Xcode or \
                     codepush releases for Android when you use different \
                     bundle IDs for release and debug etc.",
                ),
        )
        .arg(
            Arg::new("version_name")
                .value_name("VERSION_NAME")
                .long("version-name")
                .help("Override version name in release name"),
        )
        .arg(
            Arg::new("dist")
                .long("dist")
                .value_name("DISTRIBUTION")
                .multiple_occurrences(true)
                .help("The names of the distributions to publish. Can be supplied multiple times."),
        )
        .arg(
            Arg::new("print_release_name")
                .long("print-release-name")
                .help("Print the release name instead."),
        )
        .arg(
            Arg::new("release_name")
                .value_name("RELEASE_NAME")
                .long("release-name")
                .conflicts_with_all(&["bundle_id", "version_name"])
                .help("Override the entire release-name"),
        )
        .arg(
            Arg::new("app_name")
                .value_name("APP_NAME")
                .required(true)
                .help("The name of the AppCenter application."),
        )
        .arg(
            Arg::new("platform")
                .value_name("PLATFORM")
                .required(true)
                .help("The name of the app platform. [ios, android]"),
        )
        .arg(
            Arg::new("paths")
                .value_name("PATH")
                .required(true)
                .multiple_occurrences(true)
                .help("A list of folders with assets that should be processed."),
        )
        .arg(
            Arg::new("wait")
                .long("wait")
                .help("Wait for the server to fully process uploaded files."),
        )
}

pub fn execute(matches: &ArgMatches) -> Result<()> {
    let config = Config::current();
    let here = env::current_dir()?;
    let here_str: &str = &here.to_string_lossy();
    let (org, project) = config.get_org_and_project(matches)?;
    let app = matches.value_of("app_name").unwrap();
    let platform = matches.value_of("platform").unwrap();
    let deployment = matches.value_of("deployment").unwrap_or("Staging");
    let api = Api::current();
    let print_release_name = matches.is_present("print_release_name");

    info!(
        "Issuing a command for Organization: {} Project: {}",
        org, project
    );

    if !print_release_name {
        println!(
            "{} Fetching latest AppCenter deployment info",
            style(">").dim()
        );
    }

    let package = get_appcenter_package(app, deployment)?;
    let release = get_react_native_appcenter_release(
        &package,
        platform,
        matches.value_of("bundle_id"),
        matches.value_of("version_name"),
        matches.value_of("release_name"),
    )?;
    if print_release_name {
        println!("{}", release);
        return Ok(());
    }

    println!(
        "{} Processing react-native AppCenter sourcemaps",
        style(">").dim()
    );

    let mut processor = SourceMapProcessor::new();

    for path in matches.values_of("paths").unwrap() {
        let entries = fs::read_dir(path)
            .map_err(|e| anyhow!(e).context(format!("Failed processing path: \"{}\"", &path)))?;

        for entry in entries.flatten() {
            if_chain! {
                if let Some(filename) = entry.file_name().to_str();
                if let Some(ext) = entry.path().extension();
                if ext == OsStr::new("jsbundle") ||
                   ext == OsStr::new("map") ||
                   ext == OsStr::new("bundle");
                then {
                    let url = format!("~/{}", filename);
                    processor.add(&url, ReleaseFileSearch::collect_file(entry.path())?)?;
                }
            }
        }
    }

    processor.rewrite(&[here_str])?;
    processor.add_sourcemap_references()?;

    let release = api.new_release(
        &org,
        &NewRelease {
            version: (*release).to_string(),
            projects: vec![project.to_string()],
            ..Default::default()
        },
    )?;

    match matches.values_of("dist") {
        None => {
            println!(
                "Uploading sourcemaps for release {} (no distribution value given; use --dist to set distribution value)",
                &release.version
            );

            processor.upload(&UploadContext {
                org: &org,
                project: Some(&project),
                release: &release.version,
                dist: None,
                wait: matches.is_present("wait"),
            })?;
        }
        Some(dists) => {
            for dist in dists {
                println!(
                    "Uploading sourcemaps for release {} distribution {}",
                    &release.version, dist
                );

                processor.upload(&UploadContext {
                    org: &org,
                    project: Some(&project),
                    release: &release.version,
                    dist: Some(dist),
                    wait: matches.is_present("wait"),
                })?;
            }
        }
    }

    Ok(())
}
<|endoftext|>


<commit_before>
use {Field, Borrowed, Value};
use vecmath::{rotate_radians, multiply, translate, scale, shear};
use {Transform2d, Matrix2d, Rectangle, Color};
use {Fill, BackEnd};
use triangulation::{rect_tri_list_xy_f32, rect_tri_list_rgba_f32};

/// A rectangle color context.
pub struct RectangleColorContext<'a> {
    /// Base/original transformation.
    pub base: Field<'a, Matrix2d>,
    /// Current transformation.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
    /// Current color.
    pub color: Field<'a, Color>,
}

impl<'a> Transform2d<'a> for RectangleColorContext<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> RectangleColorContext<'a> {
        RectangleColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(&trans, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> RectangleColorContext<'a> {
        RectangleColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(&rot, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> RectangleColorContext<'a> {
        RectangleColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(&scale, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> RectangleColorContext<'a> {
        RectangleColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(&shear, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> Fill<'a> for RectangleColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_rgba_f32() {
            let rect = self.rect.get();
            let rect: [f32, ..4] = [rect[0] as f32, rect[1] as f32, rect[2] as f32, rect[3] as f32];
            let color = self.color.get();
            let color: [f32, ..4] = [color[0] as f32, color[1] as f32, color[2] as f32, color[3] as f32];
            back_end.tri_list_xy_rgba_f32(
                rect_tri_list_xy_f32(rect),
                rect_tri_list_rgba_f32(color)
            );
            return;
        }

        unimplemented!();
    }
}

<commit_msg>Add clear for RectangleColorContext<commit_after>
use {Field, Borrowed, Value};
use vecmath::{rotate_radians, multiply, translate, scale, shear};
use {Transform2d, Matrix2d, Rectangle, Color};
use {Fill, Clear, BackEnd};
use triangulation::{rect_tri_list_xy_f32, rect_tri_list_rgba_f32};

/// A rectangle color context.
pub struct RectangleColorContext<'a> {
    /// Base/original transformation.
    pub base: Field<'a, Matrix2d>,
    /// Current transformation.
    pub transform: Field<'a, Matrix2d>,
    /// Current rectangle.
    pub rect: Field<'a, Rectangle>,
    /// Current color.
    pub color: Field<'a, Color>,
}

impl<'a> Transform2d<'a> for RectangleColorContext<'a> {
    #[inline(always)]
    fn trans(&'a self, x: f64, y: f64) -> RectangleColorContext<'a> {
        RectangleColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let trans = translate(x, y);
                Value(multiply(&trans, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn rot_rad(&'a self, angle: f64) -> RectangleColorContext<'a> {
        RectangleColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let rot = rotate_radians(angle);
                Value(multiply(&rot, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn scale(&'a self, sx: f64, sy: f64) -> RectangleColorContext<'a> {
        RectangleColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let scale = scale(sx, sy);
                Value(multiply(&scale, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            color: Borrowed(self.color.get()),
        }
    }

    #[inline(always)]
    fn shear(&'a self, sx: f64, sy: f64) -> RectangleColorContext<'a> {
        RectangleColorContext {
            base: Borrowed(self.base.get()),
            transform: {
                let shear = shear(sx, sy);
                Value(multiply(&shear, self.transform.get()))
            },
            rect: Borrowed(self.rect.get()),
            color: Borrowed(self.color.get()),
        }
    }
}

impl<'a> Fill<'a> for RectangleColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_rgba_f32() {
            let rect = self.rect.get();
            let rect: [f32, ..4] = [rect[0] as f32, rect[1] as f32, rect[2] as f32, rect[3] as f32];
            let color = self.color.get();
            let color: [f32, ..4] = [color[0] as f32, color[1] as f32, color[2] as f32, color[3] as f32];
            back_end.tri_list_xy_rgba_f32(
                rect_tri_list_xy_f32(rect),
                rect_tri_list_rgba_f32(color)
            );
            return;
        }

        unimplemented!();
    }
}

impl<'a> Clear for RectangleColorContext<'a> {
    fn clear<B: BackEnd>(&self, back_end: &mut B) {
        if back_end.supports_clear_rgba() {
            let color = self.color.get();
            back_end.clear_rgba(color[0], color[1], color[2], color[3]);
        } else {
            unimplemented!();
        }
    }
}
<|endoftext|>


<commit_before>/// # Plans
/// Current this uses raw bit operations to provide a packed representation
/// with an interface similar to [Option<T>; N]. Once integer generics land,
/// it can instead use an abstraction layer to provide operations. Hopefully
/// that can be maintained as a separate crate.

use std::marker::PhantomData;
use std::mem;
use std::ptr;
use super::traits::JpmNode;
use super::innerptr::InnerPtr;
use ::rudymap::results::{InsertResult, RemoveResult};
use ::Key;
use nodrop::NoDrop;

pub struct LeafBitmap<K: Key, V> {
    keys: [u8; 256 / 8],
    values: NoDrop<[V; 256]>,
    pd: PhantomData<K>
}

impl<K: Key, V> LeafBitmap<K, V> {
    pub fn new() -> LeafBitmap<K, V> {
        LeafBitmap {
            keys: [0; 256 / 8],
            values: unsafe { mem::zeroed() },
            pd: PhantomData
        }
    }
}

#[derive(Debug)]
enum Place {
    Occupied(usize),
    Empty(usize)
}

fn singleton_index(key: &[u8], keys: &[u8; 256 / 8]) -> Place {
    debug_assert_eq!(key.len(), 1);
    let index = key[0] as usize;
    let occupied = keys[index / 8] & (1 << (index % 8));
    if occupied != 0 {
        Place::Occupied(index)
    } else {
        Place::Empty(index)
    }
}

impl<K: Key, V> JpmNode<K, V> for LeafBitmap<K, V> {
    fn get(&self, key: &[u8]) -> Option<&V> {
        match singleton_index(key, &self.keys) {
            Place::Occupied(index) => Some(&self.values[index]),
            Place::Empty(index) => None
        }
    }

    fn get_mut(&mut self, key: &[u8]) -> Option<&mut V> {
        match singleton_index(key, &self.keys) {
            Place::Occupied(index) => Some(&mut self.values[index]),
            Place::Empty(index) => None
        }
    }

    fn insert(&mut self, key: &[u8], value: V) -> InsertResult<V> {
        match singleton_index(key, &self.keys) {
            Place::Occupied(index) => {
                let place = &mut self.values[index];
                InsertResult::replace(place, value)
            },
            Place::Empty(index) => {
                let place = &mut self.values[index];
                self.keys[index / 8] |= 1 << (index % 8);
                unsafe {
                    ptr::write(place, value);
                }
                InsertResult::Success(None)
            }
        }
    }

    fn expand(self, pop: usize, key: &[u8], value: V) -> InnerPtr<K, V> {
        unreachable!();
    }

    fn remove(&mut self, key: &[u8]) -> RemoveResult<V> {
        match singleton_index(key, &self.keys) {
            Place::Occupied(index) => {
                let place = &mut self.values[index];
                let value = unsafe { ptr::read(place) };
                self.keys[index / 8] &= !(1 << (index % 8));
                RemoveResult::Success(Some(value))
            },
            Place::Empty(_) => {
                RemoveResult::Success(None)
            }
        }
    }

    fn shrink_remove(self, pop: usize, key: &[u8]) -> (InnerPtr<K, V>, V) {
        unreachable!()
    }
}
<commit_msg>Implement Drop on LeafBitmap<commit_after>/// # Plans
/// Current this uses raw bit operations to provide a packed representation
/// with an interface similar to [Option<T>; N]. Once integer generics land,
/// it can instead use an abstraction layer to provide operations. Hopefully
/// that can be maintained as a separate crate.

use std::marker::PhantomData;
use std::mem;
use std::ptr;
use super::traits::JpmNode;
use super::innerptr::InnerPtr;
use ::rudymap::results::{InsertResult, RemoveResult};
use ::Key;
use nodrop::NoDrop;

pub struct LeafBitmap<K: Key, V> {
    keys: [u8; 256 / 8],
    values: NoDrop<[V; 256]>,
    pd: PhantomData<K>
}

impl<K: Key, V> LeafBitmap<K, V> {
    pub fn new() -> LeafBitmap<K, V> {
        LeafBitmap {
            keys: [0; 256 / 8],
            values: unsafe { mem::zeroed() },
            pd: PhantomData
        }
    }
}

impl<K: Key, V> Drop for LeafBitmap<K, V> {
    fn drop(&mut self) {
        for index in 0..256 {
            let key: [u8; 1] = [index as u8];
            self.remove(&key).success();
        }
    }
}

#[derive(Debug)]
enum Place {
    Occupied(usize),
    Empty(usize)
}

fn singleton_index(key: &[u8], keys: &[u8; 256 / 8]) -> Place {
    debug_assert_eq!(key.len(), 1);
    let index = key[0] as usize;
    let occupied = keys[index / 8] & (1 << (index % 8));
    if occupied != 0 {
        Place::Occupied(index)
    } else {
        Place::Empty(index)
    }
}

impl<K: Key, V> JpmNode<K, V> for LeafBitmap<K, V> {
    fn get(&self, key: &[u8]) -> Option<&V> {
        match singleton_index(key, &self.keys) {
            Place::Occupied(index) => Some(&self.values[index]),
            Place::Empty(index) => None
        }
    }

    fn get_mut(&mut self, key: &[u8]) -> Option<&mut V> {
        match singleton_index(key, &self.keys) {
            Place::Occupied(index) => Some(&mut self.values[index]),
            Place::Empty(index) => None
        }
    }

    fn insert(&mut self, key: &[u8], value: V) -> InsertResult<V> {
        match singleton_index(key, &self.keys) {
            Place::Occupied(index) => {
                let place = &mut self.values[index];
                InsertResult::replace(place, value)
            },
            Place::Empty(index) => {
                let place = &mut self.values[index];
                self.keys[index / 8] |= 1 << (index % 8);
                unsafe {
                    ptr::write(place, value);
                }
                InsertResult::Success(None)
            }
        }
    }

    fn expand(self, pop: usize, key: &[u8], value: V) -> InnerPtr<K, V> {
        unreachable!();
    }

    fn remove(&mut self, key: &[u8]) -> RemoveResult<V> {
        match singleton_index(key, &self.keys) {
            Place::Occupied(index) => {
                let place = &mut self.values[index];
                let value = unsafe { ptr::read(place) };
                self.keys[index / 8] &= !(1 << (index % 8));
                RemoveResult::Success(Some(value))
            },
            Place::Empty(_) => {
                RemoveResult::Success(None)
            }
        }
    }

    fn shrink_remove(self, pop: usize, key: &[u8]) -> (InnerPtr<K, V>, V) {
        unreachable!()
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use std::sync::atomic::{AtomicUsize,Ordering};

    struct Droppable<'a>(&'a AtomicUsize);
    impl<'a> Drop for Droppable<'a> {
        fn drop(&mut self) {
            self.0.fetch_add(1, Ordering::AcqRel);
        }
    }

    #[test]
    fn test_drop() {
        let drop_count = AtomicUsize::new(0);

        {
            // insert a single key
            let mut lb: LeafBitmap<u32, Droppable> = LeafBitmap::new();
            lb.insert(&[0], Droppable(&drop_count)).success();

            // inserting into an empty map should cause no drops
            assert_eq!(drop_count.load(Ordering::Acquire), 0);

            // overwriting the key should drop the old key
            lb.insert(&[0], Droppable(&drop_count)).success();
            assert_eq!(drop_count.load(Ordering::Acquire), 1);
        }

        // dropping the LeafBitmap should drop its only value
        assert_eq!(drop_count.load(Ordering::Acquire), 2);

        // reset the counter
        drop_count.store(0, Ordering::Release);

        {
            let mut lb: LeafBitmap<u32, Droppable> = LeafBitmap::new();
            for i in 0..256 {
                lb.insert(&[i as u8], Droppable(&drop_count)).success();
            }

            // inserting a full bitmap should cause no drops
            assert_eq!(drop_count.load(Ordering::Acquire), 0);

            // getting/get_muting should cause no drops
            lb.get(&[1]);
            lb.get_mut(&[2]);
            assert_eq!(drop_count.load(Ordering::Acquire), 0);

            // removing one key should cause one drop
            lb.remove(&[42]).success();
            assert_eq!(drop_count.load(Ordering::Acquire), 1);
        }

        // discarding the LeafBitmap should drop the others
        assert_eq!(drop_count.load(Ordering::Acquire), 256);
    }
}<|endoftext|>


<commit_before>pub trait Pattern: ToString {
  fn precedence(&self) -> uint;

  fn bracket(&self, outer_precedence: uint) -> String {
    if self.precedence() < outer_precedence {
      format!("({})", self.to_string())
    } else {
      self.to_string()
    }
  }

  fn inspect(&self) -> String {
    format!("/{}/", self.to_string())
  }
}

#[deriving(Show)]
pub struct Empty;

impl Empty {
  // override the ToString
  fn to_string(&self) -> String {
    "".to_string()
  }
}

impl Pattern for Empty {
  fn precedence(&self) -> uint { 3 }
}

#[deriving(Show)]
pub struct Literal {
  pub character: char
}

impl Literal {
  fn to_string(&self) -> String {
    String::from_char(1, self.character)
  }
}

impl Pattern for Literal {
  fn precedence(&self) -> uint { 3 }
}

#[cfg(test)]
mod test {
  use super::Pattern;
  use super::Empty;
  use super::Literal;

  #[test]
  fn test_empty() {
    assert_eq!(Empty.precedence(), 3);
    assert_eq!(Empty.to_string().as_slice(), "");
  }

  #[test]
  fn test_literal() {
    let literal = Literal { character: 'a' };

    assert_eq!(literal.precedence(), 3);
    assert_eq!(literal.to_string().as_slice(), "a");
  }
}
<commit_msg>use Show instead of ToString, and add Concatenate<commit_after>use std::fmt;
use std::fmt::Show;

pub trait Pattern: Show {
  fn precedence(&self) -> uint;

  fn bracket(&self, outer_precedence: uint) -> String {
    if self.precedence() < outer_precedence {
      format!("({})", self)
    } else {
      format!("{}", self)
    }
  }

  fn inspect(&self) -> String {
    format!("/{}/", self)
  }
}

pub struct Empty;

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

impl Pattern for Empty {
  fn precedence(&self) -> uint { 3 }
}

pub struct Literal {
  pub character: char
}

impl Show for Literal {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    self.character.fmt(f)
  }
}

impl Pattern for Literal {
  fn precedence(&self) -> uint { 3 }
}

/// Concatenate node
pub struct Concatenate<S, T> {
  pub first: S,
  pub second: T
}

/// implement Show trait for Concatenate
impl<S: Show, T: Show> Show for Concatenate<S, T> {
  fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
    write!(f, "{}|{}", self.first, self.second)
  }
}

impl<S, T> Pattern for Concatenate<S, T>
  where S: Show + Pattern, T: Show + Pattern {
  fn precedence(&self) -> uint { 1 }
}

#[cfg(test)]
mod test {
  use super::Pattern;
  use super::Empty;
  use super::Literal;
  use super::Concatenate;

  #[test]
  fn test_empty() {
    assert_eq!(Empty.precedence(), 3);
    assert_eq!(Empty.to_string().as_slice(), "");
  }

  #[test]
  fn test_literal() {
    let literal = Literal { character: 'a' };

    assert_eq!(literal.precedence(), 3);
    assert_eq!(literal.to_string().as_slice(), "a");
  }

  #[test]
  fn test_concatenate() {
    let literal = Literal { character: 'a' };
    let concat = Concatenate { first: Empty, second: literal };

    assert_eq!(concat.precedence(), 1);
    assert_eq!(concat.to_string().as_slice(), "|a");
  }
}
<|endoftext|>


<commit_before>#[doc = "Records the full path to items"];

export mk_pass;

fn mk_pass() -> pass { run }

type ctxt = {
    srv: astsrv::srv,
    mutable path: [str]
};

fn run(srv: astsrv::srv, doc: doc::cratedoc) -> doc::cratedoc {
    let ctxt = {
        srv: srv,
        mutable path: []
    };
    let fold = fold::fold({
        fold_item: fold_item,
        fold_mod: fold_mod
        with *fold::default_seq_fold(ctxt)
    });
    fold.fold_crate(fold, doc)
}

fn fold_item(fold: fold::fold<ctxt>, doc: doc::itemdoc) -> doc::itemdoc {
    {
        path: fold.ctxt.path
        with doc
    }
}

fn fold_mod(fold: fold::fold<ctxt>, doc: doc::moddoc) -> doc::moddoc {
    let is_topmod = doc.id() == rustc::syntax::ast::crate_node_id;

    if !is_topmod { vec::push(fold.ctxt.path, doc.name()); }
    let doc = fold::default_seq_fold_mod(fold, doc);
    if !is_topmod { vec::pop(fold.ctxt.path); }

    {
        item: fold.fold_item(fold, doc.item)
        with doc
    }
}

#[test]
fn should_record_mod_paths() {
    let source = "mod a { mod b { mod c { } } mod d { mod e { } } }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = run(srv, doc);
    log(error, doc.topmod.mods()[0].mods()[0].mods()[0].path());
    assert doc.topmod.mods()[0].mods()[0].mods()[0].path() == ["a", "b"];
    assert doc.topmod.mods()[0].mods()[1].mods()[0].path() == ["a", "d"];
}

#[test]
fn should_record_fn_paths() {
    let source = "mod a { fn b() { } }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = run(srv, doc);
    assert doc.topmod.mods()[0].fns()[0].path() == ["a"];
}<commit_msg>rustdoc: Remove stray log<commit_after>#[doc = "Records the full path to items"];

export mk_pass;

fn mk_pass() -> pass { run }

type ctxt = {
    srv: astsrv::srv,
    mutable path: [str]
};

fn run(srv: astsrv::srv, doc: doc::cratedoc) -> doc::cratedoc {
    let ctxt = {
        srv: srv,
        mutable path: []
    };
    let fold = fold::fold({
        fold_item: fold_item,
        fold_mod: fold_mod
        with *fold::default_seq_fold(ctxt)
    });
    fold.fold_crate(fold, doc)
}

fn fold_item(fold: fold::fold<ctxt>, doc: doc::itemdoc) -> doc::itemdoc {
    {
        path: fold.ctxt.path
        with doc
    }
}

fn fold_mod(fold: fold::fold<ctxt>, doc: doc::moddoc) -> doc::moddoc {
    let is_topmod = doc.id() == rustc::syntax::ast::crate_node_id;

    if !is_topmod { vec::push(fold.ctxt.path, doc.name()); }
    let doc = fold::default_seq_fold_mod(fold, doc);
    if !is_topmod { vec::pop(fold.ctxt.path); }

    {
        item: fold.fold_item(fold, doc.item)
        with doc
    }
}

#[test]
fn should_record_mod_paths() {
    let source = "mod a { mod b { mod c { } } mod d { mod e { } } }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = run(srv, doc);
    assert doc.topmod.mods()[0].mods()[0].mods()[0].path() == ["a", "b"];
    assert doc.topmod.mods()[0].mods()[1].mods()[0].path() == ["a", "d"];
}

#[test]
fn should_record_fn_paths() {
    let source = "mod a { fn b() { } }";
    let srv = astsrv::mk_srv_from_str(source);
    let doc = extract::from_srv(srv, "");
    let doc = run(srv, doc);
    assert doc.topmod.mods()[0].fns()[0].path() == ["a"];
}<|endoftext|>