<commit_before>use nom::{
  be_u8, be_u16, be_u32,
  IResult,
  ErrorKind,
};

use attribute_info::*;
use attribute_info::types::StackMapFrame::*;

pub fn attribute_parser(input: &[u8]) -> IResult<&[u8], AttributeInfo> {
    do_parse!(input,
        attribute_name_index: be_u16 >>
        attribute_length: be_u32 >>
        info: take!(attribute_length)>>
        (AttributeInfo {
            attribute_name_index: attribute_name_index,
            attribute_length: attribute_length,
            info: info.to_owned(),
        })
    )
}

pub fn exception_entry_parser(input: &[u8]) -> IResult<&[u8], ExceptionEntry> {
    do_parse!(input,
        start_pc: be_u16 >>
        end_pc: be_u16 >>
        handler_pc: be_u16 >>
        catch_type: be_u16>>
        (ExceptionEntry {
            start_pc: start_pc,
            end_pc: end_pc,
            handler_pc: handler_pc,
            catch_type: catch_type,
        })
    )
}

pub fn code_attribute_parser(input: &[u8]) -> IResult<&[u8], CodeAttribute> {
    do_parse!(input,
        max_stack: be_u16 >>
        max_locals: be_u16 >>
        code_length: be_u32 >>
        code: take!(code_length) >>
        exception_table_length: be_u16 >>
        exception_table: count!(exception_entry_parser, exception_table_length as usize) >>
        attributes_count: be_u16 >>
        attributes: count!(attribute_parser, attributes_count as usize) >>
        (CodeAttribute {
            max_stack: max_stack,
            max_locals: max_locals,
            code_length: code_length,
            code: code.to_owned(),
            exception_table_length: exception_table_length,
            exception_table: exception_table,
            attributes_count: attributes_count,
            attributes: attributes,
        })
    )
}

fn same_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    value!(input, SameFrame { frame_type })
}

fn verification_type(v: &u8) -> Option<VerificationTypeInfo> {
    use self::VerificationTypeInfo::*;
    match *v {
        0 => Some(Top),
        1 => Some(Integer),
        2 => Some(Float),
        3 => Some(Double),
        4 => Some(Long),
        5 => Some(Null),
        6 => Some(UninitializedThis),
        7 => Some(Object),
        8 => Some(Uninitialized),
        _ => None,
    }
}

fn verification_type_parser(input: &[u8]) -> IResult<&[u8], VerificationTypeInfo> {
    match verification_type(&input[0]) {
        Some(x) => IResult::Done(&input[1..], x),
        _ => IResult::Error(error_position!(ErrorKind::Alt, input)),
    }
}

fn same_locals_1_stack_item_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        stack: verification_type_parser >>
        (SameLocals1StackItemFrame { frame_type, stack })
    )
}

fn same_locals_1_stack_item_frame_extended_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        offset_delta: be_u16 >>
        stack: verification_type_parser >>
        (SameLocals1StackItemFrameExtended { frame_type, offset_delta, stack })
    )
}

fn chop_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        offset_delta: be_u16 >>
        (ChopFrame { frame_type, offset_delta })
    )
}

fn same_frame_extended_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        offset_delta: be_u16 >>
        (SameFrameExtended { frame_type, offset_delta })
    )
}

fn append_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        offset_delta: be_u16 >>
        locals: count!(verification_type_parser, (frame_type - 251) as usize) >>
        (AppendFrame { frame_type, offset_delta, locals })
    )
}

fn full_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        offset_delta: be_u16 >>
        number_of_locals: be_u16 >>
        locals: count!(verification_type_parser, number_of_locals as usize) >>
        number_of_stack_items: be_u16 >>
        stack: count!(verification_type_parser, number_of_stack_items as usize) >>
        (FullFrame {
            frame_type,
            offset_delta,
            number_of_locals,
            locals,
            number_of_stack_items,
            stack,
        })
    )
}

fn stack_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    match frame_type {
          0... 63 => same_frame_parser(input, frame_type),
         64...127 => same_locals_1_stack_item_frame_parser(input, frame_type),
        247       => same_locals_1_stack_item_frame_extended_parser(input, frame_type),
        248...250 => chop_frame_parser(input, frame_type),
        251       => same_frame_extended_parser(input, frame_type),
        252...254 => append_frame_parser(input, frame_type),
        255       => full_frame_parser(input, frame_type),
        _ => IResult::Error(error_position!(ErrorKind::Alt, input)),
    }
}

fn stack_map_frame_entry_parser(input: &[u8]) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        frame_type: be_u8 >>
        stack_frame: apply!(stack_frame_parser, frame_type) >>
        (stack_frame)
    )
}

pub fn stack_map_table_attribute_parser(input: &[u8]) -> IResult<&[u8], StackMapTableAttribute> {
    do_parse!(input,
        number_of_entries: be_u16 >>
        entries: count!(stack_map_frame_entry_parser, number_of_entries as usize) >>
        (StackMapTableAttribute {
            number_of_entries,
            entries,
        })
    )
}

pub fn exceptions_attribute_parser(input: &[u8]) -> IResult<&[u8], ExceptionsAttribute> {
    do_parse!(input,
        exception_table_length: be_u16 >>
        exception_table: count!(be_u16, exception_table_length as usize) >>
        (ExceptionsAttribute {
        exception_table_length: exception_table_length,
        exception_table: exception_table,
        })
    )
}

pub fn constant_value_attribute_parser(input: &[u8]) -> IResult<&[u8], ConstantValueAttribute> {
    do_parse!(input,
        constant_value_index: be_u16 >>
        (ConstantValueAttribute {
            constant_value_index: constant_value_index,
        })
    )
}
<commit_msg>Stop co-opting ErrorKind::Alt<commit_after>use nom::{
  be_u8, be_u16, be_u32,
  IResult,
  ErrorKind,
};

use attribute_info::*;
use attribute_info::types::StackMapFrame::*;

pub fn attribute_parser(input: &[u8]) -> IResult<&[u8], AttributeInfo> {
    do_parse!(input,
        attribute_name_index: be_u16 >>
        attribute_length: be_u32 >>
        info: take!(attribute_length)>>
        (AttributeInfo {
            attribute_name_index: attribute_name_index,
            attribute_length: attribute_length,
            info: info.to_owned(),
        })
    )
}

pub fn exception_entry_parser(input: &[u8]) -> IResult<&[u8], ExceptionEntry> {
    do_parse!(input,
        start_pc: be_u16 >>
        end_pc: be_u16 >>
        handler_pc: be_u16 >>
        catch_type: be_u16>>
        (ExceptionEntry {
            start_pc: start_pc,
            end_pc: end_pc,
            handler_pc: handler_pc,
            catch_type: catch_type,
        })
    )
}

pub fn code_attribute_parser(input: &[u8]) -> IResult<&[u8], CodeAttribute> {
    do_parse!(input,
        max_stack: be_u16 >>
        max_locals: be_u16 >>
        code_length: be_u32 >>
        code: take!(code_length) >>
        exception_table_length: be_u16 >>
        exception_table: count!(exception_entry_parser, exception_table_length as usize) >>
        attributes_count: be_u16 >>
        attributes: count!(attribute_parser, attributes_count as usize) >>
        (CodeAttribute {
            max_stack: max_stack,
            max_locals: max_locals,
            code_length: code_length,
            code: code.to_owned(),
            exception_table_length: exception_table_length,
            exception_table: exception_table,
            attributes_count: attributes_count,
            attributes: attributes,
        })
    )
}

fn same_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    value!(input, SameFrame { frame_type })
}

fn verification_type(v: &u8) -> Option<VerificationTypeInfo> {
    use self::VerificationTypeInfo::*;
    match *v {
        0 => Some(Top),
        1 => Some(Integer),
        2 => Some(Float),
        3 => Some(Double),
        4 => Some(Long),
        5 => Some(Null),
        6 => Some(UninitializedThis),
        7 => Some(Object),
        8 => Some(Uninitialized),
        _ => None,
    }
}

fn verification_type_parser(input: &[u8]) -> IResult<&[u8], VerificationTypeInfo> {
    match verification_type(&input[0]) {
        Some(x) => IResult::Done(&input[1..], x),
        _ => IResult::Error(error_position!(ErrorKind::Custom(1), input)),
    }
}

fn same_locals_1_stack_item_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        stack: verification_type_parser >>
        (SameLocals1StackItemFrame { frame_type, stack })
    )
}

fn same_locals_1_stack_item_frame_extended_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        offset_delta: be_u16 >>
        stack: verification_type_parser >>
        (SameLocals1StackItemFrameExtended { frame_type, offset_delta, stack })
    )
}

fn chop_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        offset_delta: be_u16 >>
        (ChopFrame { frame_type, offset_delta })
    )
}

fn same_frame_extended_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        offset_delta: be_u16 >>
        (SameFrameExtended { frame_type, offset_delta })
    )
}

fn append_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        offset_delta: be_u16 >>
        locals: count!(verification_type_parser, (frame_type - 251) as usize) >>
        (AppendFrame { frame_type, offset_delta, locals })
    )
}

fn full_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        offset_delta: be_u16 >>
        number_of_locals: be_u16 >>
        locals: count!(verification_type_parser, number_of_locals as usize) >>
        number_of_stack_items: be_u16 >>
        stack: count!(verification_type_parser, number_of_stack_items as usize) >>
        (FullFrame {
            frame_type,
            offset_delta,
            number_of_locals,
            locals,
            number_of_stack_items,
            stack,
        })
    )
}

fn stack_frame_parser(input: &[u8], frame_type: u8) -> IResult<&[u8], StackMapFrame> {
    match frame_type {
          0... 63 => same_frame_parser(input, frame_type),
         64...127 => same_locals_1_stack_item_frame_parser(input, frame_type),
        247       => same_locals_1_stack_item_frame_extended_parser(input, frame_type),
        248...250 => chop_frame_parser(input, frame_type),
        251       => same_frame_extended_parser(input, frame_type),
        252...254 => append_frame_parser(input, frame_type),
        255       => full_frame_parser(input, frame_type),
        _ => IResult::Error(error_position!(ErrorKind::Custom(2), input)),
    }
}

fn stack_map_frame_entry_parser(input: &[u8]) -> IResult<&[u8], StackMapFrame> {
    do_parse!(input,
        frame_type: be_u8 >>
        stack_frame: apply!(stack_frame_parser, frame_type) >>
        (stack_frame)
    )
}

pub fn stack_map_table_attribute_parser(input: &[u8]) -> IResult<&[u8], StackMapTableAttribute> {
    do_parse!(input,
        number_of_entries: be_u16 >>
        entries: count!(stack_map_frame_entry_parser, number_of_entries as usize) >>
        (StackMapTableAttribute {
            number_of_entries,
            entries,
        })
    )
}

pub fn exceptions_attribute_parser(input: &[u8]) -> IResult<&[u8], ExceptionsAttribute> {
    do_parse!(input,
        exception_table_length: be_u16 >>
        exception_table: count!(be_u16, exception_table_length as usize) >>
        (ExceptionsAttribute {
        exception_table_length: exception_table_length,
        exception_table: exception_table,
        })
    )
}

pub fn constant_value_attribute_parser(input: &[u8]) -> IResult<&[u8], ConstantValueAttribute> {
    do_parse!(input,
        constant_value_index: be_u16 >>
        (ConstantValueAttribute {
            constant_value_index: constant_value_index,
        })
    )
}
<|endoftext|>


<commit_before>//! Audit log types for administrative actions within guilds.

use std::collections::HashMap;
use std::mem::transmute;

use serde::de::{self, Deserializer};
use serde::ser::{Serialize, Serializer};

mod change;
mod utils;

pub use change::{AffectedRole, Change, EntityType};
use utils::{optional_string, users, webhooks};

use crate::model::prelude::*;

/// Determines the action that was done on a target.
#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
pub enum Action {
    GuildUpdate,
    Channel(ChannelAction),
    ChannelOverwrite(ChannelOverwriteAction),
    Member(MemberAction),
    Role(RoleAction),
    Invite(InviteAction),
    Webhook(WebhookAction),
    Emoji(EmojiAction),
    Message(MessageAction),
    Integration(IntegrationAction),
    StageInstance(StageInstanceAction),
    Sticker(StickerAction),
    Thread(ThreadAction),
}

impl Action {
    pub fn num(self) -> u8 {
        match self {
            Action::GuildUpdate => 1,
            Action::Channel(x) => x as u8,
            Action::ChannelOverwrite(x) => x as u8,
            Action::Member(x) => x as u8,
            Action::Role(x) => x as u8,
            Action::Invite(x) => x as u8,
            Action::Webhook(x) => x as u8,
            Action::Emoji(x) => x as u8,
            Action::Message(x) => x as u8,
            Action::Integration(x) => x as u8,
            Action::StageInstance(x) => x as u8,
            Action::Sticker(x) => x as u8,
            Action::Thread(x) => x as u8,
        }
    }

    pub fn from_value(value: u8) -> Option<Action> {
        let action = match value {
            1 => Action::GuildUpdate,
            10..=12 => Action::Channel(unsafe { transmute(value) }),
            13..=15 => Action::ChannelOverwrite(unsafe { transmute(value) }),
            20..=28 => 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..=75 => Action::Message(unsafe { transmute(value) }),
            80..=82 => Action::Integration(unsafe { transmute(value) }),
            83..=85 => Action::StageInstance(unsafe { transmute(value) }),
            90..=92 => Action::Sticker(unsafe { transmute(value) }),
            110..=112 => Action::Thread(unsafe { transmute(value) }),
            _ => return None,
        };

        Some(action)
    }
}

impl<'de> Deserialize<'de> for Action {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
        let value = u8::deserialize(deserializer)?;
        Action::from_value(value)
            .ok_or_else(|| de::Error::custom(format!("Unexpected action number: {}", value)))
    }
}

impl Serialize for Action {
    fn serialize<S: Serializer>(&self, serializer: S) -> StdResult<S::Ok, S::Error> {
        serializer.serialize_u8(self.num())
    }
}

#[deprecated(note = "use `ChannelAction`")]
pub type ActionChannel = ChannelAction;

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

#[deprecated(note = "use `ChannelOverwriteAction`")]
pub type ActionChannelOverwrite = ChannelOverwriteAction;

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

#[deprecated(note = "use `MemberAction`")]
pub type ActionMember = MemberAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum MemberAction {
    Kick = 20,
    Prune = 21,
    BanAdd = 22,
    BanRemove = 23,
    Update = 24,
    RoleUpdate = 25,
    MemberMove = 26,
    MemberDisconnect = 27,
    BotAdd = 28,
}

#[deprecated(note = "use `RoleAction`")]
pub type ActionRole = RoleAction;

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

#[deprecated(note = "use `InviteAction`")]
pub type ActionInvite = InviteAction;

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

#[deprecated(note = "use `WebhookAction`")]
pub type ActionWebhook = WebhookAction;

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

#[deprecated(note = "use `EmojiAction`")]
pub type ActionEmoji = EmojiAction;

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

#[deprecated(note = "use `MessageAction`")]
pub type ActionMessage = MessageAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum MessageAction {
    Delete = 72,
    BulkDelete = 73,
    Pin = 74,
    Unpin = 75,
}

#[deprecated(note = "use `IntegrationAction`")]
pub type ActionIntegration = IntegrationAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum IntegrationAction {
    Create = 80,
    Update = 81,
    Delete = 82,
}

#[deprecated(note = "use `StageInstanceAction`")]
pub type ActionStageInstance = StageInstanceAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum StageInstanceAction {
    Create = 83,
    Update = 84,
    Delete = 85,
}

#[deprecated(note = "use `StickerAction`")]
pub type ActionSticker = StickerAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum StickerAction {
    Create = 90,
    Update = 91,
    Delete = 92,
}

#[deprecated(note = "use `ThreadAction`")]
pub type ActionThread = ThreadAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum ThreadAction {
    Create = 110,
    Update = 111,
    Delete = 112,
}

#[derive(Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct AuditLogs {
    #[serde(rename = "audit_log_entries")]
    pub entries: Vec<AuditLogEntry>,
    #[serde(with = "users")]
    pub users: HashMap<UserId, User>,
    #[serde(with = "webhooks")]
    pub webhooks: HashMap<WebhookId, Webhook>,
}

#[derive(Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct AuditLogEntry {
    /// Determines to what entity an [`Self::action`] was used on.
    #[serde(with = "optional_string")]
    pub target_id: Option<u64>,
    /// Determines what action was done on a [`Self::target_id`]
    #[serde(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 associated with this entry.
    pub options: Option<Options>,
}

#[derive(Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct Options {
    /// Number of days after which inactive members were kicked.
    #[serde(default, with = "optional_string")]
    pub delete_member_days: Option<u64>,
    /// Number of members removed by the prune
    #[serde(default, with = "optional_string")]
    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 = "optional_string")]
    pub count: Option<u64>,
    /// Id of the overwritten entity
    #[serde(default)]
    pub id: Option<GenericId>,
    /// Type of overwritten entity ("member" or "role").
    #[serde(default, rename = "type")]
    pub kind: Option<String>,
    /// Message that was pinned or unpinned.
    #[serde(default)]
    pub message_id: Option<MessageId>,
    /// Name of the role if type is "role"
    #[serde(default)]
    pub role_name: Option<String>,
}

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

    #[test]
    fn action_value() {
        macro_rules! assert_action {
            ($action:pat, $num:literal) => {{
                let a = Action::from_value($num).expect("invalid action value");
                assert!(matches!(a, $action), "{:?} didn't match the variant", a);
                assert_eq!(a.num(), $num);
            }};
        }

        assert_action!(Action::GuildUpdate, 1);
        assert_action!(Action::Channel(ChannelAction::Create), 10);
        assert_action!(Action::Channel(ChannelAction::Update), 11);
        assert_action!(Action::Channel(ChannelAction::Delete), 12);
        assert_action!(Action::ChannelOverwrite(ChannelOverwriteAction::Create), 13);
        assert_action!(Action::ChannelOverwrite(ChannelOverwriteAction::Update), 14);
        assert_action!(Action::ChannelOverwrite(ChannelOverwriteAction::Delete), 15);
        assert_action!(Action::Member(MemberAction::Kick), 20);
        assert_action!(Action::Member(MemberAction::Prune), 21);
        assert_action!(Action::Member(MemberAction::BanAdd), 22);
        assert_action!(Action::Member(MemberAction::BanRemove), 23);
        assert_action!(Action::Member(MemberAction::Update), 24);
        assert_action!(Action::Member(MemberAction::RoleUpdate), 25);
        assert_action!(Action::Member(MemberAction::MemberMove), 26);
        assert_action!(Action::Member(MemberAction::MemberDisconnect), 27);
        assert_action!(Action::Member(MemberAction::BotAdd), 28);
        assert_action!(Action::Role(RoleAction::Create), 30);
        assert_action!(Action::Role(RoleAction::Update), 31);
        assert_action!(Action::Role(RoleAction::Delete), 32);
        assert_action!(Action::Invite(InviteAction::Create), 40);
        assert_action!(Action::Invite(InviteAction::Update), 41);
        assert_action!(Action::Invite(InviteAction::Delete), 42);
        assert_action!(Action::Webhook(WebhookAction::Create), 50);
        assert_action!(Action::Webhook(WebhookAction::Update), 51);
        assert_action!(Action::Webhook(WebhookAction::Delete), 52);
        assert_action!(Action::Emoji(EmojiAction::Create), 60);
        assert_action!(Action::Emoji(EmojiAction::Update), 61);
        assert_action!(Action::Emoji(EmojiAction::Delete), 62);
        assert_action!(Action::Message(MessageAction::Delete), 72);
        assert_action!(Action::Message(MessageAction::BulkDelete), 73);
        assert_action!(Action::Message(MessageAction::Pin), 74);
        assert_action!(Action::Message(MessageAction::Unpin), 75);
        assert_action!(Action::Integration(IntegrationAction::Create), 80);
        assert_action!(Action::Integration(IntegrationAction::Update), 81);
        assert_action!(Action::Integration(IntegrationAction::Delete), 82);
        assert_action!(Action::StageInstance(StageInstanceAction::Create), 83);
        assert_action!(Action::StageInstance(StageInstanceAction::Update), 84);
        assert_action!(Action::StageInstance(StageInstanceAction::Delete), 85);
        assert_action!(Action::Sticker(StickerAction::Create), 90);
        assert_action!(Action::Sticker(StickerAction::Update), 91);
        assert_action!(Action::Sticker(StickerAction::Delete), 92);
        assert_action!(Action::Thread(ThreadAction::Create), 110);
        assert_action!(Action::Thread(ThreadAction::Update), 111);
        assert_action!(Action::Thread(ThreadAction::Delete), 112);
    }
}
<commit_msg>Add new enum variant to `audit_log::Action` to represent unknown values (#1875)<commit_after>//! Audit log types for administrative actions within guilds.

use std::collections::HashMap;
use std::mem::transmute;

use serde::de::Deserializer;
use serde::ser::{Serialize, Serializer};

mod change;
mod utils;

pub use change::{AffectedRole, Change, EntityType};
use utils::{optional_string, users, webhooks};

use crate::model::prelude::*;

/// Determines the action that was done on a target.
#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
pub enum Action {
    GuildUpdate,
    Channel(ChannelAction),
    ChannelOverwrite(ChannelOverwriteAction),
    Member(MemberAction),
    Role(RoleAction),
    Invite(InviteAction),
    Webhook(WebhookAction),
    Emoji(EmojiAction),
    Message(MessageAction),
    Integration(IntegrationAction),
    StageInstance(StageInstanceAction),
    Sticker(StickerAction),
    Thread(ThreadAction),
    Unknown(u8),
}

impl Action {
    pub fn num(self) -> u8 {
        match self {
            Action::GuildUpdate => 1,
            Action::Channel(x) => x as u8,
            Action::ChannelOverwrite(x) => x as u8,
            Action::Member(x) => x as u8,
            Action::Role(x) => x as u8,
            Action::Invite(x) => x as u8,
            Action::Webhook(x) => x as u8,
            Action::Emoji(x) => x as u8,
            Action::Message(x) => x as u8,
            Action::Integration(x) => x as u8,
            Action::StageInstance(x) => x as u8,
            Action::Sticker(x) => x as u8,
            Action::Thread(x) => x as u8,
            Action::Unknown(x) => x,
        }
    }

    // TODO: Change function to `from_value(u8) -> Action` in the next version and return
    // `Action::Unknown(u8)` for unknown values.
    pub fn from_value(value: u8) -> Option<Action> {
        let action = match value {
            1 => Action::GuildUpdate,
            10..=12 => Action::Channel(unsafe { transmute(value) }),
            13..=15 => Action::ChannelOverwrite(unsafe { transmute(value) }),
            20..=28 => 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..=75 => Action::Message(unsafe { transmute(value) }),
            80..=82 => Action::Integration(unsafe { transmute(value) }),
            83..=85 => Action::StageInstance(unsafe { transmute(value) }),
            90..=92 => Action::Sticker(unsafe { transmute(value) }),
            110..=112 => Action::Thread(unsafe { transmute(value) }),
            _ => return None,
        };

        Some(action)
    }
}

impl<'de> Deserialize<'de> for Action {
    fn deserialize<D: Deserializer<'de>>(deserializer: D) -> StdResult<Self, D::Error> {
        let value = u8::deserialize(deserializer)?;
        Ok(Action::from_value(value).unwrap_or(Action::Unknown(value)))
    }
}

impl Serialize for Action {
    fn serialize<S: Serializer>(&self, serializer: S) -> StdResult<S::Ok, S::Error> {
        serializer.serialize_u8(self.num())
    }
}

#[deprecated(note = "use `ChannelAction`")]
pub type ActionChannel = ChannelAction;

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

#[deprecated(note = "use `ChannelOverwriteAction`")]
pub type ActionChannelOverwrite = ChannelOverwriteAction;

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

#[deprecated(note = "use `MemberAction`")]
pub type ActionMember = MemberAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum MemberAction {
    Kick = 20,
    Prune = 21,
    BanAdd = 22,
    BanRemove = 23,
    Update = 24,
    RoleUpdate = 25,
    MemberMove = 26,
    MemberDisconnect = 27,
    BotAdd = 28,
}

#[deprecated(note = "use `RoleAction`")]
pub type ActionRole = RoleAction;

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

#[deprecated(note = "use `InviteAction`")]
pub type ActionInvite = InviteAction;

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

#[deprecated(note = "use `WebhookAction`")]
pub type ActionWebhook = WebhookAction;

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

#[deprecated(note = "use `EmojiAction`")]
pub type ActionEmoji = EmojiAction;

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

#[deprecated(note = "use `MessageAction`")]
pub type ActionMessage = MessageAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum MessageAction {
    Delete = 72,
    BulkDelete = 73,
    Pin = 74,
    Unpin = 75,
}

#[deprecated(note = "use `IntegrationAction`")]
pub type ActionIntegration = IntegrationAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum IntegrationAction {
    Create = 80,
    Update = 81,
    Delete = 82,
}

#[deprecated(note = "use `StageInstanceAction`")]
pub type ActionStageInstance = StageInstanceAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum StageInstanceAction {
    Create = 83,
    Update = 84,
    Delete = 85,
}

#[deprecated(note = "use `StickerAction`")]
pub type ActionSticker = StickerAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum StickerAction {
    Create = 90,
    Update = 91,
    Delete = 92,
}

#[deprecated(note = "use `ThreadAction`")]
pub type ActionThread = ThreadAction;

#[derive(Copy, Clone, Debug)]
#[non_exhaustive]
#[repr(u8)]
pub enum ThreadAction {
    Create = 110,
    Update = 111,
    Delete = 112,
}

#[derive(Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct AuditLogs {
    #[serde(rename = "audit_log_entries")]
    pub entries: Vec<AuditLogEntry>,
    #[serde(with = "users")]
    pub users: HashMap<UserId, User>,
    #[serde(with = "webhooks")]
    pub webhooks: HashMap<WebhookId, Webhook>,
}

#[derive(Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct AuditLogEntry {
    /// Determines to what entity an [`Self::action`] was used on.
    #[serde(with = "optional_string")]
    pub target_id: Option<u64>,
    /// Determines what action was done on a [`Self::target_id`]
    #[serde(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 associated with this entry.
    pub options: Option<Options>,
}

#[derive(Debug, Deserialize, Serialize)]
#[non_exhaustive]
pub struct Options {
    /// Number of days after which inactive members were kicked.
    #[serde(default, with = "optional_string")]
    pub delete_member_days: Option<u64>,
    /// Number of members removed by the prune
    #[serde(default, with = "optional_string")]
    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 = "optional_string")]
    pub count: Option<u64>,
    /// Id of the overwritten entity
    #[serde(default)]
    pub id: Option<GenericId>,
    /// Type of overwritten entity ("member" or "role").
    #[serde(default, rename = "type")]
    pub kind: Option<String>,
    /// Message that was pinned or unpinned.
    #[serde(default)]
    pub message_id: Option<MessageId>,
    /// Name of the role if type is "role"
    #[serde(default)]
    pub role_name: Option<String>,
}

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

    #[test]
    fn action_value() {
        macro_rules! assert_action {
            ($action:pat, $num:literal) => {{
                let a = Action::from_value($num).expect("invalid action value");
                assert!(matches!(a, $action), "{:?} didn't match the variant", a);
                assert_eq!(a.num(), $num);
            }};
        }

        assert_action!(Action::GuildUpdate, 1);
        assert_action!(Action::Channel(ChannelAction::Create), 10);
        assert_action!(Action::Channel(ChannelAction::Update), 11);
        assert_action!(Action::Channel(ChannelAction::Delete), 12);
        assert_action!(Action::ChannelOverwrite(ChannelOverwriteAction::Create), 13);
        assert_action!(Action::ChannelOverwrite(ChannelOverwriteAction::Update), 14);
        assert_action!(Action::ChannelOverwrite(ChannelOverwriteAction::Delete), 15);
        assert_action!(Action::Member(MemberAction::Kick), 20);
        assert_action!(Action::Member(MemberAction::Prune), 21);
        assert_action!(Action::Member(MemberAction::BanAdd), 22);
        assert_action!(Action::Member(MemberAction::BanRemove), 23);
        assert_action!(Action::Member(MemberAction::Update), 24);
        assert_action!(Action::Member(MemberAction::RoleUpdate), 25);
        assert_action!(Action::Member(MemberAction::MemberMove), 26);
        assert_action!(Action::Member(MemberAction::MemberDisconnect), 27);
        assert_action!(Action::Member(MemberAction::BotAdd), 28);
        assert_action!(Action::Role(RoleAction::Create), 30);
        assert_action!(Action::Role(RoleAction::Update), 31);
        assert_action!(Action::Role(RoleAction::Delete), 32);
        assert_action!(Action::Invite(InviteAction::Create), 40);
        assert_action!(Action::Invite(InviteAction::Update), 41);
        assert_action!(Action::Invite(InviteAction::Delete), 42);
        assert_action!(Action::Webhook(WebhookAction::Create), 50);
        assert_action!(Action::Webhook(WebhookAction::Update), 51);
        assert_action!(Action::Webhook(WebhookAction::Delete), 52);
        assert_action!(Action::Emoji(EmojiAction::Create), 60);
        assert_action!(Action::Emoji(EmojiAction::Update), 61);
        assert_action!(Action::Emoji(EmojiAction::Delete), 62);
        assert_action!(Action::Message(MessageAction::Delete), 72);
        assert_action!(Action::Message(MessageAction::BulkDelete), 73);
        assert_action!(Action::Message(MessageAction::Pin), 74);
        assert_action!(Action::Message(MessageAction::Unpin), 75);
        assert_action!(Action::Integration(IntegrationAction::Create), 80);
        assert_action!(Action::Integration(IntegrationAction::Update), 81);
        assert_action!(Action::Integration(IntegrationAction::Delete), 82);
        assert_action!(Action::StageInstance(StageInstanceAction::Create), 83);
        assert_action!(Action::StageInstance(StageInstanceAction::Update), 84);
        assert_action!(Action::StageInstance(StageInstanceAction::Delete), 85);
        assert_action!(Action::Sticker(StickerAction::Create), 90);
        assert_action!(Action::Sticker(StickerAction::Update), 91);
        assert_action!(Action::Sticker(StickerAction::Delete), 92);
        assert_action!(Action::Thread(ThreadAction::Create), 110);
        assert_action!(Action::Thread(ThreadAction::Update), 111);
        assert_action!(Action::Thread(ThreadAction::Delete), 112);

        // TODO: use `assert_action!` when `Action::from_value` returns `Action::Unknown`
        assert_eq!(Action::Unknown(234).num(), 234);
    }

    #[test]
    fn action_serde() {
        use serde_json::json;

        #[derive(Debug, Deserialize, Serialize)]
        struct T {
            action: Action,
        }

        let value = json!({
            "action": 234,
        });

        let value = serde_json::from_value::<T>(value).unwrap();
        assert_eq!(value.action.num(), 234);

        assert!(matches!(value.action, Action::Unknown(234)));
    }
}
<|endoftext|>


<commit_before>//! This module provides the Torrance Sparrow microfacet BRDF, see
//! [Walter et al. 07](https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf)
//! for details.

use std::f32;
use enum_set::EnumSet;

use linalg::{self, Vector};
use film::Colorf;
use bxdf::{self, BxDF, BxDFType};
use bxdf::fresnel::Fresnel;
use bxdf::microfacet::{MicrofacetDistribution};

/// Struct providing the Torrance Sparrow BRDF, implemented as described in
/// [Walter et al. 07](https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf)
pub struct TorranceSparrow {
    reflectance: Colorf,
    fresnel: Box<Fresnel + Send + Sync>,
    /// Microfacet distribution describing the structure of the microfacets of
    /// the material
    microfacet: Box<MicrofacetDistribution + Send + Sync>,
}

impl TorranceSparrow {
    /// Create a new Torrance Sparrow microfacet BRDF
    pub fn new(c: &Colorf, fresnel: Box<Fresnel + Send + Sync>,
               microfacet: Box<MicrofacetDistribution + Send + Sync>) -> TorranceSparrow {
        TorranceSparrow { reflectance: *c, fresnel: fresnel, microfacet: microfacet }
    }
}

impl BxDF for TorranceSparrow {
    fn bxdf_type(&self) -> EnumSet<BxDFType> {
        let mut e = EnumSet::new();
        e.insert(BxDFType::Glossy);
        e.insert(BxDFType::Reflection);
        e
    }
    fn eval(&self, w_o: &Vector, w_i: &Vector) -> Colorf {
        let cos_to = f32::abs(bxdf::cos_theta(w_o));
        let cos_ti = f32::abs(bxdf::cos_theta(w_i));
        if cos_to == 0.0 || cos_ti == 0.0 {
            return Colorf::new(0.0, 0.0, 0.0)
        }
        let mut w_h = *w_i + *w_o;
        if w_h.x == 0.0 && w_h.y == 0.0 && w_h.z == 0.0 {
            return Colorf::new(0.0, 0.0, 0.0)
        }
        w_h = w_h.normalized();
        let d = self.microfacet.normal_distribution(&w_h);
        let f = self.fresnel.fresnel(linalg::dot(w_i, &w_h));
        let g = self.microfacet.shadowing_masking(w_i, w_o, &w_h);
        (self.reflectance * f * d * g / (4.0 * cos_ti * cos_to))
    }
    fn sample(&self, w_o: &Vector, samples: &(f32, f32)) -> (Colorf, Vector, f32) {
        let mut w_h = self.microfacet.sample(w_o, samples);
        if !bxdf::same_hemisphere(w_o, &w_h) {
            w_h = -w_h;
        }
        let w_i = linalg::reflect(w_o, &w_h);
        if !bxdf::same_hemisphere(w_o, &w_i) {
            (Colorf::black(), Vector::broadcast(0.0), 0.0)
        } else {
            // This term is p_o(o) in eq. 38 of Walter et al's 07 paper and is for reflection so
            // we use the Jacobian for reflection, eq. 14
            let jacobian = 1.0 / (4.0 * f32::abs(linalg::dot(w_o, &w_h)));
            let pdf = self.microfacet.pdf(&w_h) * jacobian;
            (self.eval(w_o, &w_i), w_i, pdf)
        }
    }
    fn pdf(&self, w_o: &Vector, w_i: &Vector) -> f32 {
        if !bxdf::same_hemisphere(w_o, w_i) {
            0.0
        } else {
            let w_h = *w_o + *w_i;
            if w_h.x == 0.0 && w_h.y == 0.0 && w_h.z == 0.0 {
                0.0
            } else {
                // This term is p_o(o) in eq. 38 of Walter et al's 07 paper and is for reflection so
                // we use the Jacobian for reflection, eq. 14
                let jacobian = 1.0 / (4.0 * f32::abs(linalg::dot(w_o, &w_h)));
                self.microfacet.pdf(&w_h.normalized()) * jacobian
            }
        }
    }
}

<commit_msg>Half vector should be normalized<commit_after>//! This module provides the Torrance Sparrow microfacet BRDF, see
//! [Walter et al. 07](https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf)
//! for details.

use std::f32;
use enum_set::EnumSet;

use linalg::{self, Vector};
use film::Colorf;
use bxdf::{self, BxDF, BxDFType};
use bxdf::fresnel::Fresnel;
use bxdf::microfacet::{MicrofacetDistribution};

/// Struct providing the Torrance Sparrow BRDF, implemented as described in
/// [Walter et al. 07](https://www.cs.cornell.edu/~srm/publications/EGSR07-btdf.pdf)
pub struct TorranceSparrow {
    reflectance: Colorf,
    fresnel: Box<Fresnel + Send + Sync>,
    /// Microfacet distribution describing the structure of the microfacets of
    /// the material
    microfacet: Box<MicrofacetDistribution + Send + Sync>,
}

impl TorranceSparrow {
    /// Create a new Torrance Sparrow microfacet BRDF
    pub fn new(c: &Colorf, fresnel: Box<Fresnel + Send + Sync>,
               microfacet: Box<MicrofacetDistribution + Send + Sync>) -> TorranceSparrow {
        TorranceSparrow { reflectance: *c, fresnel: fresnel, microfacet: microfacet }
    }
}

impl BxDF for TorranceSparrow {
    fn bxdf_type(&self) -> EnumSet<BxDFType> {
        let mut e = EnumSet::new();
        e.insert(BxDFType::Glossy);
        e.insert(BxDFType::Reflection);
        e
    }
    fn eval(&self, w_o: &Vector, w_i: &Vector) -> Colorf {
        let cos_to = f32::abs(bxdf::cos_theta(w_o));
        let cos_ti = f32::abs(bxdf::cos_theta(w_i));
        if cos_to == 0.0 || cos_ti == 0.0 {
            return Colorf::new(0.0, 0.0, 0.0)
        }
        let mut w_h = *w_i + *w_o;
        if w_h.x == 0.0 && w_h.y == 0.0 && w_h.z == 0.0 {
            return Colorf::new(0.0, 0.0, 0.0)
        }
        w_h = w_h.normalized();
        let d = self.microfacet.normal_distribution(&w_h);
        let f = self.fresnel.fresnel(linalg::dot(w_i, &w_h));
        let g = self.microfacet.shadowing_masking(w_i, w_o, &w_h);
        (self.reflectance * f * d * g / (4.0 * cos_ti * cos_to))
    }
    fn sample(&self, w_o: &Vector, samples: &(f32, f32)) -> (Colorf, Vector, f32) {
        let mut w_h = self.microfacet.sample(w_o, samples);
        if !bxdf::same_hemisphere(w_o, &w_h) {
            w_h = -w_h;
        }
        let w_i = linalg::reflect(w_o, &w_h);
        if !bxdf::same_hemisphere(w_o, &w_i) {
            (Colorf::black(), Vector::broadcast(0.0), 0.0)
        } else {
            // This term is p_o(o) in eq. 38 of Walter et al's 07 paper and is for reflection so
            // we use the Jacobian for reflection, eq. 14
            let jacobian = 1.0 / (4.0 * f32::abs(linalg::dot(w_o, &w_h)));
            let pdf = self.microfacet.pdf(&w_h) * jacobian;
            (self.eval(w_o, &w_i), w_i, pdf)
        }
    }
    fn pdf(&self, w_o: &Vector, w_i: &Vector) -> f32 {
        if !bxdf::same_hemisphere(w_o, w_i) {
            0.0
        } else {
            let mut w_h = *w_o + *w_i;
            if w_h.x == 0.0 && w_h.y == 0.0 && w_h.z == 0.0 {
                0.0
            } else {
                w_h = w_h.normalized();
                // This term is p_o(o) in eq. 38 of Walter et al's 07 paper and is for reflection so
                // we use the Jacobian for reflection, eq. 14
                let jacobian = 1.0 / (4.0 * f32::abs(linalg::dot(w_o, &w_h)));
                self.microfacet.pdf(&w_h.normalized()) * jacobian
            }
        }
    }
}

<|endoftext|>


<commit_before>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![crate_id = "github.com/mozilla/servo"]
#![comment = "The Servo Parallel Browser Project"]
#![license = "MPL"]

#![feature(globs, macro_rules, phase, thread_local)]

#[phase(syntax, link)]
extern crate log;

extern crate alert;
extern crate azure;
extern crate geom;
extern crate gfx;
#[cfg(not(target_os="android"))]
extern crate glfw;
#[cfg(target_os="android")]
extern crate glut;
extern crate js;
extern crate layers;
extern crate opengles;
extern crate png;
extern crate rustuv;
extern crate script;
#[phase(syntax)]
extern crate servo_macros = "macros";
extern crate servo_net = "net";
extern crate servo_msg = "msg";
#[phase(syntax, link)]
extern crate servo_util = "util";
extern crate style;
extern crate sharegl;
extern crate stb_image;

extern crate collections;
extern crate green;
extern crate libc;
extern crate native;
extern crate serialize;
extern crate sync;
extern crate time;
extern crate url;

#[cfg(target_os="macos")]
extern crate core_graphics;
#[cfg(target_os="macos")]
extern crate core_text;

#[cfg(not(test))]
use compositing::{CompositorChan, CompositorTask};
#[cfg(not(test))]
use constellation::Constellation;
#[cfg(not(test))]
use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg};

#[cfg(not(test))]
use servo_net::image_cache_task::{ImageCacheTask, SyncImageCacheTask};
#[cfg(not(test))]
use servo_net::resource_task::ResourceTask;
#[cfg(not(test))]
use servo_util::time::Profiler;

#[cfg(not(test))]
use servo_util::opts;
#[cfg(not(test))]
use servo_util::url::parse_url;

#[cfg(not(test), not(target_os="android"))]
use std::os;
#[cfg(not(test), target_os="android")]
use std::str;
#[cfg(not(test))]
use std::task::TaskOpts;
#[cfg(not(test))]
use url::Url;

#[path="compositing/compositor_task.rs"]
pub mod compositing;

pub mod css {
    mod node_util;

    pub mod select;
    pub mod matching;
    pub mod node_style;
}

pub mod constellation;
pub mod pipeline;

pub mod layout {
    pub mod block;
    pub mod box_;
    pub mod construct;
    pub mod context;
    pub mod floats;
    pub mod flow;
    pub mod flow_list;
    pub mod layout_task;
    pub mod inline;
    pub mod model;
    pub mod parallel;
    pub mod table_wrapper;
    pub mod table;
    pub mod table_caption;
    pub mod table_colgroup;
    pub mod table_rowgroup;
    pub mod table_row;
    pub mod table_cell;
    pub mod text;
    pub mod util;
    pub mod incremental;
    pub mod wrapper;
    pub mod extra;
}

pub mod windowing;

#[path="platform/mod.rs"]
pub mod platform;

#[cfg(not(test), target_os="linux")]
#[cfg(not(test), target_os="macos")]
#[start]
#[allow(dead_code)]
fn start(argc: int, argv: **u8) -> int {
    native::start(argc, argv, proc() {
        opts::from_cmdline_args(os::args()).map(run);
    })
}

#[cfg(not(test), target_os="android")]
#[no_mangle]
#[allow(dead_code)]
pub extern "C" fn android_start(argc: int, argv: **u8) -> int {
    native::start(argc, argv, proc() {
        let mut args: Vec<~str> = vec!();
        for i in range(0u, argc as uint) {
            unsafe {
                args.push(str::raw::from_c_str(*argv.offset(i as int) as *i8));
            }
        }

        let mut opts = opts::from_cmdline_args(args.as_slice());
        match opts {
            Some(mut o) => {
                // Always use CPU rendering on android.
                o.cpu_painting = true;
                run(o);
            },
            None => {}
        }
    })
}

#[cfg(not(test))]
fn run(opts: opts::Opts) {
    let mut pool_config = green::PoolConfig::new();
    pool_config.event_loop_factory = rustuv::event_loop;
    let mut pool = green::SchedPool::new(pool_config);

    let (compositor_port, compositor_chan) = CompositorChan::new();
    let profiler_chan = Profiler::create(opts.profiler_period);

    let opts_clone = opts.clone();
    let profiler_chan_clone = profiler_chan.clone();

    let (result_chan, result_port) = channel();
    pool.spawn(TaskOpts::new(), proc() {
        let opts = &opts_clone;
        // Create a Servo instance.
        let resource_task = ResourceTask();
        // If we are emitting an output file, then we need to block on
        // image load or we risk emitting an output file missing the
        // image.
        let image_cache_task = if opts.output_file.is_some() {
                SyncImageCacheTask(resource_task.clone())
            } else {
                ImageCacheTask(resource_task.clone())
            };
        let constellation_chan = Constellation::start(compositor_chan,
                                                      opts,
                                                      resource_task,
                                                      image_cache_task,
                                                      profiler_chan_clone);

        // Send the URL command to the constellation.
        for filename in opts.urls.iter() {
            let url = if filename.starts_with("data:") {
                // As a hack for easier command-line testing,
                // assume that data URLs are not URL-encoded.
                Url::new("data".to_owned(), None, "".to_owned(), None,
                    filename.slice_from(5).to_owned(), vec!(), None)
            } else {
                parse_url(*filename, None)
            };

            let ConstellationChan(ref chan) = constellation_chan;
            chan.send(InitLoadUrlMsg(url));
        }

        // Send the constallation Chan as the result
        result_chan.send(constellation_chan);
    });

    let constellation_chan = result_port.recv();

    debug!("preparing to enter main loop");
    CompositorTask::create(opts,
                           compositor_port,
                           constellation_chan,
                           profiler_chan);

    pool.shutdown();
}

<commit_msg>Fix file mode for servo.rs<commit_after>/* This Source Code Form is subject to the terms of the Mozilla Public
 * License, v. 2.0. If a copy of the MPL was not distributed with this
 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */

#![crate_id = "github.com/mozilla/servo"]
#![comment = "The Servo Parallel Browser Project"]
#![license = "MPL"]

#![feature(globs, macro_rules, phase, thread_local)]

#[phase(syntax, link)]
extern crate log;

extern crate alert;
extern crate azure;
extern crate geom;
extern crate gfx;
#[cfg(not(target_os="android"))]
extern crate glfw;
#[cfg(target_os="android")]
extern crate glut;
extern crate js;
extern crate layers;
extern crate opengles;
extern crate png;
extern crate rustuv;
extern crate script;
#[phase(syntax)]
extern crate servo_macros = "macros";
extern crate servo_net = "net";
extern crate servo_msg = "msg";
#[phase(syntax, link)]
extern crate servo_util = "util";
extern crate style;
extern crate sharegl;
extern crate stb_image;

extern crate collections;
extern crate green;
extern crate libc;
extern crate native;
extern crate serialize;
extern crate sync;
extern crate time;
extern crate url;

#[cfg(target_os="macos")]
extern crate core_graphics;
#[cfg(target_os="macos")]
extern crate core_text;

#[cfg(not(test))]
use compositing::{CompositorChan, CompositorTask};
#[cfg(not(test))]
use constellation::Constellation;
#[cfg(not(test))]
use servo_msg::constellation_msg::{ConstellationChan, InitLoadUrlMsg};

#[cfg(not(test))]
use servo_net::image_cache_task::{ImageCacheTask, SyncImageCacheTask};
#[cfg(not(test))]
use servo_net::resource_task::ResourceTask;
#[cfg(not(test))]
use servo_util::time::Profiler;

#[cfg(not(test))]
use servo_util::opts;
#[cfg(not(test))]
use servo_util::url::parse_url;

#[cfg(not(test), not(target_os="android"))]
use std::os;
#[cfg(not(test), target_os="android")]
use std::str;
#[cfg(not(test))]
use std::task::TaskOpts;
#[cfg(not(test))]
use url::Url;

#[path="compositing/compositor_task.rs"]
pub mod compositing;

pub mod css {
    mod node_util;

    pub mod select;
    pub mod matching;
    pub mod node_style;
}

pub mod constellation;
pub mod pipeline;

pub mod layout {
    pub mod block;
    pub mod box_;
    pub mod construct;
    pub mod context;
    pub mod floats;
    pub mod flow;
    pub mod flow_list;
    pub mod layout_task;
    pub mod inline;
    pub mod model;
    pub mod parallel;
    pub mod table_wrapper;
    pub mod table;
    pub mod table_caption;
    pub mod table_colgroup;
    pub mod table_rowgroup;
    pub mod table_row;
    pub mod table_cell;
    pub mod text;
    pub mod util;
    pub mod incremental;
    pub mod wrapper;
    pub mod extra;
}

pub mod windowing;

#[path="platform/mod.rs"]
pub mod platform;

#[cfg(not(test), target_os="linux")]
#[cfg(not(test), target_os="macos")]
#[start]
#[allow(dead_code)]
fn start(argc: int, argv: **u8) -> int {
    native::start(argc, argv, proc() {
        opts::from_cmdline_args(os::args()).map(run);
    })
}

#[cfg(not(test), target_os="android")]
#[no_mangle]
#[allow(dead_code)]
pub extern "C" fn android_start(argc: int, argv: **u8) -> int {
    native::start(argc, argv, proc() {
        let mut args: Vec<~str> = vec!();
        for i in range(0u, argc as uint) {
            unsafe {
                args.push(str::raw::from_c_str(*argv.offset(i as int) as *i8));
            }
        }

        let mut opts = opts::from_cmdline_args(args.as_slice());
        match opts {
            Some(mut o) => {
                // Always use CPU rendering on android.
                o.cpu_painting = true;
                run(o);
            },
            None => {}
        }
    })
}

#[cfg(not(test))]
fn run(opts: opts::Opts) {
    let mut pool_config = green::PoolConfig::new();
    pool_config.event_loop_factory = rustuv::event_loop;
    let mut pool = green::SchedPool::new(pool_config);

    let (compositor_port, compositor_chan) = CompositorChan::new();
    let profiler_chan = Profiler::create(opts.profiler_period);

    let opts_clone = opts.clone();
    let profiler_chan_clone = profiler_chan.clone();

    let (result_chan, result_port) = channel();
    pool.spawn(TaskOpts::new(), proc() {
        let opts = &opts_clone;
        // Create a Servo instance.
        let resource_task = ResourceTask();
        // If we are emitting an output file, then we need to block on
        // image load or we risk emitting an output file missing the
        // image.
        let image_cache_task = if opts.output_file.is_some() {
                SyncImageCacheTask(resource_task.clone())
            } else {
                ImageCacheTask(resource_task.clone())
            };
        let constellation_chan = Constellation::start(compositor_chan,
                                                      opts,
                                                      resource_task,
                                                      image_cache_task,
                                                      profiler_chan_clone);

        // Send the URL command to the constellation.
        for filename in opts.urls.iter() {
            let url = if filename.starts_with("data:") {
                // As a hack for easier command-line testing,
                // assume that data URLs are not URL-encoded.
                Url::new("data".to_owned(), None, "".to_owned(), None,
                    filename.slice_from(5).to_owned(), vec!(), None)
            } else {
                parse_url(*filename, None)
            };

            let ConstellationChan(ref chan) = constellation_chan;
            chan.send(InitLoadUrlMsg(url));
        }

        // Send the constallation Chan as the result
        result_chan.send(constellation_chan);
    });

    let constellation_chan = result_port.recv();

    debug!("preparing to enter main loop");
    CompositorTask::create(opts,
                           compositor_port,
                           constellation_chan,
                           profiler_chan);

    pool.shutdown();
}

<|endoftext|>


<commit_before>use super::Core;
use std::num::Wrapping;
use ram::ADDRBUS_MASK;

pub fn absolute_word(core: &mut Core) -> u32 {
	let ea = core.read_imm_i16() as u32;
	ea & ADDRBUS_MASK
}
pub fn absolute_long(core: &mut Core) -> u32 {
	let ea = core.read_imm_u32();
	ea & ADDRBUS_MASK
}
pub fn predecrement_ay_8(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	predecrement_8(core, reg_ndx)
}
pub fn postincrement_ay_8(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	postincrement_8(core, reg_ndx)
}
pub fn predecrement_ay_16(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	predecrement_16(core, reg_ndx)
}
pub fn postincrement_ay_16(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	postincrement_16(core, reg_ndx)
}
pub fn address_indirect_ay(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	core.dar[reg_ndx] & ADDRBUS_MASK
}
pub fn displacement_ay(core: &mut Core) -> u32 {
	let reg_val = core.dar[ir_ay!(core)];
	displacement(core, reg_val)
}
pub fn displacement_pc(core: &mut Core) -> u32 {
	let old_pc = core.pc;
	displacement(core, old_pc)
}
pub fn index_ay(core: &mut Core) -> u32 {
	let reg_val = core.dar[ir_ay!(core)];
	index(core, reg_val)
}
pub fn index_pc(core: &mut Core) -> u32 {
	let pc = core.pc;
	index(core, pc)
}
pub fn predecrement_ax_8(core: &mut Core) -> u32 {
	let reg_ndx = ir_ax!(core);
	predecrement_8(core, reg_ndx)
}
pub fn predecrement_ax_16(core: &mut Core) -> u32 {
	let reg_ndx = ir_ax!(core);
	predecrement_16(core, reg_ndx)
}

fn predecrement_8(core: &mut Core, reg_ndx: usize) -> u32 {
	// pre-decrement
	core.dar[reg_ndx] = (Wrapping(core.dar[reg_ndx]) - match reg_ndx {
		15 => Wrapping(2), // A7 is kept even
		 _ => Wrapping(1)
	}).0;
	core.dar[reg_ndx] & ADDRBUS_MASK
}
fn postincrement_8(core: &mut Core, reg_ndx: usize) -> u32 {
	// post-increment
	let ea = core.dar[reg_ndx];
	core.dar[reg_ndx] = (Wrapping(core.dar[reg_ndx]) + match reg_ndx {
		15 => Wrapping(2), // A7 is kept even
		 _ => Wrapping(1)
	}).0;
	ea & ADDRBUS_MASK
}
fn predecrement_16(core: &mut Core, reg_ndx: usize) -> u32 {
	// pre-decrement
	core.dar[reg_ndx] = (Wrapping(core.dar[reg_ndx]) - Wrapping(2)).0;
	core.dar[reg_ndx] & ADDRBUS_MASK
}
fn postincrement_16(core: &mut Core, reg_ndx: usize) -> u32 {
	// post-increment
	let ea = core.dar[reg_ndx];
	core.dar[reg_ndx] = (Wrapping(core.dar[reg_ndx]) + Wrapping(2)).0;
	ea & ADDRBUS_MASK
}
fn displacement(core: &mut Core, reg_val: u32) -> u32 {
	let displacement = core.read_imm_i16();
	let ea = (Wrapping(reg_val) + Wrapping(displacement as u32)).0;
	ea & ADDRBUS_MASK
}
// Brief Extension Word format (see M68000 PRM section 2.1)
const LONG_INDEX_MASK: u16 = 0x0800;
fn index(core: &mut Core, reg_val: u32) -> u32 {
	let extension = core.read_imm_u16();
	let xreg_ndx = (extension>>12) as usize;
	let xn = core.dar[xreg_ndx];
	let xn = if (extension & LONG_INDEX_MASK) > 0 {xn} else {(xn as i16) as u32};

  	let index = extension as i8;
	let ea = (Wrapping(reg_val) + Wrapping(xn) + Wrapping(index as u32)).0;
	ea & ADDRBUS_MASK
}

#[cfg(test)]
mod tests {
	use super::super::Core;
	use super::super::effective_address::{predecrement_8, postincrement_8};
	use ram::{ADDRBUS_MASK};

	#[test]
	fn predecrement_wraps() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			// pre-decrement should wrap to 0xFFFFFFFF
			// but the following read should be from address 0x00FFFFFF
			// i.e. limited by the 24-bit address bus width
			core.dar[8+i as usize] = 0;
		}
		let ea = predecrement_8(&mut core, 8+0);
		assert_eq!(0x00FFFFFF, ea);
	}
	#[test]
	fn predecrement_8_wraps_a7_by_two() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			// pre-decrement should wrap to 0xFFFFFFFF
			// but the following read should be from address 0x00FFFFFF
			// i.e. limited by the 24-bit address bus width
			core.dar[8+i as usize] = 0;
		}
		let ea = predecrement_8(&mut core, 8+7);
		// a7 is kept even
		assert_eq!(0x00FFFFFE, ea);
	}
	#[test]
	fn postincrement_wraps() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			// pre-decrement should wrap to 0xFFFFFFFF
			// but the following read should be from address 0x00FFFFFF
			// i.e. limited by the 24-bit address bus width
			core.dar[8+i as usize] = 0xFFFFFFFF;
		}
		let ea = postincrement_8(&mut core, 8+0);
		assert_eq!(0xFFFFFFFF & ADDRBUS_MASK, ea);
		assert_eq!(0x0, core.dar[8+0]);
	}
	#[test]
	fn postincrement_8_wraps_a7_by_two() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			// pre-decrement should wrap to 0xFFFFFFFF
			// but the following read should be from address 0x00FFFFFF
			// i.e. limited by the 24-bit address bus width
			core.dar[8+i as usize] = 0xFFFFFFFE;
		}
		let ea = postincrement_8(&mut core, 8+7);
		// a7 is kept even
		assert_eq!(0xFFFFFFFE & ADDRBUS_MASK, ea);
		assert_eq!(0x0, core.dar[8+7]);
	}
}
<commit_msg>Add clarifying comment<commit_after>use super::Core;
use std::num::Wrapping;
use ram::ADDRBUS_MASK;

pub fn absolute_word(core: &mut Core) -> u32 {
	let ea = core.read_imm_i16() as u32;
	ea & ADDRBUS_MASK
}
pub fn absolute_long(core: &mut Core) -> u32 {
	let ea = core.read_imm_u32();
	ea & ADDRBUS_MASK
}
pub fn predecrement_ay_8(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	predecrement_8(core, reg_ndx)
}
pub fn postincrement_ay_8(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	postincrement_8(core, reg_ndx)
}
pub fn predecrement_ay_16(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	predecrement_16(core, reg_ndx)
}
pub fn postincrement_ay_16(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	postincrement_16(core, reg_ndx)
}
pub fn address_indirect_ay(core: &mut Core) -> u32 {
	let reg_ndx = ir_ay!(core);
	core.dar[reg_ndx] & ADDRBUS_MASK
}
pub fn displacement_ay(core: &mut Core) -> u32 {
	let reg_val = core.dar[ir_ay!(core)];
	displacement(core, reg_val)
}
pub fn displacement_pc(core: &mut Core) -> u32 {
	let old_pc = core.pc;
	displacement(core, old_pc)
}
pub fn index_ay(core: &mut Core) -> u32 {
	let reg_val = core.dar[ir_ay!(core)];
	index(core, reg_val)
}
pub fn index_pc(core: &mut Core) -> u32 {
	let pc = core.pc;
	index(core, pc)
}
pub fn predecrement_ax_8(core: &mut Core) -> u32 {
	let reg_ndx = ir_ax!(core);
	predecrement_8(core, reg_ndx)
}
pub fn predecrement_ax_16(core: &mut Core) -> u32 {
	let reg_ndx = ir_ax!(core);
	predecrement_16(core, reg_ndx)
}

fn predecrement_8(core: &mut Core, reg_ndx: usize) -> u32 {
	// pre-decrement
	core.dar[reg_ndx] = (Wrapping(core.dar[reg_ndx]) - match reg_ndx {
		15 => Wrapping(2), // A7 is kept even
		 _ => Wrapping(1)
	}).0;
	core.dar[reg_ndx] & ADDRBUS_MASK
}
fn postincrement_8(core: &mut Core, reg_ndx: usize) -> u32 {
	// post-increment
	let ea = core.dar[reg_ndx];
	core.dar[reg_ndx] = (Wrapping(core.dar[reg_ndx]) + match reg_ndx {
		15 => Wrapping(2), // A7 is kept even
		 _ => Wrapping(1)
	}).0;
	ea & ADDRBUS_MASK
}
fn predecrement_16(core: &mut Core, reg_ndx: usize) -> u32 {
	// pre-decrement
	core.dar[reg_ndx] = (Wrapping(core.dar[reg_ndx]) - Wrapping(2)).0;
	core.dar[reg_ndx] & ADDRBUS_MASK
}
fn postincrement_16(core: &mut Core, reg_ndx: usize) -> u32 {
	// post-increment
	let ea = core.dar[reg_ndx];
	core.dar[reg_ndx] = (Wrapping(core.dar[reg_ndx]) + Wrapping(2)).0;
	ea & ADDRBUS_MASK
}
fn displacement(core: &mut Core, reg_val: u32) -> u32 {
	let displacement = core.read_imm_i16();
	let ea = (Wrapping(reg_val) + Wrapping(displacement as u32)).0;
	ea & ADDRBUS_MASK
}
// Brief Extension Word format (see M68000 PRM section 2.1)
const LONG_INDEX_MASK: u16 = 0x0800;
fn index(core: &mut Core, reg_val: u32) -> u32 {
	let extension = core.read_imm_u16();
	// top four bits = (D/A RRR) matches our register array layout
	let xreg_ndx = (extension>>12) as usize;
	let xn = core.dar[xreg_ndx];
	let xn = if (extension & LONG_INDEX_MASK) > 0 {xn} else {(xn as i16) as u32};

  	let index = extension as i8;
	let ea = (Wrapping(reg_val) + Wrapping(xn) + Wrapping(index as u32)).0;
	ea & ADDRBUS_MASK
}

#[cfg(test)]
mod tests {
	use super::super::Core;
	use super::super::effective_address::{predecrement_8, postincrement_8};
	use ram::{ADDRBUS_MASK};

	#[test]
	fn predecrement_wraps() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			// pre-decrement should wrap to 0xFFFFFFFF
			// but the following read should be from address 0x00FFFFFF
			// i.e. limited by the 24-bit address bus width
			core.dar[8+i as usize] = 0;
		}
		let ea = predecrement_8(&mut core, 8+0);
		assert_eq!(0x00FFFFFF, ea);
	}
	#[test]
	fn predecrement_8_wraps_a7_by_two() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			// pre-decrement should wrap to 0xFFFFFFFF
			// but the following read should be from address 0x00FFFFFF
			// i.e. limited by the 24-bit address bus width
			core.dar[8+i as usize] = 0;
		}
		let ea = predecrement_8(&mut core, 8+7);
		// a7 is kept even
		assert_eq!(0x00FFFFFE, ea);
	}
	#[test]
	fn postincrement_wraps() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			// pre-decrement should wrap to 0xFFFFFFFF
			// but the following read should be from address 0x00FFFFFF
			// i.e. limited by the 24-bit address bus width
			core.dar[8+i as usize] = 0xFFFFFFFF;
		}
		let ea = postincrement_8(&mut core, 8+0);
		assert_eq!(0xFFFFFFFF & ADDRBUS_MASK, ea);
		assert_eq!(0x0, core.dar[8+0]);
	}
	#[test]
	fn postincrement_8_wraps_a7_by_two() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			// pre-decrement should wrap to 0xFFFFFFFF
			// but the following read should be from address 0x00FFFFFF
			// i.e. limited by the 24-bit address bus width
			core.dar[8+i as usize] = 0xFFFFFFFE;
		}
		let ea = postincrement_8(&mut core, 8+7);
		// a7 is kept even
		assert_eq!(0xFFFFFFFE & ADDRBUS_MASK, ea);
		assert_eq!(0x0, core.dar[8+7]);
	}
}
<|endoftext|>


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

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

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

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

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

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

impl<'a> Fill<'a> for EllipseColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_rgba_f32() {
            let rect = self.rect.get();
            let color = self.color.get();
            let color: [f32, ..4] = [color[0], color[1], color[2], color[3]];
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_ellipse_tri_list_xy_rgba_f32(
                128,
                self.transform.get(),
                rect,
                color,
                |vertices, colors| {
                    back_end.tri_list_xy_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}
<commit_msg>Implemented Clear for EllipseColorContext<commit_after>
use {Field, Borrowed, Value};
use vecmath::{rotate_radians, multiply, translate, scale, shear};
use {Clear, Fill, BackEnd, Transform2d, Matrix2d, Rectangle, Color};
use triangulation::{with_ellipse_tri_list_xy_rgba_f32};

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

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

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

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

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

impl<'a> Fill<'a> for EllipseColorContext<'a> {
    fn fill<B: BackEnd>(&'a self, back_end: &mut B) {
        if back_end.supports_tri_list_xy_rgba_f32() {
            let rect = self.rect.get();
            let color = self.color.get();
            let color: [f32, ..4] = [color[0], color[1], color[2], color[3]];
            // Complete transparency does not need to be rendered.
            if color[3] == 0.0 { return; }
            // Turn on alpha blending if not completely opaque.
            let needs_alpha = color[3] != 1.0;
            if needs_alpha { back_end.enable_alpha_blend(); }
            with_ellipse_tri_list_xy_rgba_f32(
                128,
                self.transform.get(),
                rect,
                color,
                |vertices, colors| {
                    back_end.tri_list_xy_rgba_f32(vertices, colors)
                }
            );
            if needs_alpha { back_end.disable_alpha_blend(); }
        } else {
            unimplemented!();
        }
    }
}

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

<|endoftext|>


<commit_before>use std::env::consts;
use std::time::SystemTime;

use async_trait::async_trait;
use serde_json::json;
use tracing::instrument;
use tracing::{debug, trace};

use crate::client::bridge::gateway::{ChunkGuildFilter, GatewayIntents};
use crate::constants::{self, OpCode};
use crate::gateway::{CurrentPresence, WsStream};
use crate::internal::prelude::*;
use crate::internal::ws_impl::SenderExt;
use crate::model::id::GuildId;

#[async_trait]
pub trait WebSocketGatewayClientExt {
    async fn send_chunk_guild(
        &mut self,
        guild_id: GuildId,
        shard_info: &[u64; 2],
        limit: Option<u16>,
        filter: ChunkGuildFilter,
        nonce: Option<&str>,
    ) -> Result<()>;

    async fn send_heartbeat(&mut self, shard_info: &[u64; 2], seq: Option<u64>) -> Result<()>;

    async fn send_identify(
        &mut self,
        shard_info: &[u64; 2],
        token: &str,
        intents: GatewayIntents,
    ) -> Result<()>;

    async fn send_presence_update(
        &mut self,
        shard_info: &[u64; 2],
        current_presence: &CurrentPresence,
    ) -> Result<()>;

    async fn send_resume(
        &mut self,
        shard_info: &[u64; 2],
        session_id: &str,
        seq: u64,
        token: &str,
    ) -> Result<()>;
}

#[async_trait]
impl WebSocketGatewayClientExt for WsStream {
    #[instrument(skip(self))]
    async fn send_chunk_guild(
        &mut self,
        guild_id: GuildId,
        shard_info: &[u64; 2],
        limit: Option<u16>,
        filter: ChunkGuildFilter,
        nonce: Option<&str>,
    ) -> Result<()> {
        debug!("[Shard {:?}] Requesting member chunks", shard_info);

        let mut payload = json!({
            "op": OpCode::GetGuildMembers.num(),
            "d": {
                "guild_id": [guild_id.as_ref().0],
                "limit": limit.unwrap_or(0),
                "nonce": nonce.unwrap_or(""),
            },
        });

        match filter {
            ChunkGuildFilter::None => {},
            ChunkGuildFilter::Query(query) => payload["d"]["query"] = json!(query),
            ChunkGuildFilter::UserIds(user_ids) => {
                let ids = user_ids.iter().map(|x| x.0).collect::<Vec<u64>>();
                payload["d"]["user_ids"] = json!(ids)
            },
        };

        self.send_json(&payload).await.map_err(From::from)
    }

    #[instrument(skip(self))]
    async fn send_heartbeat(&mut self, shard_info: &[u64; 2], seq: Option<u64>) -> Result<()> {
        trace!("[Shard {:?}] Sending heartbeat d: {:?}", shard_info, seq);

        self.send_json(&json!({
            "d": seq,
            "op": OpCode::Heartbeat.num(),
        }))
        .await
        .map_err(From::from)
    }

    #[instrument(skip(self, token))]
    async fn send_identify(
        &mut self,
        shard_info: &[u64; 2],
        token: &str,
        intents: GatewayIntents,
    ) -> Result<()> {
        debug!("[Shard {:?}] Identifying", shard_info);

        self.send_json(&json!({
            "op": OpCode::Identify.num(),
            "d": {
                "compress": true,
                "large_threshold": constants::LARGE_THRESHOLD,
                "shard": shard_info,
                "token": token,
                "intents": intents,
                "v": constants::GATEWAY_VERSION,
                "properties": {
                    "$browser": "serenity",
                    "$device": "serenity",
                    "$os": consts::OS,
                },
            },
        }))
        .await
    }

    #[instrument(skip(self))]
    async fn send_presence_update(
        &mut self,
        shard_info: &[u64; 2],
        current_presence: &CurrentPresence,
    ) -> Result<()> {
        let &(ref activity, ref status) = current_presence;
        let now = SystemTime::now();

        debug!("[Shard {:?}] Sending presence update", shard_info);

        self.send_json(&json!({
            "op": OpCode::StatusUpdate.num(),
            "d": {
                "afk": false,
                "since": now,
                "status": status.name(),
                "game": activity.as_ref().map(|x| json!({
                    "name": x.name,
                    "type": x.kind,
                    "url": x.url,
                })),
            },
        }))
        .await
    }

    #[instrument(skip(self, token))]
    async fn send_resume(
        &mut self,
        shard_info: &[u64; 2],
        session_id: &str,
        seq: u64,
        token: &str,
    ) -> Result<()> {
        debug!("[Shard {:?}] Sending resume; seq: {}", shard_info, seq);

        self.send_json(&json!({
            "op": OpCode::Resume.num(),
            "d": {
                "session_id": session_id,
                "seq": seq,
                "token": token,
            },
        }))
        .await
        .map_err(From::from)
    }
}
<commit_msg>Fix `WebSocketGatewayClientExt::send_chunk_guild` to not get disconnected by Discord's gateway (#1200)<commit_after>use std::env::consts;
use std::time::SystemTime;

use async_trait::async_trait;
use serde_json::json;
use tracing::instrument;
use tracing::{debug, trace};

use crate::client::bridge::gateway::{ChunkGuildFilter, GatewayIntents};
use crate::constants::{self, OpCode};
use crate::gateway::{CurrentPresence, WsStream};
use crate::internal::prelude::*;
use crate::internal::ws_impl::SenderExt;
use crate::model::id::GuildId;

#[async_trait]
pub trait WebSocketGatewayClientExt {
    async fn send_chunk_guild(
        &mut self,
        guild_id: GuildId,
        shard_info: &[u64; 2],
        limit: Option<u16>,
        filter: ChunkGuildFilter,
        nonce: Option<&str>,
    ) -> Result<()>;

    async fn send_heartbeat(&mut self, shard_info: &[u64; 2], seq: Option<u64>) -> Result<()>;

    async fn send_identify(
        &mut self,
        shard_info: &[u64; 2],
        token: &str,
        intents: GatewayIntents,
    ) -> Result<()>;

    async fn send_presence_update(
        &mut self,
        shard_info: &[u64; 2],
        current_presence: &CurrentPresence,
    ) -> Result<()>;

    async fn send_resume(
        &mut self,
        shard_info: &[u64; 2],
        session_id: &str,
        seq: u64,
        token: &str,
    ) -> Result<()>;
}

#[async_trait]
impl WebSocketGatewayClientExt for WsStream {
    #[instrument(skip(self))]
    async fn send_chunk_guild(
        &mut self,
        guild_id: GuildId,
        shard_info: &[u64; 2],
        limit: Option<u16>,
        filter: ChunkGuildFilter,
        nonce: Option<&str>,
    ) -> Result<()> {
        debug!("[Shard {:?}] Requesting member chunks", shard_info);

        let mut payload = json!({
            "op": OpCode::GetGuildMembers.num(),
            "d": {
                "guild_id": guild_id.as_ref().0.to_string(),
                "limit": limit.unwrap_or(0),
                "nonce": nonce.unwrap_or(""),
            },
        });

        match filter {
            ChunkGuildFilter::None => payload["d"]["query"] = json!(""),
            ChunkGuildFilter::Query(query) => payload["d"]["query"] = json!(query),
            ChunkGuildFilter::UserIds(user_ids) => {
                let ids = user_ids.iter().map(|x| x.0).collect::<Vec<u64>>();
                payload["d"]["user_ids"] = json!(ids)
            },
        };

        self.send_json(&payload).await.map_err(From::from)
    }

    #[instrument(skip(self))]
    async fn send_heartbeat(&mut self, shard_info: &[u64; 2], seq: Option<u64>) -> Result<()> {
        trace!("[Shard {:?}] Sending heartbeat d: {:?}", shard_info, seq);

        self.send_json(&json!({
            "d": seq,
            "op": OpCode::Heartbeat.num(),
        }))
        .await
        .map_err(From::from)
    }

    #[instrument(skip(self, token))]
    async fn send_identify(
        &mut self,
        shard_info: &[u64; 2],
        token: &str,
        intents: GatewayIntents,
    ) -> Result<()> {
        debug!("[Shard {:?}] Identifying", shard_info);

        self.send_json(&json!({
            "op": OpCode::Identify.num(),
            "d": {
                "compress": true,
                "large_threshold": constants::LARGE_THRESHOLD,
                "shard": shard_info,
                "token": token,
                "intents": intents,
                "v": constants::GATEWAY_VERSION,
                "properties": {
                    "$browser": "serenity",
                    "$device": "serenity",
                    "$os": consts::OS,
                },
            },
        }))
        .await
    }

    #[instrument(skip(self))]
    async fn send_presence_update(
        &mut self,
        shard_info: &[u64; 2],
        current_presence: &CurrentPresence,
    ) -> Result<()> {
        let &(ref activity, ref status) = current_presence;
        let now = SystemTime::now();

        debug!("[Shard {:?}] Sending presence update", shard_info);

        self.send_json(&json!({
            "op": OpCode::StatusUpdate.num(),
            "d": {
                "afk": false,
                "since": now,
                "status": status.name(),
                "game": activity.as_ref().map(|x| json!({
                    "name": x.name,
                    "type": x.kind,
                    "url": x.url,
                })),
            },
        }))
        .await
    }

    #[instrument(skip(self, token))]
    async fn send_resume(
        &mut self,
        shard_info: &[u64; 2],
        session_id: &str,
        seq: u64,
        token: &str,
    ) -> Result<()> {
        debug!("[Shard {:?}] Sending resume; seq: {}", shard_info, seq);

        self.send_json(&json!({
            "op": OpCode::Resume.num(),
            "d": {
                "session_id": session_id,
                "seq": seq,
                "token": token,
            },
        }))
        .await
        .map_err(From::from)
    }
}
<|endoftext|>


<commit_before>extern crate clap;
extern crate toml;
extern crate regex;

use base::math::*;
use self::clap::{App, Arg};
use self::regex::Regex;
use std::error::Error as StdError;

pub struct Config {
    pub resolution: Dimension2u,
    pub window_mode: WindowMode,
    pub window_title: String,
    pub vsync: bool,
    pub seed: u64, /* sichtweite
                    * Vsync
                    * kantenglättung
                    * steuerung
                    * frames
                    * seed
                    * Chunkweite */
}
impl Config {
    pub fn load_config() -> Result<Config, Box<StdError>> {
        let conf = Config::default();
        command_config(conf)
    }
}

impl Default for Config {
    fn default() -> Self {
        Config {
            resolution: Dimension2::new(800, 600),
            window_mode: WindowMode::Windowed,
            window_title: format!("Plantex {}", env!("CARGO_PKG_VERSION")),
            vsync: false,
            seed: 42,
        }
    }
}

fn command_config(mut toml_config: Config) -> Result<Config, Box<StdError>> {
    let matches = App::new("Plantex")
        .version(env!("CARGO_PKG_VERSION"))
        .about("Game about Plants!")
        .arg(Arg::with_name("Resolution")
            .help("(e.g. =1280x720) 'Sets Resolution to new value'")
            .takes_value(true)
            .long("resolution"))
        .arg(Arg::with_name("WindowMode")
            .help("[Windowed, FullScreen] 'Sets WindowMode'")
            .takes_value(true)
            .long("windowmode"))
        .arg(Arg::with_name("Vsync")
            .help("[on/off]")
            .takes_value(true)
            .long("vsync"))
        .arg(Arg::with_name("Seed")
            .help("'Takes a specified seed to generate map'")
            .takes_value(true)
            .long("seed"))
        .get_matches();

    if let Some(res) = matches.value_of("Resolution") {
        let reg_res = Regex::new(r"^([1-9]\d{1,4})x([1-9]\d{1,4})").unwrap();

        if reg_res.is_match(res) {
            for cap in reg_res.captures_iter(res) {
                let res_x = cap.at(1).unwrap().parse::<u32>().unwrap();
                let res_y = cap.at(2).unwrap().parse::<u32>().unwrap();
                toml_config.resolution = Dimension2::new(res_x, res_y);
            }
        } else {
            return Err("invalid resolution in command line argument".into());
        }
    }

    if let Some(mode) = matches.value_of("WindowMode") {
        match mode {
            "Windowed" => toml_config.window_mode = WindowMode::Windowed,
            "FullScreen" => toml_config.window_mode = WindowMode::FullScreen,
            _ => return Err("invalid Window Mode in command line argument".into()),
        }
    }

    if let Some(sync) = matches.value_of("Vsync") {
        match sync {
            "on" => toml_config.vsync = true,
            "off" => toml_config.vsync = false,
            _ => return Err("Vsync can only be set on or off on command line".into()),
        }
    }

    if let Some(seed) = matches.value_of("Seed") {
        match seed.parse::<u64>() {
            Ok(n) => toml_config.seed = n,
            _ => return Err("Seed from command line is invalid".into()),
        }
    }
    Ok(toml_config)
}
pub enum WindowMode {
    Windowed,
    // FullScreenWindow, // TODO: maybe add this
    FullScreen,
}
<commit_msg>adjusted clap function<commit_after>extern crate clap;
extern crate toml;
extern crate regex;

use base::math::*;
use self::clap::{App, Arg, ArgMatches};
use self::regex::Regex;
use std::error::Error as StdError;

pub struct Config {
    pub resolution: Dimension2u,
    pub window_mode: WindowMode,
    pub window_title: String,
    pub vsync: bool,
    pub seed: u64, /* sichtweite
                    * Vsync
                    * kantenglättung
                    * steuerung
                    * frames
                    * seed
                    * Chunkweite */
}
impl Config {
    ///creates a new Config in three steps:
    ///1. loads default config
    ///2. Overrides from toml config file
    ///3. Overrides from command line
    pub fn load_config() -> Result<Config, Box<StdError>> {
        let matches = App::new("Plantex")
        .version(env!("CARGO_PKG_VERSION"))
        .about("Game about Plants!")
        .arg(Arg::with_name("Resolution")
            .help("(e.g. =1280x720) 'Sets Resolution to new value'")
            .takes_value(true)
            .long("resolution"))
        .arg(Arg::with_name("WindowMode")
            .help("[Windowed, FullScreen] 'Sets WindowMode'")
            .takes_value(true)
            .long("windowmode"))
        .arg(Arg::with_name("Vsync")
            .help("[on/off]")
            .takes_value(true)
            .long("vsync"))
        .arg(Arg::with_name("Seed")
            .help("'Takes a specified seed to generate map'")
            .takes_value(true)
            .long("seed"))
        .arg(Arg::with_name("File")
            .help("Takes config file")
            .takes_value(true)
            .long("config-file"))
        .get_matches();

        let conf = Config::default();
        let t_conf = match config_toml(conf, &matches){
            Ok(n) => n,
            Err(e) => return Err(e),
        };
        let conf_final = match config_command(t_conf, &matches){
            Ok(n) => n,
            Err(e) => return Err(e),
        };
        Ok(conf_final)
    }
}

impl Default for Config {
    ///Returns default config from hard coded values
    fn default() -> Self {
        Config {
            resolution: Dimension2::new(800, 600),
            window_mode: WindowMode::Windowed,
            window_title: format!("Plantex {}", env!("CARGO_PKG_VERSION")),
            vsync: false,
            seed: 42,
        }
    }
}

fn config_toml(mut default_config: Config, matches: &ArgMatches<>) -> Result<Config, Box<StdError>>{
    if let Some(file) = matches.value_of("File"){
        println!("Celebrate!!");
    }

    Ok(default_config)
}

fn config_command(mut toml_config: Config, matches: &ArgMatches<>) -> Result<Config, Box<StdError>> {

    if let Some(res) = matches.value_of("Resolution") {
        let reg_res = Regex::new(r"^([1-9]\d{1,4})x([1-9]\d{1,4})").unwrap();

        if reg_res.is_match(res) {
            for cap in reg_res.captures_iter(res) {
                let res_x = cap.at(1).unwrap().parse::<u32>().unwrap();
                let res_y = cap.at(2).unwrap().parse::<u32>().unwrap();
                toml_config.resolution = Dimension2::new(res_x, res_y);
            }
        } else {
            return Err("invalid resolution in command line argument".into());
        }
    }

    if let Some(mode) = matches.value_of("WindowMode") {
        match mode {
            "Windowed" => toml_config.window_mode = WindowMode::Windowed,
            "FullScreen" => toml_config.window_mode = WindowMode::FullScreen,
            _ => return Err("invalid Window Mode in command line argument".into()),
        }
    }

    if let Some(sync) = matches.value_of("Vsync") {
        match sync {
            "on" => toml_config.vsync = true,
            "off" => toml_config.vsync = false,
            _ => return Err("Vsync can only be set on or off on command line".into()),
        }
    }

    if let Some(seed) = matches.value_of("Seed") {
        match seed.parse::<u64>() {
            Ok(n) => toml_config.seed = n,
            _ => return Err("Seed from command line is invalid".into()),
        }
    }
    Ok(toml_config)
}
pub enum WindowMode {
    Windowed,
    // FullScreenWindow, // TODO: maybe add this
    FullScreen,
}
<|endoftext|>


<commit_before>use std::net;
use std::str;

struct Listener{
    clientAddr: net::SocketAddr,
    reqType: String,
    reqFile: String,
    httpProto: String,
    userAgent: String,
    rawReq: String,
}

impl Listener {

    fn listen (self) {

    }

    fn ParseRequestStr(self, req_str: str) {
        //Populate the fields of the listener struct
        //http://www.trevisrothwell.com/2015/01/string-tokenization-in-rust/
        //Now StrExt doesn't exist. Part of std:str

        let mut term = str::Split(req_str, " ");

        loop {
            match term.next() {
                "GET" => {self.reqType = "GET"},
                path @ _ => {self.reqFile = path},
                "HTTP /1.1" => {self.httpProto = "HTTP /1.1"}
            }
        }
    }
}<commit_msg>Committing silly changes<commit_after>use std::net;
use std::str;

struct Listener{
    clientAddr: net::SocketAddr,
    reqType: String,
    reqFile: String,
    httpProto: String,
    userAgent: String,
    rawReq: String,
}

impl Listener {

    fn listen (self) {

    }

    fn ParseRequestStr(self, req_str: str) {
        //Populate the fields of the listener struct
        //http://www.trevisrothwell.com/2015/01/string-tokenization-in-rust/
        //Now StrExt doesn't exist. Part of std:str

        let mut term = str::Split(req_str, " ");

        loop { //Works only if path isn't missing
            match term.next() {
                "GET" => {self.reqType = "GET"},
                path @ _ => {self.reqFile = path},
                "HTTP /1.1" => {self.httpProto = "HTTP /1.1"}
            }
        }
    }

}<|endoftext|>


<commit_before>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use anyhow::{Error, Result};
use libra_types::{
    account_address::AccountAddress,
    account_state_blob::AccountStateBlob,
    contract_event::ContractEvent,
    event::EventKey,
    proof::{TransactionAccumulatorProof, TransactionListProof, TransactionProof},
    transaction::{
        Transaction, TransactionInfo, TransactionListWithProof, TransactionWithProof, Version,
    },
    vm_error::StatusCode,
};
use libradb::LibraDBTrait;
use std::collections::BTreeMap;

/// Lightweight mock of LibraDB
#[derive(Clone)]
pub(crate) struct MockLibraDB {
    pub version: u64,
    pub timestamp: u64,
    pub all_accounts: BTreeMap<AccountAddress, AccountStateBlob>,
    pub all_txns: Vec<Transaction>,
    pub events: Vec<(u64, ContractEvent)>,
}

impl LibraDBTrait for MockLibraDB {
    fn get_latest_account_state(
        &self,
        address: AccountAddress,
    ) -> Result<Option<AccountStateBlob>> {
        if let Some(blob) = self.all_accounts.get(&address) {
            Ok(Some(blob.clone()))
        } else {
            Ok(None)
        }
    }

    fn get_latest_commit_metadata(&self) -> Result<(Version, u64)> {
        Ok((self.version, self.timestamp))
    }

    fn get_txn_by_account(
        &self,
        address: AccountAddress,
        seq_num: u64,
        _ledger_version: u64,
        _fetch_events: bool,
    ) -> Result<Option<TransactionWithProof>, Error> {
        Ok(self
            .all_txns
            .iter()
            .find(|x| {
                if let Some(t) = x.as_signed_user_txn().ok() {
                    t.sender() == address && t.sequence_number() == seq_num
                } else {
                    false
                }
            })
            .map(|x| TransactionWithProof {
                version: 0,
                transaction: x.clone(),
                events: None,
                proof: TransactionProof::new(
                    TransactionAccumulatorProof::new(vec![]),
                    TransactionInfo::new(
                        Default::default(),
                        Default::default(),
                        Default::default(),
                        0,
                        StatusCode::EXECUTED,
                    ),
                ),
            }))
    }

    fn get_latest_version(&self) -> Result<u64, Error> {
        Ok(self.version)
    }

    fn get_transactions(
        &self,
        start_version: u64,
        limit: u64,
        _ledger_version: u64,
        _fetch_events: bool,
    ) -> Result<TransactionListWithProof, Error> {
        let transactions: Vec<Transaction> = self
            .all_txns
            .iter()
            .skip(start_version as usize)
            .take(limit as usize)
            .map(|x| x.clone())
            .collect();
        let first_transaction_version = transactions.first().map(|_| start_version);
        Ok(TransactionListWithProof {
            transactions,
            events: None,
            first_transaction_version,
            proof: TransactionListProof::new_empty(),
        })
    }

    fn get_events(
        &self,
        key: &EventKey,
        start: u64,
        limit: u64,
    ) -> Result<Vec<(u64, ContractEvent)>> {
        let events = self
            .events
            .iter()
            .filter(|(_, e)| {
                e.key() == key
                    && start <= e.sequence_number()
                    && e.sequence_number() < start + limit
            })
            .cloned()
            .collect();
        Ok(events)
    }
}
<commit_msg>fixup! clippy fix<commit_after>// Copyright (c) The Libra Core Contributors
// SPDX-License-Identifier: Apache-2.0

use anyhow::{Error, Result};
use libra_types::{
    account_address::AccountAddress,
    account_state_blob::AccountStateBlob,
    contract_event::ContractEvent,
    event::EventKey,
    proof::{TransactionAccumulatorProof, TransactionListProof, TransactionProof},
    transaction::{
        Transaction, TransactionInfo, TransactionListWithProof, TransactionWithProof, Version,
    },
    vm_error::StatusCode,
};
use libradb::LibraDBTrait;
use std::collections::BTreeMap;

/// Lightweight mock of LibraDB
#[derive(Clone)]
pub(crate) struct MockLibraDB {
    pub version: u64,
    pub timestamp: u64,
    pub all_accounts: BTreeMap<AccountAddress, AccountStateBlob>,
    pub all_txns: Vec<Transaction>,
    pub events: Vec<(u64, ContractEvent)>,
}

impl LibraDBTrait for MockLibraDB {
    fn get_latest_account_state(
        &self,
        address: AccountAddress,
    ) -> Result<Option<AccountStateBlob>> {
        if let Some(blob) = self.all_accounts.get(&address) {
            Ok(Some(blob.clone()))
        } else {
            Ok(None)
        }
    }

    fn get_latest_commit_metadata(&self) -> Result<(Version, u64)> {
        Ok((self.version, self.timestamp))
    }

    fn get_txn_by_account(
        &self,
        address: AccountAddress,
        seq_num: u64,
        _ledger_version: u64,
        _fetch_events: bool,
    ) -> Result<Option<TransactionWithProof>, Error> {
        Ok(self
            .all_txns
            .iter()
            .find(|x| {
                if let Ok(t) = x.as_signed_user_txn() {
                    t.sender() == address && t.sequence_number() == seq_num
                } else {
                    false
                }
            })
            .map(|x| TransactionWithProof {
                version: 0,
                transaction: x.clone(),
                events: None,
                proof: TransactionProof::new(
                    TransactionAccumulatorProof::new(vec![]),
                    TransactionInfo::new(
                        Default::default(),
                        Default::default(),
                        Default::default(),
                        0,
                        StatusCode::EXECUTED,
                    ),
                ),
            }))
    }

    fn get_latest_version(&self) -> Result<u64, Error> {
        Ok(self.version)
    }

    fn get_transactions(
        &self,
        start_version: u64,
        limit: u64,
        _ledger_version: u64,
        _fetch_events: bool,
    ) -> Result<TransactionListWithProof, Error> {
        let transactions: Vec<Transaction> = self
            .all_txns
            .iter()
            .skip(start_version as usize)
            .take(limit as usize)
            .cloned()
            .collect();
        let first_transaction_version = transactions.first().map(|_| start_version);
        Ok(TransactionListWithProof {
            transactions,
            events: None,
            first_transaction_version,
            proof: TransactionListProof::new_empty(),
        })
    }

    fn get_events(
        &self,
        key: &EventKey,
        start: u64,
        limit: u64,
    ) -> Result<Vec<(u64, ContractEvent)>> {
        let events = self
            .events
            .iter()
            .filter(|(_, e)| {
                e.key() == key
                    && start <= e.sequence_number()
                    && e.sequence_number() < start + limit
            })
            .cloned()
            .collect();
        Ok(events)
    }
}
<|endoftext|>