<commit_before>use ffi::*;

use pipeline::Pipeline;
use pipeline::PipelineT;
use element::Element;
use element::ElementT;
use std::ffi::CString;
use ::Transfer;

unsafe impl Sync for PlayBin {}
unsafe impl Send for PlayBin {}

pub struct PlayBin{
    playbin: Pipeline
}

impl PlayBin{
    pub fn new(name: &str) -> Option<PlayBin>{
        let pipeline = Element::new("playbin",name);
        match pipeline{
            Some(p) => {
                match unsafe{ Pipeline::new_from_gst_pipeline( p.transfer() as *mut GstPipeline) }{
                    Some(p) => Some(PlayBin{ playbin: p }),
                    None => None
                }
            }
            None => None
        }
    }

    pub fn set_audio_sink(&self, audio_sink: &ElementT){
        self.set("audio-sink", unsafe{ audio_sink.gst_element() });
    }

    /*pub fn frame(&self) -> GBuffer{
        GBuffer::new(playbin.get<GstBuffer*>("frame"))
    }*/

    pub fn set_subtitle_font_desc(&self, font: &str){
        let cfont = CString::new(font).unwrap();
        self.set("subtitle-font-desc", cfont);
    }

    pub fn set_video_sink(&self, video_sink: &ElementT){
        self.set("video-sink", unsafe{ video_sink.gst_element() });
    }

    pub fn set_vis_plugin(&self, vis_plugin: &ElementT){
        self.set("vis-plugin", vis_plugin);
    }

    pub fn set_volume(&self, volume: f64){
        self.set("volume", volume);
    }

    pub fn set_connection_speed(&self, connection_speed: u64){
        self.set("connection-speed",connection_speed);
    }

    pub fn set_av_offset(&self, av_offset: i64){
        self.set("av-offset", av_offset);
    }

    pub fn set_buffer_duration(&self, buffer_duration: i64){
        self.set("buffer-duration",buffer_duration);
    }

    pub fn set_current_audio(&self, current_audio: i32){
        self.set("current-audio",current_audio);
    }

    pub fn set_current_text(&self, current_text: i32){
        self.set("current-text", current_text);
    }

    /*pub fn set_flags(&self, flags: GstPlayFlags){
        self.set("flags", flags);
    }*/

    pub fn mute(&self){
        self.set("mute", 1 as gboolean);
    }

    pub fn unmute(&self){
        self.set("mute", 0 as gboolean);
    }

    pub fn set_ring_buffer_max_size(&self, ring_buffer_max_size: u64){
        self.set("ring-buffer-max-size", ring_buffer_max_size);
    }

    pub fn set_source(&self, source: &ElementT){
        self.set("source", unsafe{ source.gst_element() });
    }

    pub fn set_subtitle_encoding(&self, encoding: &str){
        let cencoding = CString::new(encoding).unwrap();
        self.set("subtitle-encoding", cencoding);
    }

    pub fn set_suburi(&self, suburi: &str){
        let csuburi = CString::new(suburi).unwrap();
        self.set("suburi", csuburi);
    }

    pub fn set_text_sink(&self, textsink: &ElementT){
        self.set("text-sink", unsafe{ textsink.gst_element() });
    }

    pub fn set_uri(&self, uri: &str){
        let curi = CString::new(uri).unwrap();
        self.set("uri", curi);
    }

    pub fn set_force_aspect_ratio(&self, force_aspect_ratio: bool){
        self.set("force-aspect-ratio", force_aspect_ratio as gboolean);
    }

    pub fn set_audio_stream_combiner(&self, audio_stream_combiner: &ElementT){
        self.set("audio-stream-combiner", unsafe{ audio_stream_combiner.gst_element() });
    }

    pub fn set_video_stream_combiner(&self, video_stream_combiner: &ElementT){
        self.set("vide-stream-combiner", unsafe{ video_stream_combiner.gst_element() });
    }

    pub fn set_flags(&self, flags: i32){
        self.set("flags", flags);
    }
}

impl PipelineT for PlayBin{
    fn as_pipeline(&self) -> &Pipeline{
        &self.playbin
    }

    fn as_pipeline_mut(&mut self) -> &mut Pipeline{
        &mut self.playbin
    }
}

impl ::Transfer for PlayBin{
    unsafe fn transfer(self) -> *mut GstElement{
        self.playbin.transfer()
    }
}
<commit_msg>playbin: use as_ptr for c strings<commit_after>use ffi::*;

use pipeline::Pipeline;
use pipeline::PipelineT;
use element::Element;
use element::ElementT;
use std::ffi::CString;
use ::Transfer;

unsafe impl Sync for PlayBin {}
unsafe impl Send for PlayBin {}

pub struct PlayBin{
    playbin: Pipeline
}

impl PlayBin{
    pub fn new(name: &str) -> Option<PlayBin>{
        let pipeline = Element::new("playbin",name);
        match pipeline{
            Some(p) => {
                match unsafe{ Pipeline::new_from_gst_pipeline( p.transfer() as *mut GstPipeline) }{
                    Some(p) => Some(PlayBin{ playbin: p }),
                    None => None
                }
            }
            None => None
        }
    }

    pub fn set_audio_sink(&self, audio_sink: &ElementT){
        self.set("audio-sink", unsafe{ audio_sink.gst_element() });
    }

    /*pub fn frame(&self) -> GBuffer{
        GBuffer::new(playbin.get<GstBuffer*>("frame"))
    }*/

    pub fn set_subtitle_font_desc(&self, font: &str){
        let cfont = CString::new(font).unwrap();
        self.set("subtitle-font-desc", cfont.as_ptr());
    }

    pub fn set_video_sink(&self, video_sink: &ElementT){
        self.set("video-sink", unsafe{ video_sink.gst_element() });
    }

    pub fn set_vis_plugin(&self, vis_plugin: &ElementT){
        self.set("vis-plugin", vis_plugin);
    }

    pub fn set_volume(&self, volume: f64){
        self.set("volume", volume);
    }

    pub fn set_connection_speed(&self, connection_speed: u64){
        self.set("connection-speed",connection_speed);
    }

    pub fn set_av_offset(&self, av_offset: i64){
        self.set("av-offset", av_offset);
    }

    pub fn set_buffer_duration(&self, buffer_duration: i64){
        self.set("buffer-duration",buffer_duration);
    }

    pub fn set_current_audio(&self, current_audio: i32){
        self.set("current-audio",current_audio);
    }

    pub fn set_current_text(&self, current_text: i32){
        self.set("current-text", current_text);
    }

    /*pub fn set_flags(&self, flags: GstPlayFlags){
        self.set("flags", flags);
    }*/

    pub fn mute(&self){
        self.set("mute", 1 as gboolean);
    }

    pub fn unmute(&self){
        self.set("mute", 0 as gboolean);
    }

    pub fn set_ring_buffer_max_size(&self, ring_buffer_max_size: u64){
        self.set("ring-buffer-max-size", ring_buffer_max_size);
    }

    pub fn set_source(&self, source: &ElementT){
        self.set("source", unsafe{ source.gst_element() });
    }

    pub fn set_subtitle_encoding(&self, encoding: &str){
        let cencoding = CString::new(encoding).unwrap();
        self.set("subtitle-encoding", cencoding.as_ptr());
    }

    pub fn set_suburi(&self, suburi: &str){
        let csuburi = CString::new(suburi).unwrap();
        self.set("suburi", csuburi.as_ptr());
    }

    pub fn set_text_sink(&self, textsink: &ElementT){
        self.set("text-sink", unsafe{ textsink.gst_element() });
    }

    pub fn set_uri(&self, uri: &str){
        let curi = CString::new(uri).unwrap();
        self.set("uri", curi.as_ptr());
    }

    pub fn set_force_aspect_ratio(&self, force_aspect_ratio: bool){
        self.set("force-aspect-ratio", force_aspect_ratio as gboolean);
    }

    pub fn set_audio_stream_combiner(&self, audio_stream_combiner: &ElementT){
        self.set("audio-stream-combiner", unsafe{ audio_stream_combiner.gst_element() });
    }

    pub fn set_video_stream_combiner(&self, video_stream_combiner: &ElementT){
        self.set("vide-stream-combiner", unsafe{ video_stream_combiner.gst_element() });
    }

    pub fn set_flags(&self, flags: i32){
        self.set("flags", flags);
    }
}

impl PipelineT for PlayBin{
    fn as_pipeline(&self) -> &Pipeline{
        &self.playbin
    }

    fn as_pipeline_mut(&mut self) -> &mut Pipeline{
        &mut self.playbin
    }
}

impl ::Transfer for PlayBin{
    unsafe fn transfer(self) -> *mut GstElement{
        self.playbin.transfer()
    }
}
<|endoftext|>


<commit_before>use internal::prelude::*;
use serde::de::{
    self,
    Deserialize,
    Deserializer,
    MapAccess,
    Visitor
};
use serde::ser::{
    Serialize,
    Serializer
};
use super::super::prelude::*;
use std::{
    collections::HashMap,
    mem::transmute,
    fmt
};

/// Determines to what entity an action was used on.
#[derive(Debug)]
#[repr(u8)]
pub enum Target {
    Guild = 10,
    Channel = 20,
    User = 30,
    Role = 40,
    Invite = 50,
    Webhook = 60,
    Emoji = 70,
}

/// Determines the action that was done on a target.
#[derive(Debug)]
pub enum Action {
    GuildUpdate,
    Channel(ActionChannel),
    ChannelOverwrite(ActionChannelOverwrite),
    Member(ActionMember),
    Role(ActionRole),
    Invite(ActionInvite),
    Webhook(ActionWebhook),
    Emoji(ActionEmoji),
    MessageDelete,
}

impl Action {
    pub fn num(&self) -> u8 {
        use self::Action::*;

        match *self {
            GuildUpdate => 1,
            Action::Channel(ref x) => x.num(),
            Action::ChannelOverwrite(ref x) => x.num(),
            Action::Member(ref x) => x.num(),
            Action::Role(ref x) => x.num(),
            Action::Invite(ref x) => x.num(),
            Action::Webhook(ref x) => x.num(),
            Action::Emoji(ref x) => x.num(),
            Action::MessageDelete => 72,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionChannel {
    Create = 10,
    Update = 11,
    Delete = 12,
}

impl ActionChannel {
    pub fn num(&self) -> u8 {
        match *self {
            ActionChannel::Create => 10,
            ActionChannel::Update => 11,
            ActionChannel::Delete => 12,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionChannelOverwrite {
    Create = 13,
    Update = 14,
    Delete = 15,
}

impl ActionChannelOverwrite {
    pub fn num(&self) -> u8 {
        match *self {
            ActionChannelOverwrite::Create => 13,
            ActionChannelOverwrite::Update => 14,
            ActionChannelOverwrite::Delete => 15,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionMember {
    Kick = 20,
    Prune = 21,
    BanAdd = 22,
    BanRemove = 23,
    Update = 24,
    RoleUpdate = 25,
}

impl ActionMember {
    pub fn num(&self) -> u8 {
        match *self {
            ActionMember::Kick => 20,
            ActionMember::Prune => 21,
            ActionMember::BanAdd => 22,
            ActionMember::BanRemove => 23,
            ActionMember::Update => 24,
            ActionMember::RoleUpdate => 25,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionRole {
    Create = 30,
    Update = 31,
    Delete = 32,
}

impl ActionRole {
    pub fn num(&self) -> u8 {
        match *self {
            ActionRole::Create => 30,
            ActionRole::Update => 31,
            ActionRole::Delete => 32,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionInvite {
    Create = 40,
    Update = 41,
    Delete = 42,
}

impl ActionInvite {
    pub fn num(&self) -> u8 {
        match *self {
            ActionInvite::Create => 40,
            ActionInvite::Update => 41,
            ActionInvite::Delete => 42,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionWebhook {
    Create = 50,
    Update = 51,
    Delete = 52,
}

impl ActionWebhook {
    pub fn num(&self) -> u8 {
        match *self {
            ActionWebhook::Create => 50,
            ActionWebhook::Update => 51,
            ActionWebhook::Delete => 52,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionEmoji {
    Create = 60,
    Delete = 61,
    Update = 62,
}

impl ActionEmoji {
    pub fn num(&self) -> u8 {
        match *self {
            ActionEmoji::Create => 60,
            ActionEmoji::Update => 61,
            ActionEmoji::Delete => 62,
        }
    }
}

#[derive(Debug, Deserialize, Serialize)]
pub struct Change {
    #[serde(rename = "key")] pub name: String,
    // TODO: Change these to an actual type.
    #[serde(rename = "old_value")] pub old: String,
    #[serde(rename = "new_value")] pub new: String,
}

#[derive(Debug)]
pub struct AuditLogs {
    pub entries: HashMap<AuditLogEntryId, AuditLogEntry>,
    pub webhooks: Vec<Webhook>,
    pub users: Vec<User>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct AuditLogEntry {
    /// Determines to what entity an [`action`] was used on.
    ///
    /// [`action`]: #structfield.action
    #[serde(with = "u64_handler")]
    pub target_id: u64,
    /// Determines what action was done on a [`target`]
    ///
    /// [`target`]: #structfield.target
    #[serde(
        with = "action_handler",
        rename = "action_type"
    )]
    pub action: Action,
    /// What was the reasoning by doing an action on a target? If there was one.
    pub reason: Option<String>,
    /// The user that did this action on a target.
    pub user_id: UserId,
    /// What changes were made.
    pub changes: Option<Vec<Change>>,
    /// The id of this entry.
    pub id: AuditLogEntryId,
    /// Some optional data assosiated with this entry.
    pub options: Option<Options>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct Options {
    /// Number of days after which inactive members were kicked.
    #[serde(default, with = "option_u64_handler")]
    pub delete_member_days: Option<u64>,
    /// Number of members removed by the prune
    #[serde(default, with = "option_u64_handler")]
    pub members_removed: Option<u64>,
    /// Channel in which the messages were deleted
    #[serde(default)]
    pub channel_id: Option<ChannelId>,
    /// Number of deleted messages.
    #[serde(default, with = "option_u64_handler")]
    pub count: Option<u64>,
    /// Id of the overwritten entity
    #[serde(default, with = "option_u64_handler")]
    pub id: Option<u64>,
    /// Type of overwritten entity ("member" or "role").
    #[serde(default, rename = "type")]
    pub kind: Option<String>,
    /// Name of the role if type is "role"
    #[serde(default)]
    pub role_name: Option<String>,
}

mod u64_handler {
    use super::*;

    pub fn deserialize<'de, D: Deserializer<'de>>(des: D) -> StdResult<u64, D::Error> {
        struct U64Visitor;

        impl<'de> Visitor<'de> for U64Visitor {
            type Value = u64;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("an integer or a string with a valid number inside")
            }

            // NOTE: Serde internally delegates number types below `u64` to it.
            fn visit_u64<E: de::Error>(self, val: u64) -> StdResult<u64, E> {
                Ok(val)
            }

            fn visit_str<E: de::Error>(self, string: &str) -> StdResult<u64, E> {
                string.parse().map_err(|e| de::Error::custom(e))
            }
        }

        des.deserialize_any(U64Visitor)
    }

    pub fn serialize<S: Serializer>(num: &u64, s: S) -> StdResult<S::Ok, S::Error> {
        s.serialize_u64(*num)
    }
}

mod option_u64_handler {
    use super::*;

    pub fn deserialize<'de, D: Deserializer<'de>>(des: D) -> StdResult<Option<u64>, D::Error> {
        struct OptionU64Visitor;

        impl<'de> Visitor<'de> for OptionU64Visitor {
            type Value = Option<u64>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("an optional integer or a string with a valid number inside")
            }

            fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> StdResult<Self::Value, D::Error> {
                deserializer.deserialize_any(OptionU64Visitor)
            }

            fn visit_none<E: de::Error>(self) -> StdResult<Self::Value, E> {
                Ok(None)
            }

            fn visit_u64<E: de::Error>(self, val: u64) -> StdResult<Option<u64>, E> {
                Ok(Some(val))
            }

            fn visit_str<E: de::Error>(self, string: &str) -> StdResult<Option<u64>, E> {
                string.parse().map(Some).map_err(|e| de::Error::custom(e))
            }
        }

        des.deserialize_option(OptionU64Visitor)
    }

    pub fn serialize<S: Serializer>(num: &Option<u64>, s: S) -> StdResult<S::Ok, S::Error> {
        Option::serialize(num, s)
    }
}

mod action_handler {
    use super::*;

    pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> StdResult<Action, D::Error> {
        struct ActionVisitor;

        impl<'de> Visitor<'de> for ActionVisitor {
            type Value = Action;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("an integer between 1 to 72")
            }

            // NOTE: Serde internally delegates number types below `u64` to it.
            fn visit_u64<E: de::Error>(self, value: u64) -> StdResult<Action, E> {
                let value = value as u8;

                Ok(match value {
                    1 => Action::GuildUpdate,
                    10...12 => Action::Channel(unsafe { transmute(value) }),
                    13...15 => Action::ChannelOverwrite(unsafe { transmute(value) }),
                    20...25 => Action::Member(unsafe { transmute(value) }),
                    30...32 => Action::Role(unsafe { transmute(value) }),
                    40...42 => Action::Invite(unsafe { transmute(value) }),
                    50...52 => Action::Webhook(unsafe { transmute(value) }),
                    60...62 => Action::Emoji(unsafe { transmute(value) }),
                    72 => Action::MessageDelete,
                    _ => return Err(E::custom(format!("Unexpected action number: {}", value))),
                })
            }
        }

        de.deserialize_any(ActionVisitor)
    }

    pub fn serialize<S: Serializer>(
        action: &Action,
        serializer: S,
    ) -> StdResult<S::Ok, S::Error> {
        serializer.serialize_u8(action.num())
    }
}
impl<'de> Deserialize<'de> for AuditLogs {
    fn deserialize<D: Deserializer<'de>>(de: D) -> StdResult<Self, D::Error> {
        #[derive(Deserialize)]
        #[serde(field_identifier)]
        enum Field {
            #[serde(rename = "audit_log_entries")] Entries,
            #[serde(rename = "webhooks")] Webhooks,
            #[serde(rename = "users")] Users,
        }

        struct EntriesVisitor;

        impl<'de> Visitor<'de> for EntriesVisitor {
            type Value = AuditLogs;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("audit log entries")
            }

            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> StdResult<AuditLogs, V::Error> {
                let mut audit_log_entries = None;
                let mut users = None;
                let mut webhooks = None;

                while let Some(field) = map.next_key()? {
                    match field {
                        Field::Entries => {
                            if audit_log_entries.is_some() {
                                return Err(de::Error::duplicate_field("entries"));
                            }

                            audit_log_entries = Some(map.next_value::<Vec<AuditLogEntry>>()?);
                        },
                        Field::Webhooks => {
                            if webhooks.is_some() {
                                return Err(de::Error::duplicate_field("webhooks"));
                            }

                            webhooks = Some(map.next_value::<Vec<Webhook>>()?);
                        },
                        Field::Users => {
                            if users.is_some() {
                                return Err(de::Error::duplicate_field("users"));
                            }

                            users = Some(map.next_value::<Vec<User>>()?);
                        },
                    }
                }

                Ok(AuditLogs {
                    entries: audit_log_entries
                        .unwrap()
                        .into_iter()
                        .map(|entry| (entry.id, entry))
                        .collect(),
                    webhooks: webhooks.unwrap(),
                    users: users.unwrap(),
                })
            }
        }

        const FIELD: &[&str] = &["audit_log_entries"];
        de.deserialize_struct("AuditLogs", FIELD, EntriesVisitor)
    }
}
<commit_msg>Get rid of a spurious import warning<commit_after>use internal::prelude::*;
use serde::de::{
    self,
    Deserialize,
    Deserializer,
    MapAccess,
    Visitor
};
use serde::ser::Serializer;
use super::super::prelude::*;
use std::{
    collections::HashMap,
    mem::transmute,
    fmt
};

/// Determines to what entity an action was used on.
#[derive(Debug)]
#[repr(u8)]
pub enum Target {
    Guild = 10,
    Channel = 20,
    User = 30,
    Role = 40,
    Invite = 50,
    Webhook = 60,
    Emoji = 70,
}

/// Determines the action that was done on a target.
#[derive(Debug)]
pub enum Action {
    GuildUpdate,
    Channel(ActionChannel),
    ChannelOverwrite(ActionChannelOverwrite),
    Member(ActionMember),
    Role(ActionRole),
    Invite(ActionInvite),
    Webhook(ActionWebhook),
    Emoji(ActionEmoji),
    MessageDelete,
}

impl Action {
    pub fn num(&self) -> u8 {
        use self::Action::*;

        match *self {
            GuildUpdate => 1,
            Action::Channel(ref x) => x.num(),
            Action::ChannelOverwrite(ref x) => x.num(),
            Action::Member(ref x) => x.num(),
            Action::Role(ref x) => x.num(),
            Action::Invite(ref x) => x.num(),
            Action::Webhook(ref x) => x.num(),
            Action::Emoji(ref x) => x.num(),
            Action::MessageDelete => 72,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionChannel {
    Create = 10,
    Update = 11,
    Delete = 12,
}

impl ActionChannel {
    pub fn num(&self) -> u8 {
        match *self {
            ActionChannel::Create => 10,
            ActionChannel::Update => 11,
            ActionChannel::Delete => 12,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionChannelOverwrite {
    Create = 13,
    Update = 14,
    Delete = 15,
}

impl ActionChannelOverwrite {
    pub fn num(&self) -> u8 {
        match *self {
            ActionChannelOverwrite::Create => 13,
            ActionChannelOverwrite::Update => 14,
            ActionChannelOverwrite::Delete => 15,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionMember {
    Kick = 20,
    Prune = 21,
    BanAdd = 22,
    BanRemove = 23,
    Update = 24,
    RoleUpdate = 25,
}

impl ActionMember {
    pub fn num(&self) -> u8 {
        match *self {
            ActionMember::Kick => 20,
            ActionMember::Prune => 21,
            ActionMember::BanAdd => 22,
            ActionMember::BanRemove => 23,
            ActionMember::Update => 24,
            ActionMember::RoleUpdate => 25,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionRole {
    Create = 30,
    Update = 31,
    Delete = 32,
}

impl ActionRole {
    pub fn num(&self) -> u8 {
        match *self {
            ActionRole::Create => 30,
            ActionRole::Update => 31,
            ActionRole::Delete => 32,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionInvite {
    Create = 40,
    Update = 41,
    Delete = 42,
}

impl ActionInvite {
    pub fn num(&self) -> u8 {
        match *self {
            ActionInvite::Create => 40,
            ActionInvite::Update => 41,
            ActionInvite::Delete => 42,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionWebhook {
    Create = 50,
    Update = 51,
    Delete = 52,
}

impl ActionWebhook {
    pub fn num(&self) -> u8 {
        match *self {
            ActionWebhook::Create => 50,
            ActionWebhook::Update => 51,
            ActionWebhook::Delete => 52,
        }
    }
}

#[derive(Debug)]
#[repr(u8)]
pub enum ActionEmoji {
    Create = 60,
    Delete = 61,
    Update = 62,
}

impl ActionEmoji {
    pub fn num(&self) -> u8 {
        match *self {
            ActionEmoji::Create => 60,
            ActionEmoji::Update => 61,
            ActionEmoji::Delete => 62,
        }
    }
}

#[derive(Debug, Deserialize, Serialize)]
pub struct Change {
    #[serde(rename = "key")] pub name: String,
    // TODO: Change these to an actual type.
    #[serde(rename = "old_value")] pub old: String,
    #[serde(rename = "new_value")] pub new: String,
}

#[derive(Debug)]
pub struct AuditLogs {
    pub entries: HashMap<AuditLogEntryId, AuditLogEntry>,
    pub webhooks: Vec<Webhook>,
    pub users: Vec<User>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct AuditLogEntry {
    /// Determines to what entity an [`action`] was used on.
    ///
    /// [`action`]: #structfield.action
    #[serde(with = "u64_handler")]
    pub target_id: u64,
    /// Determines what action was done on a [`target`]
    ///
    /// [`target`]: #structfield.target
    #[serde(
        with = "action_handler",
        rename = "action_type"
    )]
    pub action: Action,
    /// What was the reasoning by doing an action on a target? If there was one.
    pub reason: Option<String>,
    /// The user that did this action on a target.
    pub user_id: UserId,
    /// What changes were made.
    pub changes: Option<Vec<Change>>,
    /// The id of this entry.
    pub id: AuditLogEntryId,
    /// Some optional data assosiated with this entry.
    pub options: Option<Options>,
}

#[derive(Debug, Deserialize, Serialize)]
pub struct Options {
    /// Number of days after which inactive members were kicked.
    #[serde(default, with = "option_u64_handler")]
    pub delete_member_days: Option<u64>,
    /// Number of members removed by the prune
    #[serde(default, with = "option_u64_handler")]
    pub members_removed: Option<u64>,
    /// Channel in which the messages were deleted
    #[serde(default)]
    pub channel_id: Option<ChannelId>,
    /// Number of deleted messages.
    #[serde(default, with = "option_u64_handler")]
    pub count: Option<u64>,
    /// Id of the overwritten entity
    #[serde(default, with = "option_u64_handler")]
    pub id: Option<u64>,
    /// Type of overwritten entity ("member" or "role").
    #[serde(default, rename = "type")]
    pub kind: Option<String>,
    /// Name of the role if type is "role"
    #[serde(default)]
    pub role_name: Option<String>,
}

mod u64_handler {
    use super::*;

    pub fn deserialize<'de, D: Deserializer<'de>>(des: D) -> StdResult<u64, D::Error> {
        struct U64Visitor;

        impl<'de> Visitor<'de> for U64Visitor {
            type Value = u64;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("an integer or a string with a valid number inside")
            }

            // NOTE: Serde internally delegates number types below `u64` to it.
            fn visit_u64<E: de::Error>(self, val: u64) -> StdResult<u64, E> {
                Ok(val)
            }

            fn visit_str<E: de::Error>(self, string: &str) -> StdResult<u64, E> {
                string.parse().map_err(|e| de::Error::custom(e))
            }
        }

        des.deserialize_any(U64Visitor)
    }

    pub fn serialize<S: Serializer>(num: &u64, s: S) -> StdResult<S::Ok, S::Error> {
        s.serialize_u64(*num)
    }
}

mod option_u64_handler {
    use super::*;

    pub fn deserialize<'de, D: Deserializer<'de>>(des: D) -> StdResult<Option<u64>, D::Error> {
        struct OptionU64Visitor;

        impl<'de> Visitor<'de> for OptionU64Visitor {
            type Value = Option<u64>;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("an optional integer or a string with a valid number inside")
            }

            fn visit_some<D: Deserializer<'de>>(self, deserializer: D) -> StdResult<Self::Value, D::Error> {
                deserializer.deserialize_any(OptionU64Visitor)
            }

            fn visit_none<E: de::Error>(self) -> StdResult<Self::Value, E> {
                Ok(None)
            }

            fn visit_u64<E: de::Error>(self, val: u64) -> StdResult<Option<u64>, E> {
                Ok(Some(val))
            }

            fn visit_str<E: de::Error>(self, string: &str) -> StdResult<Option<u64>, E> {
                string.parse().map(Some).map_err(|e| de::Error::custom(e))
            }
        }

        des.deserialize_option(OptionU64Visitor)
    }

    pub fn serialize<S: Serializer>(num: &Option<u64>, s: S) -> StdResult<S::Ok, S::Error> {
        use serde::Serialize;

        Option::serialize(num, s)
    }
}

mod action_handler {
    use super::*;

    pub fn deserialize<'de, D: Deserializer<'de>>(de: D) -> StdResult<Action, D::Error> {
        struct ActionVisitor;

        impl<'de> Visitor<'de> for ActionVisitor {
            type Value = Action;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("an integer between 1 to 72")
            }

            // NOTE: Serde internally delegates number types below `u64` to it.
            fn visit_u64<E: de::Error>(self, value: u64) -> StdResult<Action, E> {
                let value = value as u8;

                Ok(match value {
                    1 => Action::GuildUpdate,
                    10...12 => Action::Channel(unsafe { transmute(value) }),
                    13...15 => Action::ChannelOverwrite(unsafe { transmute(value) }),
                    20...25 => Action::Member(unsafe { transmute(value) }),
                    30...32 => Action::Role(unsafe { transmute(value) }),
                    40...42 => Action::Invite(unsafe { transmute(value) }),
                    50...52 => Action::Webhook(unsafe { transmute(value) }),
                    60...62 => Action::Emoji(unsafe { transmute(value) }),
                    72 => Action::MessageDelete,
                    _ => return Err(E::custom(format!("Unexpected action number: {}", value))),
                })
            }
        }

        de.deserialize_any(ActionVisitor)
    }

    pub fn serialize<S: Serializer>(
        action: &Action,
        serializer: S,
    ) -> StdResult<S::Ok, S::Error> {
        serializer.serialize_u8(action.num())
    }
}
impl<'de> Deserialize<'de> for AuditLogs {
    fn deserialize<D: Deserializer<'de>>(de: D) -> StdResult<Self, D::Error> {
        #[derive(Deserialize)]
        #[serde(field_identifier)]
        enum Field {
            #[serde(rename = "audit_log_entries")] Entries,
            #[serde(rename = "webhooks")] Webhooks,
            #[serde(rename = "users")] Users,
        }

        struct EntriesVisitor;

        impl<'de> Visitor<'de> for EntriesVisitor {
            type Value = AuditLogs;

            fn expecting(&self, formatter: &mut fmt::Formatter) -> fmt::Result {
                formatter.write_str("audit log entries")
            }

            fn visit_map<V: MapAccess<'de>>(self, mut map: V) -> StdResult<AuditLogs, V::Error> {
                let mut audit_log_entries = None;
                let mut users = None;
                let mut webhooks = None;

                while let Some(field) = map.next_key()? {
                    match field {
                        Field::Entries => {
                            if audit_log_entries.is_some() {
                                return Err(de::Error::duplicate_field("entries"));
                            }

                            audit_log_entries = Some(map.next_value::<Vec<AuditLogEntry>>()?);
                        },
                        Field::Webhooks => {
                            if webhooks.is_some() {
                                return Err(de::Error::duplicate_field("webhooks"));
                            }

                            webhooks = Some(map.next_value::<Vec<Webhook>>()?);
                        },
                        Field::Users => {
                            if users.is_some() {
                                return Err(de::Error::duplicate_field("users"));
                            }

                            users = Some(map.next_value::<Vec<User>>()?);
                        },
                    }
                }

                Ok(AuditLogs {
                    entries: audit_log_entries
                        .unwrap()
                        .into_iter()
                        .map(|entry| (entry.id, entry))
                        .collect(),
                    webhooks: webhooks.unwrap(),
                    users: users.unwrap(),
                })
            }
        }

        const FIELD: &[&str] = &["audit_log_entries"];
        de.deserialize_struct("AuditLogs", FIELD, EntriesVisitor)
    }
}
<|endoftext|>


<commit_before>//! Not public API. Used as `$crate::export` by macros.

pub use core::marker::{Send, Sync};
pub use core::result::Result;
pub use serde;
<commit_msg>Fix module name in private module's doc<commit_after>//! Not public API. Used as `$crate::private` by macros.

pub use core::marker::{Send, Sync};
pub use core::result::Result;
pub use serde;
<|endoftext|>


<commit_before>//! Infrastructure for compiler plugins.
//!
//! Plugins are Rust libraries which extend the behavior of `rustc`
//! in various ways.
//!
//! Plugin authors will use the `Registry` type re-exported by
//! this module, along with its methods. The rest of the module
//! is for use by `rustc` itself.
//!
//! To define a plugin, build a dylib crate with a
//! `#[plugin_registrar]` function:
//!
//! ```no_run
//! #![crate_name = "myplugin"]
//! #![crate_type = "dylib"]
//! #![feature(plugin_registrar)]
//! #![feature(rustc_private)]
//!
//! extern crate rustc_plugin;
//! extern crate syntax;
//! extern crate syntax_pos;
//!
//! use rustc_plugin::Registry;
//! use syntax::ext::base::{ExtCtxt, MacResult};
//! use syntax_pos::Span;
//! use syntax::tokenstream::TokenTree;
//!
//! #[plugin_registrar]
//! pub fn plugin_registrar(reg: &mut Registry) {
//!     reg.register_macro("mymacro", expand_mymacro);
//! }
//!
//! fn expand_mymacro(cx: &mut ExtCtxt, span: Span, tt: &[TokenTree]) -> Box<MacResult> {
//!     unimplemented!()
//! }
//!
//! # fn main() {}
//! ```
//!
//! WARNING: We currently don't check that the registrar function
//! has the appropriate type!
//!
//! To use a plugin while compiling another crate:
//!
//! ```rust
//! #![feature(plugin)]
//! #![plugin(myplugin)]
//! ```
//!
//! See the [`plugin` feature](../unstable-book/language-features/plugin.html) of
//! the Unstable Book for more examples.

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]

#![feature(nll)]
#![feature(rustc_diagnostic_macros)]

#![recursion_limit="256"]

#![deny(rust_2018_idioms)]

pub use registry::Registry;

mod error_codes;
pub mod registry;
pub mod load;
pub mod build;

__build_diagnostic_array! { librustc_plugin, DIAGNOSTICS }
<commit_msg>Rollup merge of #60131 - agnxy:doc-link, r=ehuss<commit_after>//! Infrastructure for compiler plugins.
//!
//! Plugins are Rust libraries which extend the behavior of `rustc`
//! in various ways.
//!
//! Plugin authors will use the `Registry` type re-exported by
//! this module, along with its methods. The rest of the module
//! is for use by `rustc` itself.
//!
//! To define a plugin, build a dylib crate with a
//! `#[plugin_registrar]` function:
//!
//! ```no_run
//! #![crate_name = "myplugin"]
//! #![crate_type = "dylib"]
//! #![feature(plugin_registrar)]
//! #![feature(rustc_private)]
//!
//! extern crate rustc_plugin;
//! extern crate syntax;
//! extern crate syntax_pos;
//!
//! use rustc_plugin::Registry;
//! use syntax::ext::base::{ExtCtxt, MacResult};
//! use syntax_pos::Span;
//! use syntax::tokenstream::TokenTree;
//!
//! #[plugin_registrar]
//! pub fn plugin_registrar(reg: &mut Registry) {
//!     reg.register_macro("mymacro", expand_mymacro);
//! }
//!
//! fn expand_mymacro(cx: &mut ExtCtxt, span: Span, tt: &[TokenTree]) -> Box<MacResult> {
//!     unimplemented!()
//! }
//!
//! # fn main() {}
//! ```
//!
//! WARNING: We currently don't check that the registrar function
//! has the appropriate type!
//!
//! To use a plugin while compiling another crate:
//!
//! ```rust
//! #![feature(plugin)]
//! #![plugin(myplugin)]
//! ```
//!
//! See the [`plugin`
//! feature](https://doc.rust-lang.org/nightly/unstable-book/language-features/plugin.html)
//! of the Unstable Book for more examples.

#![doc(html_root_url = "https://doc.rust-lang.org/nightly/")]

#![feature(nll)]
#![feature(rustc_diagnostic_macros)]

#![recursion_limit="256"]

#![deny(rust_2018_idioms)]

pub use registry::Registry;

mod error_codes;
pub mod registry;
pub mod load;
pub mod build;

__build_diagnostic_array! { librustc_plugin, DIAGNOSTICS }
<|endoftext|>


<commit_before>use std::any::Any;

use super::bench::BenchSamples;
use super::time;
use super::types::TestDesc;
use super::options::ShouldPanic;

pub use self::TestResult::*;

// Return codes for secondary process.
// Start somewhere other than 0 so we know the return code means what we think
// it means.
pub const TR_OK: i32 = 50;
pub const TR_FAILED: i32 = 51;

#[derive(Debug, Clone, PartialEq)]
pub enum TestResult {
    TrOk,
    TrFailed,
    TrFailedMsg(String),
    TrIgnored,
    TrAllowedFail,
    TrBench(BenchSamples),
    TrTimedFail,
}

unsafe impl Send for TestResult {}

/// Creates a `TestResult` depending on the raw result of test execution
/// and assotiated data.
pub fn calc_result<'a>(
    desc: &TestDesc,
    task_result: Result<(), &'a (dyn Any + 'static + Send)>,
    time_opts: &Option<time::TestTimeOptions>,
    exec_time: &Option<time::TestExecTime>
) -> TestResult {
    let result = match (&desc.should_panic, task_result) {
        (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TestResult::TrOk,
        (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => {
            let maybe_panic_str = err
                .downcast_ref::<String>()
                .map(|e| &**e)
                .or_else(|| err.downcast_ref::<&'static str>().map(|e| *e));

            if maybe_panic_str
                .map(|e| e.contains(msg))
                .unwrap_or(false)
            {
                TestResult::TrOk
            } else {
                if desc.allow_fail {
                    TestResult::TrAllowedFail
                } else {
                    if let Some(panic_str) = maybe_panic_str{
                        TestResult::TrFailedMsg(
                            format!(r#"panic did not contain expected string
      panic message: `{:?}`,
 expected substring: `{:?}`"#, panic_str, &*msg)
                        )
                    } else {
                        TestResult::TrFailedMsg(
                            format!(r#"expected panic with string value,
 found non-string value: `{:?}`
     expected substring: `{:?}`"#, (**err).type_id(), &*msg)
                        )
                    }
                }
            }
        }
        (&ShouldPanic::Yes, Ok(())) => {
            TestResult::TrFailedMsg("test did not panic as expected".to_string())
        }
        _ if desc.allow_fail => TestResult::TrAllowedFail,
        _ => TestResult::TrFailed,
    };

    // If test is already failed (or allowed to fail), do not change the result.
    if result != TestResult::TrOk {
        return result;
    }

    // Check if test is failed due to timeout.
    if let (Some(opts), Some(time)) = (time_opts, exec_time) {
        if opts.error_on_excess && opts.is_critical(desc, time) {
            return TestResult::TrTimedFail;
        }
    }

    result
}

/// Creates a `TestResult` depending on the exit code of test subprocess.
pub fn get_result_from_exit_code(
    desc: &TestDesc,
    code: i32,
    time_opts: &Option<time::TestTimeOptions>,
    exec_time: &Option<time::TestExecTime>,
) -> TestResult {
    let result = match (desc.allow_fail, code) {
        (_, TR_OK) => TestResult::TrOk,
        (true, TR_FAILED) => TestResult::TrAllowedFail,
        (false, TR_FAILED) => TestResult::TrFailed,
        (_, _) => TestResult::TrFailedMsg(format!("got unexpected return code {}", code)),
    };

    // If test is already failed (or allowed to fail), do not change the result.
    if result != TestResult::TrOk {
        return result;
    }

    // Check if test is failed due to timeout.
    if let (Some(opts), Some(time)) = (time_opts, exec_time) {
        if opts.error_on_excess && opts.is_critical(desc, time) {
            return TestResult::TrTimedFail;
        }
    }

    result
}
<commit_msg>Simplify if else as suggested in PR feedback<commit_after>use std::any::Any;

use super::bench::BenchSamples;
use super::time;
use super::types::TestDesc;
use super::options::ShouldPanic;

pub use self::TestResult::*;

// Return codes for secondary process.
// Start somewhere other than 0 so we know the return code means what we think
// it means.
pub const TR_OK: i32 = 50;
pub const TR_FAILED: i32 = 51;

#[derive(Debug, Clone, PartialEq)]
pub enum TestResult {
    TrOk,
    TrFailed,
    TrFailedMsg(String),
    TrIgnored,
    TrAllowedFail,
    TrBench(BenchSamples),
    TrTimedFail,
}

unsafe impl Send for TestResult {}

/// Creates a `TestResult` depending on the raw result of test execution
/// and assotiated data.
pub fn calc_result<'a>(
    desc: &TestDesc,
    task_result: Result<(), &'a (dyn Any + 'static + Send)>,
    time_opts: &Option<time::TestTimeOptions>,
    exec_time: &Option<time::TestExecTime>
) -> TestResult {
    let result = match (&desc.should_panic, task_result) {
        (&ShouldPanic::No, Ok(())) | (&ShouldPanic::Yes, Err(_)) => TestResult::TrOk,
        (&ShouldPanic::YesWithMessage(msg), Err(ref err)) => {
            let maybe_panic_str = err
                .downcast_ref::<String>()
                .map(|e| &**e)
                .or_else(|| err.downcast_ref::<&'static str>().map(|e| *e));

            if maybe_panic_str.map(|e| e.contains(msg)).unwrap_or(false) {
                TestResult::TrOk
            } else if desc.allow_fail {
                TestResult::TrAllowedFail
            } else if let Some(panic_str) = maybe_panic_str {
                TestResult::TrFailedMsg(format!(
                    r#"panic did not contain expected string
      panic message: `{:?}`,
 expected substring: `{:?}`"#,
                    panic_str, msg
                ))
            } else {
                TestResult::TrFailedMsg(format!(
                    r#"expected panic with string value,
 found non-string value: `{:?}`
     expected substring: `{:?}`"#,
                    (**err).type_id(),
                    msg
                ))
            }
        }
        (&ShouldPanic::Yes, Ok(())) => {
            TestResult::TrFailedMsg("test did not panic as expected".to_string())
        }
        _ if desc.allow_fail => TestResult::TrAllowedFail,
        _ => TestResult::TrFailed,
    };

    // If test is already failed (or allowed to fail), do not change the result.
    if result != TestResult::TrOk {
        return result;
    }

    // Check if test is failed due to timeout.
    if let (Some(opts), Some(time)) = (time_opts, exec_time) {
        if opts.error_on_excess && opts.is_critical(desc, time) {
            return TestResult::TrTimedFail;
        }
    }

    result
}

/// Creates a `TestResult` depending on the exit code of test subprocess.
pub fn get_result_from_exit_code(
    desc: &TestDesc,
    code: i32,
    time_opts: &Option<time::TestTimeOptions>,
    exec_time: &Option<time::TestExecTime>,
) -> TestResult {
    let result = match (desc.allow_fail, code) {
        (_, TR_OK) => TestResult::TrOk,
        (true, TR_FAILED) => TestResult::TrAllowedFail,
        (false, TR_FAILED) => TestResult::TrFailed,
        (_, _) => TestResult::TrFailedMsg(format!("got unexpected return code {}", code)),
    };

    // If test is already failed (or allowed to fail), do not change the result.
    if result != TestResult::TrOk {
        return result;
    }

    // Check if test is failed due to timeout.
    if let (Some(opts), Some(time)) = (time_opts, exec_time) {
        if opts.error_on_excess && opts.is_critical(desc, time) {
            return TestResult::TrTimedFail;
        }
    }

    result
}
<|endoftext|>


<commit_before>extern mod std;

use core::libc::{c_char, c_int, c_void};
use core::option::{Some, None};
use core::result::{Ok, Err};
use core::result::Result;
use consts::*;

enum Pcre {}
enum PcreExtra {}
struct PcreRes {
    p: *Pcre,
    drop { unsafe { c::free(self.p as *c_void); } }
}

/// The result type of `compile`
pub type CompileResult = Result<Pattern, CompileErr>;

/// The result type of `exec`
pub type ExecResult = Result<Match, ExecErr>;

/// The result type of `search`
pub type SearchResult = Result<Match, RegexErr>;

// The result type of `replace`
pub type ReplaceResult = Result<@~str, RegexErr>;

/// The type that represents compile error
pub struct CompileErr {
    code: int,
    reason: @~str,
    offset: uint,
}

/// The type that represents exec error
pub type ExecErr = int;

/// Either compile or exec error
pub enum RegexErr {
    CompileErr(CompileErr),
    ExecErr(ExecErr),
}

/// Compiled regular expression
pub struct Pattern {
    str: @~str,
    priv pcre_res: @PcreRes,
}

/// Match
pub struct Match {
    subject: @~str,
    pattern: Pattern,
    priv captures: @~[int],
}

#[nolink]
#[abi = "cdecl"]
extern mod c {
    fn free(p: *c_void);
}

extern mod pcre {
    fn pcre_compile2(pattern: *c_char, options: c_int,
                     errorcodeptr: *c_int,
                     errptr: **c_char, erroffset: *c_int,
                     tableptr: *c_char) -> *Pcre;
    fn pcre_exec(code: *Pcre, extra: *PcreExtra,
                 subject: *c_char, length: c_int, startoffset: c_int,
                 options: c_int, ovector: * c_int, ovecsize: c_int) -> c_int;
    fn pcre_fullinfo(code: *Pcre, extra: *PcreExtra,
                     what: c_int, where: *c_void) -> c_int;
    fn pcre_get_stringnumber(code: *Pcre, name: *c_char) -> c_int;
}

pub trait PatternUtil {
    fn info_capture_count(self) -> uint;
    fn info_name_count(self) -> uint;
    fn info_name_entry_size(self) -> uint;
    fn with_name_table(self, blk: &fn(*u8));
    fn group_count(self) -> uint;
    fn group_names(self) -> ~[~str];
}

impl PatternUtil for Pattern {
    fn info_capture_count(self) -> uint {
        let count = -1 as c_int;
        unsafe {
            pcre::pcre_fullinfo(self.pcre_res.p, ptr::null(),
                                PCRE_INFO_CAPTURECOUNT as c_int,
                                ptr::addr_of(&count) as *c_void);
        }
        assert!(count >= 0 as c_int);
        return count as uint;
    }

    fn info_name_count(self) -> uint {
        let count = -1 as c_int;
        unsafe {
            pcre::pcre_fullinfo(self.pcre_res.p, ptr::null(),
                                PCRE_INFO_NAMECOUNT as c_int,
                                ptr::addr_of(&count) as *c_void);
        }
        assert!(count >= 0 as c_int);
        return count as uint;
    }

    fn info_name_entry_size(self) -> uint {
        let size = -1 as c_int;
        unsafe {
            pcre::pcre_fullinfo(self.pcre_res.p, ptr::null(),
                                PCRE_INFO_NAMEENTRYSIZE as c_int,
                                ptr::addr_of(&size) as *c_void);
        }
        assert!(size >= 0 as c_int);
        return size as uint;
    }

    fn with_name_table(self, blk: &fn(*u8)) {
        let table = ptr::null::<u8>();
        unsafe {
            pcre::pcre_fullinfo(self.pcre_res.p, ptr::null(),
                                PCRE_INFO_NAMETABLE as c_int,
                                ptr::addr_of(&table) as *c_void);
        }
        assert!(table != ptr::null::<u8>());
        blk(table);
    }

    fn group_count(self) -> uint {
        return self.info_capture_count();
    }

    fn group_names(self) -> ~[~str] {
        let count = self.info_name_count();
        if count == 0u { return ~[]; }
        let size = self.info_name_entry_size();
        let mut names: ~[~str] = ~[];
        unsafe {
            do self.with_name_table |table| {
                for uint::range(0u, count) |i| {
                    let p = ptr::offset(table, size * i + 2u);
                    let s = str::raw::from_c_str(p as *c_char);
                    vec::push(&mut names, s);
                }
            }
        }
        return names;
    }
}

pub trait PatternLike {
    fn compile(&self, options: int) -> CompileResult;
}

impl<'self> PatternLike for &'self str {
    fn compile(&self, options: int) -> CompileResult {
        compile(*self, options)
    }
}

impl PatternLike for ~str {
    fn compile(&self, options: int) -> CompileResult {
        compile(*self, options)
    }
}

impl PatternLike for @str {
    fn compile(&self, options: int) -> CompileResult {
        compile(*self, options)
    }
}

impl PatternLike for Pattern {
    fn compile(&self, _options: int) -> CompileResult {
        Ok(*self)
    }
}

impl PatternLike for CompileResult {
    fn compile(&self, _options: int) -> CompileResult {
        *self
    }
}

pub trait MatchExtensions {
    fn matched(self) -> ~str;
    fn prematch(self) -> ~str;
    fn postmatch(self) -> ~str;
    fn begin(self) -> uint;
    fn end(self) -> uint;
    fn group(self, i: uint) -> Option<@~str>;
    fn named_group(self, name: &str) -> Option<@~str>;
    fn subgroups(self) -> ~[~str];
    fn subgroups_iter(self, blk: &fn(&str));
    fn group_count(self) -> uint;
    fn group_names(self) -> ~[~str];
}

impl MatchExtensions for Match {
    fn matched(self) -> ~str {
        return str::slice(*self.subject, self.begin(), self.end());
    }

    fn prematch(self) -> ~str {
        return str::slice(*self.subject, 0u, self.begin());
    }

    fn postmatch(self) -> ~str {
        return str::slice(*self.subject ,self.end(),
                          str::char_len(*self.subject));
    }

    fn begin(self) -> uint {
        return self.captures[0] as uint;
    }

    fn end(self) -> uint {
        return self.captures[1] as uint;
    }

    fn group(self, i: uint) -> Option<@~str> {
        if i > self.group_count() {
            return None;
        }
        let i1 = self.captures[i * 2u];
        let i2 = self.captures[i * 2u + 1u];
        if(i1 < 0 || i2 < 0) {
            return None;
        }
        return Some(@str::slice(*self.subject, i1 as uint, i2 as uint));
    }

    fn named_group(self, name: &str) -> Option<@~str> {
        let i =  unsafe {
            str::as_buf(name, |s, _n| {
                pcre::pcre_get_stringnumber(self.pattern.pcre_res.p,
                                            s as *c_char)
            })
        };
        if i <= 0 as c_int { return None; }
        return self.group(i as uint);
    }

    fn subgroups(self) -> ~[~str] {
        let mut v = ~[];
        unsafe {
            vec::reserve(&mut v, self.group_count());
            do self.subgroups_iter |subgroup| {
                vec::push(&mut v, str::from_slice(subgroup));
            }
        }
        return v;
    }

    fn subgroups_iter(self, blk: &fn(&str)) {
        for uint::range(1u, self.group_count() + 1u) |i| {
            match self.group(i) {
              Some(s) => blk(*s),
              None => fail!(),
            }
        }
    }

    fn group_count(self) -> uint {
        return vec::len(*self.captures) / 2u - 1u;
    }

    fn group_names(self) -> ~[~str] {
        return self.pattern.group_names();
    }
}

pub fn compile(pattern: &str, options: int) -> CompileResult {
    if options | COMPILE_OPTIONS != COMPILE_OPTIONS {
        warn!("unrecognized option bit(s) are set");
    }

    let options = options | PCRE_NO_UTF8_CHECK; // str is always valid
    let errcode = 0 as c_int;
    let errreason: *c_char = ptr::null();
    let erroffset = 0 as c_int;
    let p = unsafe {
        str::as_buf(pattern, |pat, _n| {
            pcre::pcre_compile2(pat as *c_char,
                                options as c_int,
                                ptr::addr_of(&errcode),
                                ptr::addr_of(&errreason),
                                ptr::addr_of(&erroffset),
                                ptr::null())
        })
    };
    if p == ptr::null() {
        let reason = unsafe { @str::raw::from_c_str(errreason) };
        return Err(CompileErr {code: errcode as int,
                               reason: reason,
                               offset: erroffset as uint});
    }
    return Ok(Pattern {str: @str::from_slice(pattern),
                       pcre_res: @PcreRes {p: p}});
}

pub fn exec(pattern: Pattern,
            subject: &str, offset: uint,
            options: int) -> ExecResult {

    if (options | EXEC_OPTIONS) != EXEC_OPTIONS {
        warn!("unrecognized option bit(s) are set");
    }

    let options = options | PCRE_NO_UTF8_CHECK; // str is always valid

    let count = (pattern.info_capture_count() + 1u) as c_int;
    let mut ovec = vec::from_elem((count as uint) * 3u, 0u as c_int);

    let ret_code = unsafe {
        str::as_buf(subject, |s, _n| {
            pcre::pcre_exec(pattern.pcre_res.p, ptr::null(),
                            s as *c_char, str::len(subject) as c_int,
                            offset as c_int, options as c_int,
                            vec::raw::to_ptr(ovec) as *c_int,
                            count * (3 as c_int)) as int
        })
    };

    if ret_code < 0 { return Err(ret_code as ExecErr); }

    // Truncate the working space.
    unsafe { vec::raw::set_len(&mut ovec, count as uint * 2u) }

    let mut captures: ~[int] = ~[];
    unsafe { vec::reserve(&mut captures, vec::len(ovec)); }
    for ovec.each |o| {
        unsafe { vec::push(&mut captures, *o as int); }
    }
    assert!(vec::len(captures) % 2u == 0u);

    return Ok(Match {subject: @str::from_slice(subject),
                     pattern: pattern,
                     captures: @captures});
}

pub fn search<T: PatternLike>(pattern: T, subject: &str,
                              options: int)
                              -> SearchResult {
    return search_from(pattern, subject, 0u, options);
}

pub fn search_from<T: PatternLike>(pattern: T, subject: &str,
                                   offset: uint, options: int)
                                   -> SearchResult {
    assert!(offset <= str::len(subject));

    let c_opts = options & COMPILE_OPTIONS;
    let e_opts = options & EXEC_OPTIONS;

    let c = pattern.compile(c_opts);
    match c {
        Ok(pattern) => {
            let e = exec(pattern, subject, offset, e_opts);
            match e {
                Ok(m) => {
                    return Ok(m);
                }
                Err(e_err) => {
                    return Err(ExecErr(e_err));
                }
            }
        }
        Err(c_err) => {
            return Err(CompileErr(c_err));
        }
    }
}

pub fn replace<T: PatternLike + Copy>(pattern: T, subject: &str,
                                      repl: &str, options: int)
                                      -> ReplaceResult {
    return replace_fn_from(pattern, subject,
                           |_m| { str::from_slice(repl) }, 0u, options);
}

pub fn replace_from<T: PatternLike + Copy>(pattern: T, subject: &str,
                                           repl: &str,  offset: uint,
                                           options: int)
                                           -> ReplaceResult {
    return replace_fn_from(pattern, subject,
                           |_m| { str::from_slice(repl) }, offset, options);
}

pub fn replace_fn<T: PatternLike + Copy>(pattern: T, subject: &str,
                                         repl_fn: &fn(Match) -> ~str,
                                         options: int)
                                         -> ReplaceResult {
    return replace_fn_from(pattern, subject, repl_fn, 0u, options);
}

pub fn replace_fn_from<T: PatternLike + Copy>(pattern: T, subject: &str,
                                              repl_fn: &fn(Match) -> ~str,
                                              offset: uint,
                                              options: int)
                                              -> ReplaceResult {
    let r = search_from(pattern, subject, offset, options);
    match r {
        Ok(m) => {
            return Ok(@(m.prematch() + repl_fn(m) + m.postmatch()));
        }
        Err(e) => { return Err(e); }
    }
}

pub fn replace_all<T: PatternLike + Copy>(pattern: T, subject: &str,
                                          repl: &str,
                                          options: int)
                                          -> ReplaceResult {
    return replace_all_fn_from(pattern, subject,
                               |_m| { str::from_slice(repl) }, 0u, options);
}

pub fn replace_all_fn<T: PatternLike + Copy>(pattern: T, subject: &str,
                                             repl_fn: &fn(Match) -> ~str,
                                             options: int)
                                             -> ReplaceResult {
    return replace_all_fn_from(pattern, subject, repl_fn, 0u, options);
}

pub fn replace_all_from<T: PatternLike + Copy>(pattern: T, subject: &str,
                                               repl: &str,
                                               offset: uint,
                                               options: int)
                                               -> ReplaceResult {
    return replace_all_fn_from(pattern, subject,
                               |_m| { str::from_slice(repl) }, offset, options);
}

pub fn replace_all_fn_from<T: PatternLike + Copy>(pattern: T, subject: &str,
                                                  repl_fn: &fn(Match) -> ~str,
                                                  offset: uint,
                                                  options: int)
                                                  -> ReplaceResult {
    let mut offset = offset;
    let subject_len = str::len(subject);
    assert!(offset <= subject_len);

    let mut s = str::slice(subject, 0, offset);
    loop {
        let r = search_from(pattern, subject, offset, options);
        match r {
            Ok(m) => {
                s += str::slice(subject, offset, m.begin());
                s += repl_fn(m);
                offset = m.end();
            }
            Err(ExecErr(e)) if e == PCRE_ERROR_NOMATCH => {
                if offset != subject_len {
                    s += str::slice(subject, offset, subject_len);
                }
                break;
            }
            Err(e) => {
                return Err(copy e);
            }
        }
    }
    return Ok(@s);
}

pub fn fmt_compile_err(e: CompileErr) -> ~str {
    return fmt!("error %d: %s at offset %u", e.code, *e.reason, e.offset);
}

/// Return true iff `sr` indicates that the subject did not match the pattern
pub fn is_nomatch(sr: SearchResult) -> bool {
    match sr {
        Err(ExecErr(e)) if e == PCRE_ERROR_NOMATCH => true,
        _ => false,
    }
}
<commit_msg>Convert str slice to owned str<commit_after>extern mod std;

use core::libc::{c_char, c_int, c_void};
use core::option::{Some, None};
use core::result::{Ok, Err};
use core::result::Result;
use consts::*;

enum Pcre {}
enum PcreExtra {}
struct PcreRes {
    p: *Pcre,
    drop { unsafe { c::free(self.p as *c_void); } }
}

/// The result type of `compile`
pub type CompileResult = Result<Pattern, CompileErr>;

/// The result type of `exec`
pub type ExecResult = Result<Match, ExecErr>;

/// The result type of `search`
pub type SearchResult = Result<Match, RegexErr>;

// The result type of `replace`
pub type ReplaceResult = Result<@~str, RegexErr>;

/// The type that represents compile error
pub struct CompileErr {
    code: int,
    reason: @~str,
    offset: uint,
}

/// The type that represents exec error
pub type ExecErr = int;

/// Either compile or exec error
pub enum RegexErr {
    CompileErr(CompileErr),
    ExecErr(ExecErr),
}

/// Compiled regular expression
pub struct Pattern {
    str: @~str,
    priv pcre_res: @PcreRes,
}

/// Match
pub struct Match {
    subject: @~str,
    pattern: Pattern,
    priv captures: @~[int],
}

#[nolink]
#[abi = "cdecl"]
extern mod c {
    fn free(p: *c_void);
}

extern mod pcre {
    fn pcre_compile2(pattern: *c_char, options: c_int,
                     errorcodeptr: *c_int,
                     errptr: **c_char, erroffset: *c_int,
                     tableptr: *c_char) -> *Pcre;
    fn pcre_exec(code: *Pcre, extra: *PcreExtra,
                 subject: *c_char, length: c_int, startoffset: c_int,
                 options: c_int, ovector: * c_int, ovecsize: c_int) -> c_int;
    fn pcre_fullinfo(code: *Pcre, extra: *PcreExtra,
                     what: c_int, where: *c_void) -> c_int;
    fn pcre_get_stringnumber(code: *Pcre, name: *c_char) -> c_int;
}

pub trait PatternUtil {
    fn info_capture_count(self) -> uint;
    fn info_name_count(self) -> uint;
    fn info_name_entry_size(self) -> uint;
    fn with_name_table(self, blk: &fn(*u8));
    fn group_count(self) -> uint;
    fn group_names(self) -> ~[~str];
}

impl PatternUtil for Pattern {
    fn info_capture_count(self) -> uint {
        let count = -1 as c_int;
        unsafe {
            pcre::pcre_fullinfo(self.pcre_res.p, ptr::null(),
                                PCRE_INFO_CAPTURECOUNT as c_int,
                                ptr::addr_of(&count) as *c_void);
        }
        assert!(count >= 0 as c_int);
        return count as uint;
    }

    fn info_name_count(self) -> uint {
        let count = -1 as c_int;
        unsafe {
            pcre::pcre_fullinfo(self.pcre_res.p, ptr::null(),
                                PCRE_INFO_NAMECOUNT as c_int,
                                ptr::addr_of(&count) as *c_void);
        }
        assert!(count >= 0 as c_int);
        return count as uint;
    }

    fn info_name_entry_size(self) -> uint {
        let size = -1 as c_int;
        unsafe {
            pcre::pcre_fullinfo(self.pcre_res.p, ptr::null(),
                                PCRE_INFO_NAMEENTRYSIZE as c_int,
                                ptr::addr_of(&size) as *c_void);
        }
        assert!(size >= 0 as c_int);
        return size as uint;
    }

    fn with_name_table(self, blk: &fn(*u8)) {
        let table = ptr::null::<u8>();
        unsafe {
            pcre::pcre_fullinfo(self.pcre_res.p, ptr::null(),
                                PCRE_INFO_NAMETABLE as c_int,
                                ptr::addr_of(&table) as *c_void);
        }
        assert!(table != ptr::null::<u8>());
        blk(table);
    }

    fn group_count(self) -> uint {
        return self.info_capture_count();
    }

    fn group_names(self) -> ~[~str] {
        let count = self.info_name_count();
        if count == 0u { return ~[]; }
        let size = self.info_name_entry_size();
        let mut names: ~[~str] = ~[];
        unsafe {
            do self.with_name_table |table| {
                for uint::range(0u, count) |i| {
                    let p = ptr::offset(table, size * i + 2u);
                    let s = str::raw::from_c_str(p as *c_char);
                    vec::push(&mut names, s);
                }
            }
        }
        return names;
    }
}

pub trait PatternLike {
    fn compile(&self, options: int) -> CompileResult;
}

impl<'self> PatternLike for &'self str {
    fn compile(&self, options: int) -> CompileResult {
        compile(*self, options)
    }
}

impl PatternLike for ~str {
    fn compile(&self, options: int) -> CompileResult {
        compile(*self, options)
    }
}

impl PatternLike for @str {
    fn compile(&self, options: int) -> CompileResult {
        compile(*self, options)
    }
}

impl PatternLike for Pattern {
    fn compile(&self, _options: int) -> CompileResult {
        Ok(*self)
    }
}

impl PatternLike for CompileResult {
    fn compile(&self, _options: int) -> CompileResult {
        *self
    }
}

pub trait MatchExtensions {
    fn matched(self) -> ~str;
    fn prematch(self) -> ~str;
    fn postmatch(self) -> ~str;
    fn begin(self) -> uint;
    fn end(self) -> uint;
    fn group(self, i: uint) -> Option<@~str>;
    fn named_group(self, name: &str) -> Option<@~str>;
    fn subgroups(self) -> ~[~str];
    fn subgroups_iter(self, blk: &fn(&str));
    fn group_count(self) -> uint;
    fn group_names(self) -> ~[~str];
}

impl MatchExtensions for Match {
    fn matched(self) -> ~str {
        return str::slice(*self.subject, self.begin(), self.end()).to_owned();
    }

    fn prematch(self) -> ~str {
        return str::slice(*self.subject, 0u, self.begin()).to_owned();
    }

    fn postmatch(self) -> ~str {
        return str::slice(*self.subject ,self.end(),
                          str::char_len(*self.subject)).to_owned();
    }

    fn begin(self) -> uint {
        return self.captures[0] as uint;
    }

    fn end(self) -> uint {
        return self.captures[1] as uint;
    }

    fn group(self, i: uint) -> Option<@~str> {
        if i > self.group_count() {
            return None;
        }
        let i1 = self.captures[i * 2u];
        let i2 = self.captures[i * 2u + 1u];
        if(i1 < 0 || i2 < 0) {
            return None;
        }
        return Some(@str::slice(*self.subject, i1 as uint, i2 as uint).to_owned());
    }

    fn named_group(self, name: &str) -> Option<@~str> {
        let i =  unsafe {
            str::as_buf(name, |s, _n| {
                pcre::pcre_get_stringnumber(self.pattern.pcre_res.p,
                                            s as *c_char)
            })
        };
        if i <= 0 as c_int { return None; }
        return self.group(i as uint);
    }

    fn subgroups(self) -> ~[~str] {
        let mut v = ~[];
        unsafe {
            vec::reserve(&mut v, self.group_count());
            do self.subgroups_iter |subgroup| {
                vec::push(&mut v, str::from_slice(subgroup));
            }
        }
        return v;
    }

    fn subgroups_iter(self, blk: &fn(&str)) {
        for uint::range(1u, self.group_count() + 1u) |i| {
            match self.group(i) {
              Some(s) => blk(*s),
              None => fail!(),
            }
        }
    }

    fn group_count(self) -> uint {
        return vec::len(*self.captures) / 2u - 1u;
    }

    fn group_names(self) -> ~[~str] {
        return self.pattern.group_names();
    }
}

pub fn compile(pattern: &str, options: int) -> CompileResult {
    if options | COMPILE_OPTIONS != COMPILE_OPTIONS {
        warn!("unrecognized option bit(s) are set");
    }

    let options = options | PCRE_NO_UTF8_CHECK; // str is always valid
    let errcode = 0 as c_int;
    let errreason: *c_char = ptr::null();
    let erroffset = 0 as c_int;
    let p = unsafe {
        str::as_buf(pattern, |pat, _n| {
            pcre::pcre_compile2(pat as *c_char,
                                options as c_int,
                                ptr::addr_of(&errcode),
                                ptr::addr_of(&errreason),
                                ptr::addr_of(&erroffset),
                                ptr::null())
        })
    };
    if p == ptr::null() {
        let reason = unsafe { @str::raw::from_c_str(errreason) };
        return Err(CompileErr {code: errcode as int,
                               reason: reason,
                               offset: erroffset as uint});
    }
    return Ok(Pattern {str: @str::from_slice(pattern),
                       pcre_res: @PcreRes {p: p}});
}

pub fn exec(pattern: Pattern,
            subject: &str, offset: uint,
            options: int) -> ExecResult {

    if (options | EXEC_OPTIONS) != EXEC_OPTIONS {
        warn!("unrecognized option bit(s) are set");
    }

    let options = options | PCRE_NO_UTF8_CHECK; // str is always valid

    let count = (pattern.info_capture_count() + 1u) as c_int;
    let mut ovec = vec::from_elem((count as uint) * 3u, 0u as c_int);

    let ret_code = unsafe {
        str::as_buf(subject, |s, _n| {
            pcre::pcre_exec(pattern.pcre_res.p, ptr::null(),
                            s as *c_char, str::len(subject) as c_int,
                            offset as c_int, options as c_int,
                            vec::raw::to_ptr(ovec) as *c_int,
                            count * (3 as c_int)) as int
        })
    };

    if ret_code < 0 { return Err(ret_code as ExecErr); }

    // Truncate the working space.
    unsafe { vec::raw::set_len(&mut ovec, count as uint * 2u) }

    let mut captures: ~[int] = ~[];
    unsafe { vec::reserve(&mut captures, vec::len(ovec)); }
    for ovec.each |o| {
        unsafe { vec::push(&mut captures, *o as int); }
    }
    assert!(vec::len(captures) % 2u == 0u);

    return Ok(Match {subject: @str::from_slice(subject),
                     pattern: pattern,
                     captures: @captures});
}

pub fn search<T: PatternLike>(pattern: T, subject: &str,
                              options: int)
                              -> SearchResult {
    return search_from(pattern, subject, 0u, options);
}

pub fn search_from<T: PatternLike>(pattern: T, subject: &str,
                                   offset: uint, options: int)
                                   -> SearchResult {
    assert!(offset <= str::len(subject));

    let c_opts = options & COMPILE_OPTIONS;
    let e_opts = options & EXEC_OPTIONS;

    let c = pattern.compile(c_opts);
    match c {
        Ok(pattern) => {
            let e = exec(pattern, subject, offset, e_opts);
            match e {
                Ok(m) => {
                    return Ok(m);
                }
                Err(e_err) => {
                    return Err(ExecErr(e_err));
                }
            }
        }
        Err(c_err) => {
            return Err(CompileErr(c_err));
        }
    }
}

pub fn replace<T: PatternLike + Copy>(pattern: T, subject: &str,
                                      repl: &str, options: int)
                                      -> ReplaceResult {
    return replace_fn_from(pattern, subject,
                           |_m| { str::from_slice(repl) }, 0u, options);
}

pub fn replace_from<T: PatternLike + Copy>(pattern: T, subject: &str,
                                           repl: &str,  offset: uint,
                                           options: int)
                                           -> ReplaceResult {
    return replace_fn_from(pattern, subject,
                           |_m| { str::from_slice(repl) }, offset, options);
}

pub fn replace_fn<T: PatternLike + Copy>(pattern: T, subject: &str,
                                         repl_fn: &fn(Match) -> ~str,
                                         options: int)
                                         -> ReplaceResult {
    return replace_fn_from(pattern, subject, repl_fn, 0u, options);
}

pub fn replace_fn_from<T: PatternLike + Copy>(pattern: T, subject: &str,
                                              repl_fn: &fn(Match) -> ~str,
                                              offset: uint,
                                              options: int)
                                              -> ReplaceResult {
    let r = search_from(pattern, subject, offset, options);
    match r {
        Ok(m) => {
            return Ok(@(m.prematch() + repl_fn(m) + m.postmatch()));
        }
        Err(e) => { return Err(e); }
    }
}

pub fn replace_all<T: PatternLike + Copy>(pattern: T, subject: &str,
                                          repl: &str,
                                          options: int)
                                          -> ReplaceResult {
    return replace_all_fn_from(pattern, subject,
                               |_m| { str::from_slice(repl) }, 0u, options);
}

pub fn replace_all_fn<T: PatternLike + Copy>(pattern: T, subject: &str,
                                             repl_fn: &fn(Match) -> ~str,
                                             options: int)
                                             -> ReplaceResult {
    return replace_all_fn_from(pattern, subject, repl_fn, 0u, options);
}

pub fn replace_all_from<T: PatternLike + Copy>(pattern: T, subject: &str,
                                               repl: &str,
                                               offset: uint,
                                               options: int)
                                               -> ReplaceResult {
    return replace_all_fn_from(pattern, subject,
                               |_m| { str::from_slice(repl) }, offset, options);
}

pub fn replace_all_fn_from<T: PatternLike + Copy>(pattern: T, subject: &str,
                                                  repl_fn: &fn(Match) -> ~str,
                                                  offset: uint,
                                                  options: int)
                                                  -> ReplaceResult {
    let mut offset = offset;
    let subject_len = str::len(subject);
    assert!(offset <= subject_len);

    let mut s = str::slice(subject, 0, offset).to_owned();
    loop {
        let r = search_from(pattern, subject, offset, options);
        match r {
            Ok(m) => {
                s += str::slice(subject, offset, m.begin()).to_owned();
                s += repl_fn(m);
                offset = m.end();
            }
            Err(ExecErr(e)) if e == PCRE_ERROR_NOMATCH => {
                if offset != subject_len {
                    s += str::slice(subject, offset, subject_len).to_owned();
                }
                break;
            }
            Err(e) => {
                return Err(copy e);
            }
        }
    }
    return Ok(@s);
}

pub fn fmt_compile_err(e: CompileErr) -> ~str {
    return fmt!("error %d: %s at offset %u", e.code, *e.reason, e.offset);
}

/// Return true iff `sr` indicates that the subject did not match the pattern
pub fn is_nomatch(sr: SearchResult) -> bool {
    match sr {
        Err(ExecErr(e)) if e == PCRE_ERROR_NOMATCH => true,
        _ => false,
    }
}
<|endoftext|>


<commit_before>#[macro_use]
extern crate serde_derive;
extern crate docopt;
extern crate image;
extern crate gpx;
extern crate geo;
extern crate chrono;
extern crate rayon;

use std::fs;
use std::fs::File;
use std::io::BufReader;
use std::path;

use docopt::Docopt;
use gpx::read;
use gpx::{Gpx, Track};
use geo::Point;
use image::ImageBuffer;
use rayon::prelude::*;

const USAGE: &'static str = "
Generate video from GPX files.

Usage:
  derivers <top-lat> <left-lng> <bottom-lat> <right-lng> <width> <height> <directory>
";

#[derive(Debug, Deserialize)]
struct CommandArgs {
    arg_top_lat: f64,
    arg_left_lng: f64,
    arg_bottom_lat: f64,
    arg_right_lng: f64,
    arg_width: u32,
    arg_height: u32,
    arg_directory: String,
}

#[derive(Debug)]
struct ImageFrame {
    top_left: Point<f64>,
    bottom_right: Point<f64>,
    buf: image::RgbaImage
}

impl ImageFrame {
    pub fn from(args: &CommandArgs) -> ImageFrame {

        // h == w * (top - bottom) / (right - left)
        let height = (args.arg_width as f64) *
            ((args.arg_top_lat - args.arg_bottom_lat) /
             (args.arg_right_lng - args.arg_left_lng));

        println!("Computed height: {:?}", height);

        ImageFrame {
            top_left: Point::new(args.arg_left_lng, args.arg_top_lat),
            bottom_right: Point::new(args.arg_right_lng, args.arg_bottom_lat),
            buf: ImageBuffer::from_pixel(args.arg_width, height as u32,
                                         image::Rgba([0, 0, 0, 255]))
        }
    }

    // Using simple equirectangular projection for now
    pub fn project_to_screen(&self, coord: &Point<f64>) -> Option<(u32, u32)> {
        // lng is x pos
        let x_pos = self.top_left.lng() - coord.lng();
        let y_pos = self.top_left.lat() - coord.lat();

        let x_offset = x_pos / (self.top_left.lng() - self.bottom_right.lng());
        let y_offset = y_pos / (self.top_left.lat() - self.bottom_right.lat());

        let (x, y) = ((x_offset * self.buf.width() as f64),
                      (y_offset * self.buf.height() as f64));

        if (x < 0.0 || x as u32 >= self.buf.width()) ||
            (y < 0.0 || y as u32 >= self.buf.height()) {
            None
        } else {
            Some((x as u32, y as u32))
        }
    }
}

#[derive(Debug)]
struct Activity {
    name: String,
    date: chrono::DateTime<chrono::Utc>,
    track_points: Vec<Point<f64>>,
}

fn parse_gpx(path: &path::PathBuf) -> Option<Activity> {
    let file = File::open(path).unwrap();
    let reader = BufReader::new(file);

    let gpx: Gpx = read(reader).unwrap();

    // Nothing to do if there are no tracks
    if gpx.tracks.len() == 0 {
        return None;
    } else if gpx.tracks.len() > 1 {
        println!("Warning! more than 1 track, just taking first");
    }

    let track: &Track = &gpx.tracks[0];

    let mut activity = Activity {
        name: track.name.clone().unwrap_or(String::from("Untitled")),
        date: chrono::Utc::now(),
        track_points: vec![],
    };

    if let Some(metadata) = gpx.metadata {
        if let Some(time) = metadata.time {
            activity.date = time;
        }
    }

    // Append all the waypoints.
    for seg in track.segments.iter() {
        let points = seg.points.iter().map(|ref wpt| wpt.point());
        activity.track_points.extend(points);
    }

    if activity.track_points.len() == 0 {
        None
    } else {
        Some(activity)
    }
}

fn main() {
    let args: CommandArgs = Docopt::new(USAGE)
        .and_then(|d| d.deserialize())
        .unwrap_or_else(|e| e.exit());

    println!("{:?}", args);

    let mut img = ImageFrame::from(&args);

    let paths: Vec<path::PathBuf> = fs::read_dir(args.arg_directory)
        .unwrap()
        .into_iter()
        .map(|p| p.unwrap().path())
        .collect();

    let activities: Vec<Activity> = paths
        .into_par_iter()
        .filter_map(|ref p| parse_gpx(p))
        .collect();

    for act in activities {
        println!("Activity: {:?}", act.name);

        for pt in act.track_points.iter() {
            if let Some((x, y)) = img.project_to_screen(pt) {
                let pixel = img.buf.get_pixel_mut(x, y);
                let c = if pixel[0] == 255 {
                    pixel[0]
                } else if pixel[0] == 0{
                    25
                } else {
                    pixel[0] + 5
                };

                *pixel = image::Rgba([c, c, c, 255]);
            }
        }
    }

    let fout = &mut File::create("heatmap.png").unwrap();
    image::ImageRgba8(img.buf).save(fout, image::PNG).unwrap();
}
<commit_msg>Ultra hacky support for video files<commit_after>#[macro_use]
extern crate serde_derive;
extern crate docopt;
extern crate image;
extern crate gpx;
extern crate geo;
extern crate chrono;
extern crate rayon;

use std::fs;
use std::fs::File;
use std::io::BufReader;
use std::path;

use docopt::Docopt;
use gpx::read;
use gpx::{Gpx, Track};
use geo::Point;
use image::ImageBuffer;
use rayon::prelude::*;

const USAGE: &'static str = "
Generate video from GPX files.

Usage:
  derivers <top-lat> <left-lng> <bottom-lat> <right-lng> <width> <height> <directory>
";

#[derive(Debug, Deserialize)]
struct CommandArgs {
    arg_top_lat: f64,
    arg_left_lng: f64,
    arg_bottom_lat: f64,
    arg_right_lng: f64,
    arg_width: u32,
    arg_height: u32,
    arg_directory: String,
}

#[derive(Debug)]
struct ImageFrame {
    top_left: Point<f64>,
    bottom_right: Point<f64>,
    buf: image::RgbImage
}

impl ImageFrame {
    pub fn from(args: &CommandArgs) -> ImageFrame {

        // h == w * (top - bottom) / (right - left)
        let height = (args.arg_width as f64) *
            ((args.arg_top_lat - args.arg_bottom_lat) /
             (args.arg_right_lng - args.arg_left_lng));

        println!("Computed height: {:?}", height);

        ImageFrame {
            top_left: Point::new(args.arg_left_lng, args.arg_top_lat),
            bottom_right: Point::new(args.arg_right_lng, args.arg_bottom_lat),
            buf: ImageBuffer::from_pixel(args.arg_width, height as u32,
                                         image::Rgb([0, 0, 0]))
        }
    }

    // Using simple equirectangular projection for now
    pub fn project_to_screen(&self, coord: &Point<f64>) -> Option<(u32, u32)> {
        // lng is x pos
        let x_pos = self.top_left.lng() - coord.lng();
        let y_pos = self.top_left.lat() - coord.lat();

        let x_offset = x_pos / (self.top_left.lng() - self.bottom_right.lng());
        let y_offset = y_pos / (self.top_left.lat() - self.bottom_right.lat());

        let (x, y) = ((x_offset * self.buf.width() as f64),
                      (y_offset * self.buf.height() as f64));

        if (x < 0.0 || x as u32 >= self.buf.width()) ||
            (y < 0.0 || y as u32 >= self.buf.height()) {
            None
        } else {
            Some((x as u32, y as u32))
        }
    }
}

#[derive(Debug)]
struct Activity {
    name: String,
    date: chrono::DateTime<chrono::Utc>,
    track_points: Vec<Point<f64>>,
}

fn parse_gpx(path: &path::PathBuf) -> Option<Activity> {
    let file = File::open(path).unwrap();
    let reader = BufReader::new(file);

    let gpx: Gpx = read(reader).unwrap();

    // Nothing to do if there are no tracks
    if gpx.tracks.len() == 0 {
        return None;
    } else if gpx.tracks.len() > 1 {
        println!("Warning! more than 1 track, just taking first");
    }

    let track: &Track = &gpx.tracks[0];

    let mut activity = Activity {
        name: track.name.clone().unwrap_or(String::from("Untitled")),
        date: chrono::Utc::now(),
        track_points: vec![],
    };

    if let Some(metadata) = gpx.metadata {
        if let Some(time) = metadata.time {
            activity.date = time;
        }
    }

    // Append all the waypoints.
    for seg in track.segments.iter() {
        let points = seg.points.iter().map(|ref wpt| wpt.point());
        activity.track_points.extend(points);
    }

    if activity.track_points.len() == 0 {
        None
    } else {
        Some(activity)
    }
}

fn main() {
    let args: CommandArgs = Docopt::new(USAGE)
        .and_then(|d| d.deserialize())
        .unwrap_or_else(|e| e.exit());

    println!("{:?}", args);

    let mut img = ImageFrame::from(&args);

    let paths: Vec<path::PathBuf> = fs::read_dir(args.arg_directory)
        .unwrap()
        .into_iter()
        .map(|p| p.unwrap().path())
        .collect();

    let activities: Vec<Activity> = paths
        .into_par_iter()
        .filter_map(|ref p| parse_gpx(p))
        .collect();

    let fout = &mut File::create("heatmap.ppm").unwrap();
    let cloned_buf = img.buf.clone();
    let dyn_image = image::ImageRgb8(img.buf.clone());

    for act in activities {
        println!("Activity: {:?}", act.name);

        for pt in act.track_points.iter() {
            if let Some((x, y)) = img.project_to_screen(pt) {
                let pixel = img.buf.get_pixel_mut(x, y);
                let c = if pixel[0] == 255 {
                    pixel[0]
                } else if pixel[0] == 0{
                    25
                } else {
                    pixel[0] + 5
                };

                *pixel = image::Rgb([c, c, c]);
            }
        }

        image::ImageRgb8(img.buf.clone()).save(fout, image::PPM).unwrap();
    }
}
<|endoftext|>


<commit_before>use std::process::Command;
use std::process::Child;
use std::process::Stdio;
use std::rc::Rc;
use std::sync::RwLock;
use std::ffi::OsStr;
use std::convert::AsRef;
use core::workspaces::Workspaces;
use config::Config;
use window_system::*;

#[macro_export]
macro_rules! add_key_handler_str(
    ($config: expr, $w:expr, $key:expr, $modkey:expr, $inp:expr) => (
        $config.add_key_handler($w.get_keycode_from_string($key), $modkey, box $inp);
    )
);

#[macro_export]
macro_rules! add_key_handler_code(
    ($config: expr, $key:expr, $modkey:expr, $inp:expr) => (
        $config.add_key_handler($key, $modkey, box $inp);
    )
);

#[macro_export]
macro_rules! add_mouse_handler(
    ($config: expr, $button:expr, $modkey:expr, $inp:expr) => (
        $config.add_mouse_handler($button, $modkey, box $inp);
    )
);

#[macro_export]
macro_rules! send_layout_message(
    ($message: expr) => (
        |m, w, c| m.send_layout_message($message, w.deref(), c).windows(w.deref(), c, &|x| x.clone())
    )
);

#[macro_export]
macro_rules! run(
    ($command: expr, $options: expr) => (
        |w, _, _| { run($command, String::from($options).split(' ').map(String::from).collect()); w }
    )
);

pub fn run<S: AsRef<OsStr>>(program: S, args: Vec<String>) {
    match Command::new(program).args(&args).spawn() {
        _ => ()
    }
}

pub fn spawn_pipe<S: AsRef<OsStr>>(config: &mut Config, program: S, args: Vec<String>) -> Rc<RwLock<Child>> {
    let result = Command::new(program)
        .args(&args).stdin(Stdio::piped()).spawn().unwrap();
    let rc = Rc::new(RwLock::new(result));
    config.general.pipes.push(rc.clone());
    rc
}

pub fn spawn_on(workspaces: Workspaces, _: &WindowSystem,
                window: Window, workspace_id: u32) -> Workspaces {
    workspaces.focus_window(window).shift(workspace_id)
}
<commit_msg>Remove box syntax requirement from macros<commit_after>use std::process::Command;
use std::process::Child;
use std::process::Stdio;
use std::rc::Rc;
use std::sync::RwLock;
use std::ffi::OsStr;
use std::convert::AsRef;
use core::workspaces::Workspaces;
use config::Config;
use window_system::*;

#[macro_export]
macro_rules! add_key_handler_str(
    ($config: expr, $w:expr, $key:expr, $modkey:expr, $inp:expr) => (
        $config.add_key_handler($w.get_keycode_from_string($key), $modkey, Box::new($inp));
    )
);

#[macro_export]
macro_rules! add_key_handler_code(
    ($config: expr, $key:expr, $modkey:expr, $inp:expr) => (
        $config.add_key_handler($key, $modkey, Box::new($inp));
    )
);

#[macro_export]
macro_rules! add_mouse_handler(
    ($config: expr, $button:expr, $modkey:expr, $inp:expr) => (
        $config.add_mouse_handler($button, $modkey, Box::new($inp));
    )
);

#[macro_export]
macro_rules! send_layout_message(
    ($message: expr) => (
        |m, w, c| m.send_layout_message($message, w.deref(), c).windows(w.deref(), c, &|x| x.clone())
    )
);

#[macro_export]
macro_rules! run(
    ($command: expr, $options: expr) => (
        |w, _, _| { run($command, String::from($options).split(' ').map(String::from).collect()); w }
    )
);

pub fn run<S: AsRef<OsStr>>(program: S, args: Vec<String>) {
    match Command::new(program).args(&args).spawn() {
        _ => ()
    }
}

pub fn spawn_pipe<S: AsRef<OsStr>>(config: &mut Config, program: S, args: Vec<String>) -> Rc<RwLock<Child>> {
    let result = Command::new(program)
        .args(&args).stdin(Stdio::piped()).spawn().unwrap();
    let rc = Rc::new(RwLock::new(result));
    config.general.pipes.push(rc.clone());
    rc
}

pub fn spawn_on(workspaces: Workspaces, _: &WindowSystem,
                window: Window, workspace_id: u32) -> Workspaces {
    workspaces.focus_window(window).shift(workspace_id)
}
<|endoftext|>


<commit_before>// Implements http://rosettacode.org/wiki/Metered_concurrency
// Rust has a perfectly good Semaphore type already.  It lacks count(), though, so we can't use it
// directly.
#![feature(unsafe_destructor)]

extern crate sync;

use std::io::timer;
use std::sync::Arc;
use std::sync::atomic::AtomicUint;
use std::sync::atomics;
use std::time::duration::Duration;

pub struct CountingSemaphore {
    count: AtomicUint, // Remaining resource count
    backoff: Duration, // How long to sleep if a resource is being contended
}

pub struct CountingSemaphoreGuard<'a> {
    sem: &'a CountingSemaphore, // A reference to the owning semaphore.
}

impl CountingSemaphore {
    // Create a semaphore with `max` available resources and a linearly increasing backoff of
    // `backoff` (used during spinlock contention).
    pub fn new(max: uint, backoff: Duration) -> CountingSemaphore {
        CountingSemaphore { count: AtomicUint::new(max), backoff: backoff }
    }

    // Acquire a resource, returning a RAII CountingSemaphoreGuard.
    pub fn acquire(&self) -> CountingSemaphoreGuard {
        // Spinlock until remaining resource count is at least 1
        let mut backoff: Duration = self.backoff;
        loop {
            // Probably don't need SeqCst here, but it doesn't hurt.
            let count = self.count.load(atomics::SeqCst);
            // The check for 0 is necessary to make sure we don't go negative, which is why this
            // must be a compare-and-swap rather than a straight decrement.
            if count == 0 || self.count.compare_and_swap(count, count - 1, atomics::SeqCst) != count {
                // Linear backoff a la Servo's spinlock contention.
                timer::sleep(backoff);
                backoff = backoff + self.backoff;
            } else {
                // We successfully acquired the resource.
                break
            }
        }
        CountingSemaphoreGuard { sem: self }
    }

    // Return remaining resource count
    pub fn count(&self) -> uint {
        self.count.load(atomics::SeqCst)
    }
}

#[unsafe_destructor]
impl<'a> Drop for CountingSemaphoreGuard<'a> {
    // When the guard is dropped, a resource is released back to the pool.
    fn drop(&mut self) {
        self.sem.count.fetch_add(1, atomics::SeqCst);
    }
}

fn metered(duration: Duration, backoff: Duration) {
    static MAX_COUNT: uint = 4; // Total available resources
    static NUM_WORKERS: u8 = 10; // Number of workers contending for the resources
    let sem = Arc::new(CountingSemaphore::new(MAX_COUNT, backoff));
    let (tx, rx) = channel();
    for i in range(0, NUM_WORKERS) {
        let sem = sem.clone();
        let tx = tx.clone();
        spawn(proc() {
            let guard = sem.acquire();
            let count = sem.count();
            assert!(count < MAX_COUNT);
            println!("Worker {} after acquire: count = {}", i, count);
            timer::sleep(duration);
            drop(guard);
            let count = sem.count();
            assert!(count <= MAX_COUNT);
            println!("Worker {} after release: count = {}", i, count);
            tx.send(());
        })
    }
    drop(tx);
    for _ in range(0, NUM_WORKERS) {
        rx.recv();
    }
}

#[test]
fn test_metered_concurrency() {
    metered(Duration::seconds(1) / 20, Duration::seconds(1) / 20);
}

#[cfg(not(test))]
fn main() {
    metered(Duration::seconds(2), Duration::seconds(1) / 10);
}
<commit_msg>More comments for metered concurrency, and shorter backoff.<commit_after>// Implements http://rosettacode.org/wiki/Metered_concurrency
// Rust has a perfectly good Semaphore type already.  It lacks count(), though, so we can't use it
// directly.
#![feature(unsafe_destructor)]

extern crate sync;

use std::io::timer;
use std::sync::Arc;
use std::sync::atomic::AtomicUint;
use std::sync::atomics;
use std::time::duration::Duration;

pub struct CountingSemaphore {
    count: AtomicUint, // Remaining resource count
    backoff: Duration, // How long to sleep if a resource is being contended
}

pub struct CountingSemaphoreGuard<'a> {
    sem: &'a CountingSemaphore, // A reference to the owning semaphore.
}

impl CountingSemaphore {
    // Create a semaphore with `max` available resources and a linearly increasing backoff of
    // `backoff` (used during spinlock contention).
    pub fn new(max: uint, backoff: Duration) -> CountingSemaphore {
        CountingSemaphore { count: AtomicUint::new(max), backoff: backoff }
    }

    // Acquire a resource, returning a RAII CountingSemaphoreGuard.
    pub fn acquire(&self) -> CountingSemaphoreGuard {
        // Spinlock until remaining resource count is at least 1
        let mut backoff: Duration = self.backoff;
        loop {
            // Probably don't need SeqCst here, but it doesn't hurt.
            let count = self.count.load(atomics::SeqCst);
            // The check for 0 is necessary to make sure we don't go negative, which is why this
            // must be a compare-and-swap rather than a straight decrement.
            if count == 0 || self.count.compare_and_swap(count, count - 1, atomics::SeqCst) != count {
                // Linear backoff a la Servo's spinlock contention.
                timer::sleep(backoff);
                backoff = backoff + self.backoff;
            } else {
                // We successfully acquired the resource.
                break
            }
        }
        CountingSemaphoreGuard { sem: self }
    }

    // Return remaining resource count
    pub fn count(&self) -> uint {
        self.count.load(atomics::SeqCst)
    }
}

#[unsafe_destructor]
impl<'a> Drop for CountingSemaphoreGuard<'a> {
    // When the guard is dropped, a resource is released back to the pool.
    fn drop(&mut self) {
        self.sem.count.fetch_add(1, atomics::SeqCst);
    }
}

fn metered(duration: Duration) {
    static MAX_COUNT: uint = 4; // Total available resources
    static NUM_WORKERS: u8 = 10; // Number of workers contending for the resources
    let backoff = Duration::milliseconds(1); // Linear backoff time
    // Create a shared reference to the semaphore
    let sem = Arc::new(CountingSemaphore::new(MAX_COUNT, backoff));
    // Create a channel for notifying the main task that the workers are done
    let (tx, rx) = channel();
    for i in range(0, NUM_WORKERS) {
        let sem = sem.clone();
        let tx = tx.clone();
        spawn(proc() {
            // Acquire the resource
            let guard = sem.acquire();
            let count = sem.count();
            // Make sure the count is legal
            assert!(count < MAX_COUNT);
            println!("Worker {} after acquire: count = {}", i, count);
            // Sleep for `duration`
            timer::sleep(duration);
            // Release the resource
            drop(guard);
            // Make sure the count is legal
            let count = sem.count();
            assert!(count <= MAX_COUNT);
            println!("Worker {} after release: count = {}", i, count);
            // Notify the main task of completion
            tx.send(());
        })
    }
    drop(tx);
    // Wait for all the subtasks to finish
    for _ in range(0, NUM_WORKERS) {
        rx.recv();
    }
}

#[test]
fn test_metered_concurrency() {
    // Hold each resource for 1/20 of a second per worker
    metered(Duration::seconds(1) / 20);
}

#[cfg(not(test))]
fn main() {
    // Hold each resource for 2 seconds per worker
    metered(Duration::seconds(2));
}
<|endoftext|>