<commit_before>
use super::effective_address;
use super::Core;

pub fn ay_pd_8(core: &mut Core) -> u32 {
	let ea = effective_address::predecrement_ay_8(core);
	core.read_data_byte(ea)
}
pub fn ax_pd_8(core: &mut Core) -> (u32, u32) {
	let ea = effective_address::predecrement_ax_8(core);
	(core.read_data_byte(ea), ea)
}
pub fn ay_pi_8(core: &mut Core) -> u32 {
	let ea = effective_address::postincrement_ay_8(core);
	core.read_data_byte(ea)
}
pub fn ay_ai_8(core: &mut Core) -> u32 {
	let ea = effective_address::address_indirect_ay(core);
	core.read_data_byte(ea)
}
pub fn ay_di_8(core: &mut Core) -> u32 {
	let ea = effective_address::displacement_ay(core);
	core.read_data_byte(ea)
}
pub fn ay_ix_8(core: &mut Core) -> u32 {
	let ea = effective_address::index_ay(core);
	core.read_data_byte(ea)
}
pub fn aw_8(core: &mut Core) -> u32 {
	let ea = effective_address::absolute_word(core);
	core.read_data_byte(ea)
}
pub fn al_8(core: &mut Core) -> u32 {
	let ea = effective_address::absolute_long(core);
	core.read_data_byte(ea)
}
pub fn pcdi_8(core: &mut Core) -> u32 {
	let ea = effective_address::displacement_pc(core);
	core.read_program_byte(ea)
}
pub fn pcix_8(core: &mut Core) -> u32 {
	let ea = effective_address::index_pc(core);
	core.read_program_byte(ea)
}
pub fn imm_8(core: &mut Core) -> u32 {
	let extension = core.read_imm_u16();
	mask_out_above_8!(extension) as u32
}
pub fn ay_pd_16(core: &mut Core) -> u32 {
	let ea = effective_address::predecrement_ay_16(core);
	core.read_data_word(ea)
}
pub fn ax_pd_16(core: &mut Core) -> (u32, u32) {
	let ea = effective_address::predecrement_ax_16(core);
	(core.read_data_word(ea), ea)
}
pub fn ay_pi_16(core: &mut Core) -> u32 {
	let ea = effective_address::postincrement_ay_16(core);
	core.read_data_word(ea)
}
pub fn ay_ai_16(core: &mut Core) -> u32 {
	let ea = effective_address::address_indirect_ay(core);
	core.read_data_word(ea)
}
pub fn ay_di_16(core: &mut Core) -> u32 {
	let ea = effective_address::displacement_ay(core);
	core.read_data_word(ea)
}
pub fn ay_ix_16(core: &mut Core) -> u32 {
	let ea = effective_address::index_ay(core);
	core.read_data_word(ea)
}
pub fn aw_16(core: &mut Core) -> u32 {
	let ea = effective_address::absolute_word(core);
	core.read_data_word(ea)
}
pub fn al_16(core: &mut Core) -> u32 {
	let ea = effective_address::absolute_long(core);
	core.read_data_word(ea)
}
pub fn pcdi_16(core: &mut Core) -> u32 {
	let ea = effective_address::displacement_pc(core);
	core.read_program_word(ea)
}
pub fn pcix_16(core: &mut Core) -> u32 {
	let ea = effective_address::index_pc(core);
	core.read_program_word(ea)
}
pub fn imm_16(core: &mut Core) -> u32 {
	let extension = core.read_imm_u16();
	mask_out_above_8!(extension) as u32
}
pub fn dx(core: &mut Core) -> u32 {
	dx!(core)
}
pub fn dy(core: &mut Core) -> u32 {
	dy!(core)
}
pub fn ax(core: &mut Core) -> u32 {
	ax!(core)
}
pub fn ay(core: &mut Core) -> u32 {
	ay!(core)
}
#[cfg(test)]
mod tests {
	use super::super::Core;
	use super::{ax_pd_8, ay_pd_8};
	use ram::{AddressBus, SUPERVISOR_DATA};

	#[test]
	fn predecrement_ax() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}
		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;

		assert_eq!(512+4*4, core.dar[8+4]);
		let (dst, ea) = ax_pd_8(core);
		assert_eq!(0x44, dst);
		assert_eq!(512+4*4-1, core.dar[8+4]);
		assert_eq!(512+4*4-1, ea);

		core.ir = 0b1111_1111_1111_1111; // X=7, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		let (dst, ea) = ax_pd_8(core);
		assert_eq!(0x77, dst);
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
		assert_eq!(512+4*7-2, ea);
	}
	#[test]
	fn predecrement_ay() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}

		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;
		assert_eq!(512+4*2, core.dar[8+2]);
		assert_eq!(0x22, ay_pd_8(core));
		assert_eq!(512+4*2-1, core.dar[8+2]);

		core.ir = 0b1111_1011_1111_1111; // X=5, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		assert_eq!(0x77, ay_pd_8(core));
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
	}
}
<commit_msg>All operators return Result<u32, Exception><commit_after>
use super::effective_address;
use super::{Core, Exception};

pub fn ay_pd_8(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::predecrement_ay_8(core);
	core.read_data_byte(ea)
}
pub fn ax_pd_8(core: &mut Core) -> Result<(u32, u32), Exception> {
	let ea = effective_address::predecrement_ax_8(core);
	core.read_data_byte(ea).map(|val| (val, ea))
}
pub fn ay_pi_8(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::postincrement_ay_8(core);
	core.read_data_byte(ea)
}
pub fn ay_ai_8(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::address_indirect_ay(core);
	core.read_data_byte(ea)
}
pub fn ay_di_8(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::displacement_ay(core);
	core.read_data_byte(ea)
}
pub fn ay_ix_8(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::index_ay(core);
	core.read_data_byte(ea)
}
pub fn aw_8(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::absolute_word(core);
	core.read_data_byte(ea)
}
pub fn al_8(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::absolute_long(core);
	core.read_data_byte(ea)
}
pub fn pcdi_8(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::displacement_pc(core);
	core.read_program_byte(ea)
}
pub fn pcix_8(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::index_pc(core);
	core.read_program_byte(ea)
}
pub fn imm_8(core: &mut Core) -> Result<u32, Exception> {
	let extension = core.read_imm_u16();
	Ok(mask_out_above_8!(extension) as u32)
}
pub fn ay_pd_16(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::predecrement_ay_16(core);
	core.read_data_word(ea)
}
pub fn ax_pd_16(core: &mut Core) -> Result<(u32, u32), Exception> {
	let ea = effective_address::predecrement_ax_16(core);
	core.read_data_word(ea).map(|val| (val, ea))
}
pub fn ay_pi_16(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::postincrement_ay_16(core);
	core.read_data_word(ea)
}
pub fn ay_ai_16(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::address_indirect_ay(core);
	core.read_data_word(ea)
}
pub fn ay_di_16(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::displacement_ay(core);
	core.read_data_word(ea)
}
pub fn ay_ix_16(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::index_ay(core);
	core.read_data_word(ea)
}
pub fn aw_16(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::absolute_word(core);
	core.read_data_word(ea)
}
pub fn al_16(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::absolute_long(core);
	core.read_data_word(ea)
}
pub fn pcdi_16(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::displacement_pc(core);
	core.read_program_word(ea)
}
pub fn pcix_16(core: &mut Core) -> Result<u32, Exception> {
	let ea = effective_address::index_pc(core);
	core.read_program_word(ea)
}
pub fn imm_16(core: &mut Core) -> Result<u32, Exception> {
	let extension = core.read_imm_u16();
	Ok(mask_out_above_8!(extension) as u32)
}
pub fn dx(core: &mut Core) -> Result<u32, Exception> {
	Ok(dx!(core))
}
pub fn dy(core: &mut Core) -> Result<u32, Exception> {
	Ok(dy!(core))
}
pub fn ax(core: &mut Core) -> Result<u32, Exception> {
	Ok(ax!(core))
}
pub fn ay(core: &mut Core) -> Result<u32, Exception> {
	Ok(ay!(core))
}
#[cfg(test)]
mod tests {
	use super::super::Core;
	use super::{ax_pd_8, ay_pd_8};
	use ram::{AddressBus, SUPERVISOR_DATA};

	#[test]
	fn test_ax_predecrement_8() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}
		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;

		assert_eq!(512+4*4, core.dar[8+4]);
		let (dst, ea) = ax_pd_8(core).unwrap();
		assert_eq!(0x44, dst);
		assert_eq!(512+4*4-1, core.dar[8+4]);
		assert_eq!(512+4*4-1, ea);

		core.ir = 0b1111_1111_1111_1111; // X=7, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		let (dst, ea) = ax_pd_8(core).unwrap();
		assert_eq!(0x77, dst);
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
		assert_eq!(512+4*7-2, ea);
	}
	#[test]
	fn test_ay_predecrement_8() {
		let mut core = Core::new(0x40);
		for i in 0..8 {
			let addr: u32 = 0x200 + 4*i;
			core.dar[8+i as usize] = addr;
			// write just before where A0-A7 points
			let adjustment = if i == 7 {2} else {1};
			core.mem.write_byte(SUPERVISOR_DATA, addr - adjustment, 0x11*i);
		}

		core.ir = 0b1111_1001_1111_1010; // X=4, Y=2
		let core = &mut core;
		assert_eq!(512+4*2, core.dar[8+2]);
		assert_eq!(0x22, ay_pd_8(core).unwrap());
		assert_eq!(512+4*2-1, core.dar[8+2]);

		core.ir = 0b1111_1011_1111_1111; // X=5, Y=7
		assert_eq!(512+4*7, core.dar[8+7]);
		assert_eq!(0x77, ay_pd_8(core).unwrap());
		// A7 is kept even
		assert_eq!(512+4*7-2, core.dar[8+7]);
	}
}
<|endoftext|>


<commit_before>//! Complete fields in record literals and patterns.
use ide_db::SymbolKind;
use syntax::{ast::Expr, T};

use crate::{
    patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind,
    CompletionRelevance, CompletionRelevancePostfixMatch, Completions,
};

pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
    let missing_fields = match &ctx.completion_location {
        Some(
            ImmediateLocation::RecordExpr(record_expr)
            | ImmediateLocation::RecordExprUpdate(record_expr),
        ) => {
            let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));

            if let Some(hir::Adt::Union(un)) = ty.as_ref().and_then(|t| t.original.as_adt()) {
                // ctx.sema.record_literal_missing_fields will always return
                // an empty Vec on a union literal. This is normally
                // reasonable, but here we'd like to present the full list
                // of fields if the literal is empty.
                let were_fields_specified = record_expr
                    .record_expr_field_list()
                    .and_then(|fl| fl.fields().next())
                    .is_some();

                match were_fields_specified {
                    false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
                    true => vec![],
                }
            } else {
                let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);

                let default_trait = ctx.famous_defs().core_default_Default();
                let impl_default_trait =
                    default_trait.zip(ty.as_ref()).map_or(false, |(default_trait, ty)| {
                        ty.original.impls_trait(ctx.db, default_trait, &[])
                    });

                if impl_default_trait && !missing_fields.is_empty() && ctx.path_qual().is_none() {
                    let completion_text = "..Default::default()";
                    let mut item =
                        CompletionItem::new(SymbolKind::Field, ctx.source_range(), completion_text);
                    let completion_text =
                        completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text);
                    item.insert_text(completion_text).set_relevance(CompletionRelevance {
                        postfix_match: Some(CompletionRelevancePostfixMatch::Exact),
                        ..Default::default()
                    });
                    item.add_to(acc);
                }
                if ctx.previous_token_is(T![.]) {
                    let mut item =
                        CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), "..");
                    item.insert_text(".");
                    item.add_to(acc);
                    return None;
                }
                missing_fields
            }
        }
        Some(ImmediateLocation::RecordPat(record_pat)) => {
            ctx.sema.record_pattern_missing_fields(record_pat)
        }
        _ => return None,
    };

    for (field, ty) in missing_fields {
        acc.add_field(ctx, None, field, &ty);
    }

    Some(())
}

pub(crate) fn complete_record_literal(
    acc: &mut Completions,
    ctx: &CompletionContext,
) -> Option<()> {
    if !ctx.expects_expression() {
        return None;
    }

    match ctx.expected_type.as_ref()?.as_adt()? {
        hir::Adt::Struct(strukt) if ctx.path_qual().is_none() => {
            let path = ctx
                .module
                .find_use_path(ctx.db, hir::ModuleDef::from(strukt))
                .filter(|it| it.len() > 1);

            acc.add_struct_literal(ctx, strukt, path, None);
        }
        hir::Adt::Union(un) if ctx.path_qual().is_none() => {
            let path = ctx
                .module
                .find_use_path(ctx.db, hir::ModuleDef::from(un))
                .filter(|it| it.len() > 1);

            acc.add_union_literal(ctx, un, path, None);
        }
        _ => {}
    };

    Some(())
}

#[cfg(test)]
mod tests {
    use crate::tests::check_edit;

    #[test]
    fn literal_struct_completion_edit() {
        check_edit(
            "FooDesc {…}",
            r#"
struct FooDesc { pub bar: bool }

fn create_foo(foo_desc: &FooDesc) -> () { () }

fn baz() {
    let foo = create_foo(&$0);
}
            "#,
            r#"
struct FooDesc { pub bar: bool }

fn create_foo(foo_desc: &FooDesc) -> () { () }

fn baz() {
    let foo = create_foo(&FooDesc { bar: ${1:()} }$0);
}
            "#,
        )
    }

    #[test]
    fn literal_struct_completion_from_sub_modules() {
        check_edit(
            "submod::Struct {…}",
            r#"
mod submod {
    pub struct Struct {
        pub a: u64,
    }
}

fn f() -> submod::Struct {
    Stru$0
}
            "#,
            r#"
mod submod {
    pub struct Struct {
        pub a: u64,
    }
}

fn f() -> submod::Struct {
    submod::Struct { a: ${1:()} }$0
}
            "#,
        )
    }

    #[test]
    fn literal_struct_complexion_module() {
        check_edit(
            "FooDesc {…}",
            r#"
mod _69latrick {
    pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, pub bar: bool }
    pub fn create_foo(foo_desc: &FooDesc) -> () { () }
}

fn baz() {
    use _69latrick::*;

    let foo = create_foo(&$0);
}
            "#,
            r#"
mod _69latrick {
    pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, pub bar: bool }
    pub fn create_foo(foo_desc: &FooDesc) -> () { () }
}

fn baz() {
    use _69latrick::*;

    let foo = create_foo(&FooDesc { six: ${1:()}, neuf: ${2:()}, bar: ${3:()} }$0);
}
            "#,
        );
    }

    #[test]
    fn default_completion_edit() {
        check_edit(
            "..Default::default()",
            r#"
//- minicore: default
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        .$0
    };
}
"#,
            r#"
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        ..Default::default()
    };
}
"#,
        );
        check_edit(
            "..Default::default()",
            r#"
//- minicore: default
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        $0
    };
}
"#,
            r#"
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        ..Default::default()
    };
}
"#,
        );
        check_edit(
            "..Default::default()",
            r#"
//- minicore: default
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        ..$0
    };
}
"#,
            r#"
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        ..Default::default()
    };
}
"#,
        );
    }
}
<commit_msg>feat: provide self in record literal completion<commit_after>//! Complete fields in record literals and patterns.
use ide_db::SymbolKind;
use syntax::{ast::Expr, T};

use crate::{
    patterns::ImmediateLocation, CompletionContext, CompletionItem, CompletionItemKind,
    CompletionRelevance, CompletionRelevancePostfixMatch, Completions,
};

pub(crate) fn complete_record(acc: &mut Completions, ctx: &CompletionContext) -> Option<()> {
    let missing_fields = match &ctx.completion_location {
        Some(
            ImmediateLocation::RecordExpr(record_expr)
            | ImmediateLocation::RecordExprUpdate(record_expr),
        ) => {
            let ty = ctx.sema.type_of_expr(&Expr::RecordExpr(record_expr.clone()));

            if let Some(hir::Adt::Union(un)) = ty.as_ref().and_then(|t| t.original.as_adt()) {
                // ctx.sema.record_literal_missing_fields will always return
                // an empty Vec on a union literal. This is normally
                // reasonable, but here we'd like to present the full list
                // of fields if the literal is empty.
                let were_fields_specified = record_expr
                    .record_expr_field_list()
                    .and_then(|fl| fl.fields().next())
                    .is_some();

                match were_fields_specified {
                    false => un.fields(ctx.db).into_iter().map(|f| (f, f.ty(ctx.db))).collect(),
                    true => vec![],
                }
            } else {
                let missing_fields = ctx.sema.record_literal_missing_fields(record_expr);

                let default_trait = ctx.famous_defs().core_default_Default();
                let impl_default_trait =
                    default_trait.zip(ty.as_ref()).map_or(false, |(default_trait, ty)| {
                        ty.original.impls_trait(ctx.db, default_trait, &[])
                    });

                if impl_default_trait && !missing_fields.is_empty() && ctx.path_qual().is_none() {
                    let completion_text = "..Default::default()";
                    let mut item =
                        CompletionItem::new(SymbolKind::Field, ctx.source_range(), completion_text);
                    let completion_text =
                        completion_text.strip_prefix(ctx.token.text()).unwrap_or(completion_text);
                    item.insert_text(completion_text).set_relevance(CompletionRelevance {
                        postfix_match: Some(CompletionRelevancePostfixMatch::Exact),
                        ..Default::default()
                    });
                    item.add_to(acc);
                }
                if ctx.previous_token_is(T![.]) {
                    let mut item =
                        CompletionItem::new(CompletionItemKind::Snippet, ctx.source_range(), "..");
                    item.insert_text(".");
                    item.add_to(acc);
                    return None;
                }
                missing_fields
            }
        }
        Some(ImmediateLocation::RecordPat(record_pat)) => {
            ctx.sema.record_pattern_missing_fields(record_pat)
        }
        _ => return None,
    };

    for (field, ty) in missing_fields {
        acc.add_field(ctx, None, field, &ty);
    }

    Some(())
}

pub(crate) fn complete_record_literal(
    acc: &mut Completions,
    ctx: &CompletionContext,
) -> Option<()> {
    if !ctx.expects_expression() {
        return None;
    }

    match ctx.expected_type.as_ref()?.as_adt()? {
        hir::Adt::Struct(strukt) if ctx.path_qual().is_none() => {
            let path = ctx
                .module
                .find_use_path(ctx.db, hir::ModuleDef::from(strukt))
                .filter(|it| it.len() > 1);

            acc.add_struct_literal(ctx, strukt, path, None);

            let impl_ = ctx.impl_def.as_ref()?;
            let impl_adt = ctx.sema.to_def(impl_)?.self_ty(ctx.db).as_adt()?;
            if hir::Adt::Struct(strukt) == impl_adt {
                acc.add_struct_literal(ctx, strukt, None, Some(hir::known::SELF_TYPE));
            }
        }
        hir::Adt::Union(un) if ctx.path_qual().is_none() => {
            let path = ctx
                .module
                .find_use_path(ctx.db, hir::ModuleDef::from(un))
                .filter(|it| it.len() > 1);

            acc.add_union_literal(ctx, un, path, None);
        }
        _ => {}
    };

    Some(())
}

#[cfg(test)]
mod tests {
    use crate::tests::check_edit;

    #[test]
    fn literal_struct_completion_edit() {
        check_edit(
            "FooDesc {…}",
            r#"
struct FooDesc { pub bar: bool }

fn create_foo(foo_desc: &FooDesc) -> () { () }

fn baz() {
    let foo = create_foo(&$0);
}
            "#,
            r#"
struct FooDesc { pub bar: bool }

fn create_foo(foo_desc: &FooDesc) -> () { () }

fn baz() {
    let foo = create_foo(&FooDesc { bar: ${1:()} }$0);
}
            "#,
        )
    }

    #[test]
    fn literal_struct_impl_self_completion() {
        check_edit(
            "Self {…}",
            r#"
struct Foo {
    bar: u64,
}

impl Foo {
    fn new() -> Foo {
        Self$0
    }
}
            "#,
            r#"
struct Foo {
    bar: u64,
}

impl Foo {
    fn new() -> Foo {
        Self { bar: ${1:()} }$0
    }
}
            "#,
        );

        check_edit(
            "Self(…)",
            r#"
mod submod {
    pub struct Foo(pub u64);
}

impl submod::Foo {
    fn new() -> submod::Foo {
        Self$0
    }
}
            "#,
            r#"
mod submod {
    pub struct Foo(pub u64);
}

impl submod::Foo {
    fn new() -> submod::Foo {
        Self(${1:()})$0
    }
}
            "#,
        )
    }

    #[test]
    fn literal_struct_completion_from_sub_modules() {
        check_edit(
            "submod::Struct {…}",
            r#"
mod submod {
    pub struct Struct {
        pub a: u64,
    }
}

fn f() -> submod::Struct {
    Stru$0
}
            "#,
            r#"
mod submod {
    pub struct Struct {
        pub a: u64,
    }
}

fn f() -> submod::Struct {
    submod::Struct { a: ${1:()} }$0
}
            "#,
        )
    }

    #[test]
    fn literal_struct_complexion_module() {
        check_edit(
            "FooDesc {…}",
            r#"
mod _69latrick {
    pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, pub bar: bool }
    pub fn create_foo(foo_desc: &FooDesc) -> () { () }
}

fn baz() {
    use _69latrick::*;

    let foo = create_foo(&$0);
}
            "#,
            r#"
mod _69latrick {
    pub struct FooDesc { pub six: bool, pub neuf: Vec<String>, pub bar: bool }
    pub fn create_foo(foo_desc: &FooDesc) -> () { () }
}

fn baz() {
    use _69latrick::*;

    let foo = create_foo(&FooDesc { six: ${1:()}, neuf: ${2:()}, bar: ${3:()} }$0);
}
            "#,
        );
    }

    #[test]
    fn default_completion_edit() {
        check_edit(
            "..Default::default()",
            r#"
//- minicore: default
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        .$0
    };
}
"#,
            r#"
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        ..Default::default()
    };
}
"#,
        );
        check_edit(
            "..Default::default()",
            r#"
//- minicore: default
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        $0
    };
}
"#,
            r#"
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        ..Default::default()
    };
}
"#,
        );
        check_edit(
            "..Default::default()",
            r#"
//- minicore: default
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        ..$0
    };
}
"#,
            r#"
struct Struct { foo: u32, bar: usize }

impl Default for Struct {
    fn default() -> Self {}
}

fn foo() {
    let other = Struct {
        foo: 5,
        ..Default::default()
    };
}
"#,
        );
    }
}
<|endoftext|>


<commit_before>use syntax::{
    ast::{
        self,
        edit::{AstNodeEdit, IndentLevel},
    },
    AstNode, SyntaxKind, TextRange, T,
};

use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, Assists};

// Assist: unwrap_block
//
// This assist removes if...else, for, while and loop control statements to just keep the body.
//
// ```
// fn foo() {
//     if true {$0
//         println!("foo");
//     }
// }
// ```
// ->
// ```
// fn foo() {
//     println!("foo");
// }
// ```
pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let assist_id = AssistId("unwrap_block", AssistKind::RefactorRewrite);
    let assist_label = "Unwrap block";

    let l_curly_token = ctx.find_token_syntax_at_offset(T!['{'])?;
    let mut block = ast::BlockExpr::cast(l_curly_token.parent()?)?;
    let target = block.syntax().text_range();
    let mut parent = block.syntax().parent()?;
    if ast::MatchArm::can_cast(parent.kind()) {
        parent = parent.ancestors().find(|it| ast::MatchExpr::can_cast(it.kind()))?
    }

    if matches!(parent.kind(), SyntaxKind::BLOCK_EXPR | SyntaxKind::EXPR_STMT) {
        return acc.add(assist_id, assist_label, target, |builder| {
            builder.replace(
                block.syntax().text_range(),
                update_expr_string(block.to_string(), &[' ', '{', '\n']),
            );
        });
    }

    let parent = ast::Expr::cast(parent)?;

    match parent.clone() {
        ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
        ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)),
        ast::Expr::IfExpr(if_expr) => {
            let then_branch = if_expr.then_branch()?;
            if then_branch == block {
                if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
                    // For `else if` blocks
                    let ancestor_then_branch = ancestor.then_branch()?;

                    return acc.add(assist_id, assist_label, target, |edit| {
                        let range_to_del_else_if = TextRange::new(
                            ancestor_then_branch.syntax().text_range().end(),
                            l_curly_token.text_range().start(),
                        );
                        let range_to_del_rest = TextRange::new(
                            then_branch.syntax().text_range().end(),
                            if_expr.syntax().text_range().end(),
                        );

                        edit.delete(range_to_del_rest);
                        edit.delete(range_to_del_else_if);
                        edit.replace(
                            target,
                            update_expr_string(then_branch.to_string(), &[' ', '{']),
                        );
                    });
                }
            } else {
                return acc.add(assist_id, assist_label, target, |edit| {
                    let range_to_del = TextRange::new(
                        then_branch.syntax().text_range().end(),
                        l_curly_token.text_range().start(),
                    );

                    edit.delete(range_to_del);
                    edit.replace(target, update_expr_string(block.to_string(), &[' ', '{']));
                });
            }
        }
        _ => return None,
    };

    let unwrapped = unwrap_trivial_block(block);
    acc.add(assist_id, assist_label, target, |builder| {
        builder.replace(
            parent.syntax().text_range(),
            update_expr_string(unwrapped.to_string(), &[' ', '{', '\n']),
        );
    })
}

fn update_expr_string(expr_str: String, trim_start_pat: &[char]) -> String {
    let expr_string = expr_str.trim_start_matches(trim_start_pat);
    let mut expr_string_lines: Vec<&str> = expr_string.lines().collect();
    expr_string_lines.pop(); // Delete last line

    expr_string_lines
        .into_iter()
        .map(|line| line.replacen("    ", "", 1)) // Delete indentation
        .collect::<Vec<String>>()
        .join("\n")
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    #[test]
    fn unwrap_tail_expr_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92
    }
}
"#,
            r#"
fn main() {
    92
}
"#,
        )
    }

    #[test]
    fn unwrap_stmt_expr_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92;
    }
    ()
}
"#,
            r#"
fn main() {
    92;
    ()
}
"#,
        );
        // Pedantically, we should add an `;` here...
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92
    }
    ()
}
"#,
            r#"
fn main() {
    92
    ()
}
"#,
        );
    }

    #[test]
    fn simple_if() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    bar();
    if true {$0
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
            r#"
fn main() {
    bar();
    foo();

    // comment
    bar();
}
"#,
        );
    }

    #[test]
    fn simple_if_else() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    bar();
    if true {
        foo();

        // comment
        bar();
    } else {$0
        println!("bar");
    }
}
"#,
            r#"
fn main() {
    bar();
    if true {
        foo();

        // comment
        bar();
    }
    println!("bar");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {$0
        println!("bar");
    } else {
        println!("foo");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    }
    println!("bar");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {$0
        println!("foo");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    }
    println!("foo");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested_else() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {
        println!("foo");
    } else {$0
        println!("else");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {
        println!("foo");
    }
    println!("else");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested_middle() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {$0
        println!("foo");
    } else {
        println!("else");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    }
    println!("foo");
}
"#,
        );
    }

    #[test]
    fn simple_if_bad_cursor_position() {
        check_assist_not_applicable(
            unwrap_block,
            r#"
fn main() {
    bar();$0
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_for() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    for i in 0..5 {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_if_in_for() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    for i in 0..5 {
        if true {$0
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    for i in 0..5 {
        foo();

        // comment
        bar();
    }
}
"#,
        );
    }

    #[test]
    fn simple_loop() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    loop {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_while() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    while true {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn unwrap_match_arm() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    match rel_path {
        Ok(rel_path) => {$0
            let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
            Some((*id, rel_path))
        }
        Err(_) => None,
    }
}
"#,
            r#"
fn main() {
    let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
    Some((*id, rel_path))
}
"#,
        );
    }

    #[test]
    fn simple_if_in_while_bad_cursor_position() {
        check_assist_not_applicable(
            unwrap_block,
            r#"
fn main() {
    while true {
        if true {
            foo();$0

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
        );
    }
}
<commit_msg>fix: Single-line and nested blocks in unwrap_block<commit_after>use syntax::{
    ast::{
        self,
        edit::{AstNodeEdit, IndentLevel},
    },
    AstNode, SyntaxKind, TextRange, T,
};

use crate::{utils::unwrap_trivial_block, AssistContext, AssistId, AssistKind, Assists};

// Assist: unwrap_block
//
// This assist removes if...else, for, while and loop control statements to just keep the body.
//
// ```
// fn foo() {
//     if true {$0
//         println!("foo");
//     }
// }
// ```
// ->
// ```
// fn foo() {
//     println!("foo");
// }
// ```
pub(crate) fn unwrap_block(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let assist_id = AssistId("unwrap_block", AssistKind::RefactorRewrite);
    let assist_label = "Unwrap block";

    let l_curly_token = ctx.find_token_syntax_at_offset(T!['{'])?;
    let mut block = ast::BlockExpr::cast(l_curly_token.parent()?)?;
    let target = block.syntax().text_range();
    let mut parent = block.syntax().parent()?;
    if ast::MatchArm::can_cast(parent.kind()) {
        parent = parent.ancestors().find(|it| ast::MatchExpr::can_cast(it.kind()))?
    }

    if matches!(parent.kind(), SyntaxKind::BLOCK_EXPR | SyntaxKind::EXPR_STMT) {
        return acc.add(assist_id, assist_label, target, |builder| {
            builder.replace(block.syntax().text_range(), update_expr_string(block.to_string()));
        });
    }

    let parent = ast::Expr::cast(parent)?;

    match parent.clone() {
        ast::Expr::ForExpr(_) | ast::Expr::WhileExpr(_) | ast::Expr::LoopExpr(_) => (),
        ast::Expr::MatchExpr(_) => block = block.dedent(IndentLevel(1)),
        ast::Expr::IfExpr(if_expr) => {
            let then_branch = if_expr.then_branch()?;
            if then_branch == block {
                if let Some(ancestor) = if_expr.syntax().parent().and_then(ast::IfExpr::cast) {
                    // For `else if` blocks
                    let ancestor_then_branch = ancestor.then_branch()?;

                    return acc.add(assist_id, assist_label, target, |edit| {
                        let range_to_del_else_if = TextRange::new(
                            ancestor_then_branch.syntax().text_range().end(),
                            l_curly_token.text_range().start(),
                        );
                        let range_to_del_rest = TextRange::new(
                            then_branch.syntax().text_range().end(),
                            if_expr.syntax().text_range().end(),
                        );

                        edit.delete(range_to_del_rest);
                        edit.delete(range_to_del_else_if);
                        edit.replace(
                            target,
                            update_expr_string_without_newline(then_branch.to_string()),
                        );
                    });
                }
            } else {
                return acc.add(assist_id, assist_label, target, |edit| {
                    let range_to_del = TextRange::new(
                        then_branch.syntax().text_range().end(),
                        l_curly_token.text_range().start(),
                    );

                    edit.delete(range_to_del);
                    edit.replace(target, update_expr_string_without_newline(block.to_string()));
                });
            }
        }
        _ => return None,
    };

    let unwrapped = unwrap_trivial_block(block);
    acc.add(assist_id, assist_label, target, |builder| {
        builder.replace(parent.syntax().text_range(), update_expr_string(unwrapped.to_string()));
    })
}

fn update_expr_string(expr_string: String) -> String {
    update_expr_string_with_pat(expr_string, &[' ', '\n'])
}

fn update_expr_string_without_newline(expr_string: String) -> String {
    update_expr_string_with_pat(expr_string, &[' '])
}

fn update_expr_string_with_pat(expr_str: String, whitespace_pat: &[char]) -> String {
    // Remove leading whitespace, index [1..] to remove the leading '{',
    // then continue to remove leading whitespace.
    let expr_str =
        expr_str.trim_start_matches(whitespace_pat)[1..].trim_start_matches(whitespace_pat);

    // Remove trailing whitespace, index [..expr_str.len() - 1] to remove the trailing '}',
    // then continue to remove trailing whitespace.
    let expr_str = expr_str.trim_end_matches(whitespace_pat);
    let expr_str = expr_str[..expr_str.len() - 1].trim_end_matches(whitespace_pat);

    expr_str
        .lines()
        .map(|line| line.replacen("    ", "", 1)) // Delete indentation
        .collect::<Vec<String>>()
        .join("\n")
}

#[cfg(test)]
mod tests {
    use crate::tests::{check_assist, check_assist_not_applicable};

    use super::*;

    #[test]
    fn unwrap_tail_expr_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92
    }
}
"#,
            r#"
fn main() {
    92
}
"#,
        )
    }

    #[test]
    fn unwrap_stmt_expr_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92;
    }
    ()
}
"#,
            r#"
fn main() {
    92;
    ()
}
"#,
        );
        // Pedantically, we should add an `;` here...
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        92
    }
    ()
}
"#,
            r#"
fn main() {
    92
    ()
}
"#,
        );
    }

    #[test]
    fn simple_if() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    bar();
    if true {$0
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
            r#"
fn main() {
    bar();
    foo();

    // comment
    bar();
}
"#,
        );
    }

    #[test]
    fn simple_if_else() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    bar();
    if true {
        foo();

        // comment
        bar();
    } else {$0
        println!("bar");
    }
}
"#,
            r#"
fn main() {
    bar();
    if true {
        foo();

        // comment
        bar();
    }
    println!("bar");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {$0
        println!("bar");
    } else {
        println!("foo");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    }
    println!("bar");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {$0
        println!("foo");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    }
    println!("foo");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested_else() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {
        println!("foo");
    } else {$0
        println!("else");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {
        println!("foo");
    }
    println!("else");
}
"#,
        );
    }

    #[test]
    fn simple_if_else_if_nested_middle() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    } else if true {$0
        println!("foo");
    } else {
        println!("else");
    }
}
"#,
            r#"
fn main() {
    // bar();
    if true {
        println!("true");

        // comment
        // bar();
    } else if false {
        println!("bar");
    }
    println!("foo");
}
"#,
        );
    }

    #[test]
    fn simple_if_bad_cursor_position() {
        check_assist_not_applicable(
            unwrap_block,
            r#"
fn main() {
    bar();$0
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_for() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    for i in 0..5 {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_if_in_for() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    for i in 0..5 {
        if true {$0
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    for i in 0..5 {
        foo();

        // comment
        bar();
    }
}
"#,
        );
    }

    #[test]
    fn simple_loop() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    loop {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn simple_while() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    while true {$0
        if true {
            foo();

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
            r#"
fn main() {
    if true {
        foo();

        // comment
        bar();
    } else {
        println!("bar");
    }
}
"#,
        );
    }

    #[test]
    fn unwrap_match_arm() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    match rel_path {
        Ok(rel_path) => {$0
            let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
            Some((*id, rel_path))
        }
        Err(_) => None,
    }
}
"#,
            r#"
fn main() {
    let rel_path = RelativePathBuf::from_path(rel_path).ok()?;
    Some((*id, rel_path))
}
"#,
        );
    }

    #[test]
    fn simple_if_in_while_bad_cursor_position() {
        check_assist_not_applicable(
            unwrap_block,
            r#"
fn main() {
    while true {
        if true {
            foo();$0

            // comment
            bar();
        } else {
            println!("bar");
        }
    }
}
"#,
        );
    }

    #[test]
    fn simple_single_line() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    {$0 0 }
}
"#,
            r#"
fn main() {
    0
}
"#,
        );
    }

    #[test]
    fn simple_nested_block() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    $0{
        {
            3
        }
    }
}
"#,
            r#"
fn main() {
    {
        3
    }
}
"#,
        );
    }

    #[test]
    fn nested_single_line() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    {$0 { println!("foo"); } }
}
"#,
            r#"
fn main() {
    { println!("foo"); }
}
"#,
        );

        check_assist(
            unwrap_block,
            r#"
fn main() {
    {$0 { 0 } }
}
"#,
            r#"
fn main() {
    { 0 }
}
"#,
        );
    }

    #[test]
    fn simple_if_single_line() {
        check_assist(
            unwrap_block,
            r#"
fn main() {
    if true {$0 /* foo */ foo() } else { bar() /* bar */}
}
"#,
            r#"
fn main() {
    /* foo */ foo()
}
"#,
        );
    }
}
<|endoftext|>


<commit_before>
#[derive(Debug)]
#[repr(C)]
pub struct ElfSectionsTag {
    typ: u32,
    size: u32,
    pub number_of_sections: u32,
    entry_size: u32,
    shndx: u32,
    first_section: ElfSection,
}

impl ElfSectionsTag {
    pub fn sections(&self) -> ElfSectionIter {
        let start_section = (&self.first_section) as *const _;
        ElfSectionIter {
            current_section: start_section,
            remaining_sections: self.number_of_sections - 1,
            entry_size: self.entry_size,
        }
    }
}

#[derive(Clone)]
#[allow(raw_pointer_derive)]
pub struct ElfSectionIter {
    current_section: *const ElfSection,
    remaining_sections: u32,
    entry_size: u32,
}

impl Iterator for ElfSectionIter {
    type Item = &'static ElfSection;
    fn next(&mut self) -> Option<&'static ElfSection> {
        if self.remaining_sections == 0 {
            None
        } else {
            let section = unsafe{&*self.current_section};
            self.current_section = ((self.current_section as u32) +
                self.entry_size) as *const ElfSection;
            self.remaining_sections -= 1;
			if section.typ == 0 {
				self.next()
			} else {
	            Some(section)
			}
        }
    }
}

#[derive(Debug)]
#[repr(C)]
pub struct ElfSection {
    name: u32,
    typ: u32,
    pub flags: u64,
    pub addr: u64,
    offset: u64,
    pub size: u64,
    link: u32,
    info: u32,
    addralign: u64,
    entry_size: u64,
}
<commit_msg>Improve ELF sections code<commit_after>
#[derive(Debug)]
#[repr(C)]
pub struct ElfSectionsTag {
    typ: u32,
    size: u32,
    pub number_of_sections: u32,
    entry_size: u32,
    shndx: u32, // string table
    first_section: ElfSection,
}

impl ElfSectionsTag {
    pub fn sections(&'static self) -> ElfSectionIter {
        ElfSectionIter {
            current_section: &self.first_section,
            remaining_sections: self.number_of_sections - 1,
            entry_size: self.entry_size,
        }
    }
}

#[derive(Clone)]
pub struct ElfSectionIter {
    current_section: &'static ElfSection,
    remaining_sections: u32,
    entry_size: u32,
}

impl Iterator for ElfSectionIter {
    type Item = &'static ElfSection;
    fn next(&mut self) -> Option<&'static ElfSection> {
        if self.remaining_sections == 0 {
            None
        } else {
            let section = self.current_section;
            let next_section_addr = (self.current_section as *const _ as u32) + self.entry_size;
            self.current_section = unsafe{ &*(next_section_addr as *const ElfSection) };
            self.remaining_sections -= 1;
			if section.typ == ElfSectionType::Unused as u32 {
				self.next()
			} else {
	            Some(section)
			}
        }
    }
}

#[derive(Debug)]
#[repr(C)]
pub struct ElfSection {
    name: u32,
    typ: u32,
    pub flags: u64,
    pub addr: u64,
    offset: u64,
    pub size: u64,
    link: u32,
    info: u32,
    addralign: u64,
    entry_size: u64,
}
<|endoftext|>


<commit_before>use util::units::{Direction, Point};

pub struct Actor {
    name: String,
    pos: Point,
    health: int,
    max_health: int,
    repr: char,
}

impl Actor {

    pub fn new(name: String, pos: Point, max_health: int, repr: char) -> Actor {
        Actor {
            name: name,
            pos: pos,
            health: max_health,
            max_health: max_health,
            repr: repr,
        }
    }

    pub fn repr(&self) -> char {
        self.repr
    }

    pub fn walk(&mut self, direction: Direction) {
        self.pos = self.pos.move_dir(direction);
    }

    pub fn pos(&self) -> &Point {
        &self.pos
    }

    pub fn is_dead(&self) -> bool {
        self.health <= 0
    }

    pub fn hurt(&mut self, amount: int) {
        self.health -= amount;
    }

    pub fn heal(&mut self, amount: int) {
        self.health += amount;
    }

    pub fn kill(&mut self) {
        self.health = 0;
    }

}
<commit_msg>Actor.pos() now returns by value<commit_after>use util::units::{Direction, Point};

pub struct Actor {
    name: String,
    pos: Point,
    health: int,
    max_health: int,
    repr: char,
}

impl Actor {

    pub fn new(name: String, pos: Point, max_health: int, repr: char) -> Actor {
        Actor {
            name: name,
            pos: pos,
            health: max_health,
            max_health: max_health,
            repr: repr,
        }
    }

    pub fn repr(&self) -> char {
        self.repr
    }

    pub fn walk(&mut self, direction: Direction) {
        self.pos = self.pos.move_dir(direction);
    }

    pub fn pos(&self) -> Point {
        self.pos
    }

    pub fn is_dead(&self) -> bool {
        self.health <= 0
    }

    pub fn hurt(&mut self, amount: int) {
        self.health -= amount;
    }

    pub fn heal(&mut self, amount: int) {
        self.health += amount;
    }

    pub fn kill(&mut self) {
        self.health = 0;
    }

}
<|endoftext|>


<commit_before>#[macro_use]
extern crate askama;

use askama::Template;

#[derive(Template)]
#[template(source = "{{ self.get_s() }}", ext = "txt")]
struct MethodTemplate<'a> {
    s: &'a str,
}

impl<'a> MethodTemplate<'a> {
    fn get_s(&self) -> &str {
        self.s
    }
}

#[derive(Template)]
#[template(source = "{{ self.get_s() }} {{ t.get_s() }}", ext = "txt")]
struct NestedMethodTemplate<'a> {
    t: MethodTemplate<'a>,
}

impl<'a> NestedMethodTemplate<'a> {
    fn get_s(&self) -> &str {
        "bar"
    }
}

#[test]
fn test_method() {
    let t = MethodTemplate { s: "foo" };
    assert_eq!(t.render().unwrap(), "foo");
}

#[test]
fn test_nested() {
    let t = NestedMethodTemplate {
        t: MethodTemplate { s: "foo" },
    };
    assert_eq!(t.render().unwrap(), "bar foo");
}
<commit_msg>Reformat and rename method testing tests for better organization<commit_after>#[macro_use]
extern crate askama;

use askama::Template;

#[derive(Template)]
#[template(source = "{{ self.get_s() }}", ext = "txt")]
struct SelfMethodTemplate<'a> {
    s: &'a str,
}

impl<'a> SelfMethodTemplate<'a> {
    fn get_s(&self) -> &str {
        self.s
    }
}

#[test]
fn test_self_method() {
    let t = SelfMethodTemplate { s: "foo" };
    assert_eq!(t.render().unwrap(), "foo");
}

#[derive(Template)]
#[template(source = "{{ self.get_s() }} {{ t.get_s() }}", ext = "txt")]
struct NestedSelfMethodTemplate<'a> {
    t: SelfMethodTemplate<'a>,
}

impl<'a> NestedSelfMethodTemplate<'a> {
    fn get_s(&self) -> &str {
        "bar"
    }
}

#[test]
fn test_nested() {
    let t = NestedSelfMethodTemplate {
        t: SelfMethodTemplate { s: "foo" },
    };
    assert_eq!(t.render().unwrap(), "bar foo");
}
<|endoftext|>


<commit_before>#![cfg(feature = "use_std")]

use std::collections::HashMap;
use std::hash::Hash;
use std::iter::Iterator;

/// Creates a new `GroupingMap` from `iter`
pub fn new<I, K, V>(iter: I) -> GroupingMap<I>
where
    I: Iterator<Item = (K, V)>,
    K: Hash + Eq,
{
    GroupingMap { iter }
}

/// `GroupingMap` is an intermediate struct for efficient "group-and-fold" operations.
/// It groups elements by their key and at the same time fold each group
/// using some aggregating operation.
///
/// No method on this struct performs temporary allocations.
///
// See [`.into_grouping_map()`](../trait.Itertools.html#method.into_grouping_map)
// for more information.
pub struct GroupingMap<I> {
    iter: I,
}

impl<I, K, V> GroupingMap<I>
where
    I: Iterator<Item = (K, V)>,
    K: Hash + Eq,
{
    /// Groups elements from the `GroupingMap` source by key and applies `operation` to the elements
    /// of each group sequentially, passing the previously accumulated value, a reference to the key
    /// and the current element as arguments, and stores the results in an `HashMap`.
    ///
    /// The `operation` function is invoked on each element with the following parameters:
    ///  - the current value of the accumulator of the group if there is currently one;
    ///  - a reference to the key of the group this element belongs to;
    ///  - the element from the source being aggregated;
    /// If `operation` returns `Some(element)` then the accumulator is updated with `element`,
    /// otherwise the previous accumulation is discarded.
    ///
    /// Return a `HashMap` associating the key of each group with the result of aggregation of the group elements.
    /// If there's no result then there won't be an entry associated to that key.
    ///
    /// This is the generic way to perform any operations on a `Grouping`.
    /// It's suggested to use it only to implement custom operations when the already provided ones are not enough.
    pub fn aggregate<FO, R>(self, mut operation: FO) -> HashMap<K, R>
    where
        FO: FnMut(Option<R>, &K, V) -> Option<R>,
    {
        let mut destination_map = HashMap::new();

        for (key, val) in self.iter {
            let acc = destination_map.remove(&key);
            if let Some(op_res) = operation(acc, &key, val) {
                destination_map.insert(key, op_res);
            }
        }

        destination_map
    }

    /// Groups elements from the `GroupingMap` source by key and applies `operation` to the elements
    /// of each group sequentially, passing the previously accumulated value, a reference to the key
    /// and the current element as arguments, and stores the results in a new map.
    ///
    /// `init` is the value from which will be cloned the initial value of each accumulator.
    ///
    /// `operation` is a function that is invoked on each element with the following parameters:
    ///  - the current value of the accumulator of the group;
    ///  - a reference to the key of the group this element belongs to;
    ///  - the element from the source being accumulated.
    ///
    /// Return a `HashMap` associating the key of each group with the result of folding the group elements.
    pub fn fold<FO, R>(self, init: R, mut operation: FO) -> HashMap<K, R>
    where
        R: Clone,
        FO: FnMut(R, &K, V) -> R,
    {
        self.aggregate(|acc, key, val| {
            let acc = acc.unwrap_or_else(|| init.clone());
            Some(operation(acc, key, val))
        })
    }

    /// Groups elements from the `GroupingMap` source by key and applies `operation` to the elements
    /// of each group sequentially, passing the previously accumulated value, a reference to the key
    /// and the current element as arguments, and stores the results in a new map.
    ///
    /// This is similar to [`fold`] but the initial value of the accumulator is the first element of the group.
    ///
    /// `operation` is a function that is invoked on each element with the following parameters:
    ///  - the current value of the accumulator of the group;
    ///  - a reference to the key of the group this element belongs to;
    ///  - the element from the source being accumulated.
    ///
    /// Return a `HashMap` associating the key of each group with the result of folding the group elements.
    ///
    /// [`fold`]: #tymethod.fold
    pub fn fold_first<FO>(self, mut operation: FO) -> HashMap<K, V>
    where
        FO: FnMut(V, &K, V) -> V,
    {
        self.aggregate(|acc, key, val| {
            Some(match acc {
                Some(acc) => operation(acc, key, val),
                None => val,
            })
        })
    }

    /// Groups elements from the `GroupingMap` source by key and collects the elements of each group in
    /// an instance of `C`. The iteration order is preserved when inserting elements.
    ///
    /// Return a `HashMap` associating the key of each group with the collection containing the elements of that group.
    pub fn collect<C>(self) -> HashMap<K, C>
    where
        C: Default + Extend<V>,
    {
        self.aggregate(|acc, _, v| {
            let mut acc = acc.unwrap_or_else(C::default);
            acc.extend(Some(v));
            Some(acc)
        })
    }

    /// Groups elements from the `GroupingMap` source by key and counts them.
    ///
    /// Return a `HashMap` associating the key of each group with the number of elements in that group.
    pub fn count(self) -> HashMap<K, usize> {
        self.fold(0, |acc, _, _| acc + 1)
    }
}
<commit_msg>Adjusted GroupingMap doc to be in accord with Itertools::into_grouping_map<commit_after>#![cfg(feature = "use_std")]

use std::collections::HashMap;
use std::hash::Hash;
use std::iter::Iterator;

/// Creates a new `GroupingMap` from `iter`
pub fn new<I, K, V>(iter: I) -> GroupingMap<I>
where
    I: Iterator<Item = (K, V)>,
    K: Hash + Eq,
{
    GroupingMap { iter }
}

/// `GroupingMap` is an intermediate struct for efficient group-and-fold operations.
/// It groups elements by their key and at the same time fold each group
/// using some aggregating operation.
///
/// No method on this struct performs temporary allocations.
pub struct GroupingMap<I> {
    iter: I,
}

impl<I, K, V> GroupingMap<I>
where
    I: Iterator<Item = (K, V)>,
    K: Hash + Eq,
{
    /// Groups elements from the `GroupingMap` source by key and applies `operation` to the elements
    /// of each group sequentially, passing the previously accumulated value, a reference to the key
    /// and the current element as arguments, and stores the results in an `HashMap`.
    ///
    /// The `operation` function is invoked on each element with the following parameters:
    ///  - the current value of the accumulator of the group if there is currently one;
    ///  - a reference to the key of the group this element belongs to;
    ///  - the element from the source being aggregated;
    /// If `operation` returns `Some(element)` then the accumulator is updated with `element`,
    /// otherwise the previous accumulation is discarded.
    ///
    /// Return a `HashMap` associating the key of each group with the result of aggregation of the group elements.
    /// If there's no result then there won't be an entry associated to that key.
    ///
    /// This is the generic way to perform any operations on a `Grouping`.
    /// It's suggested to use it only to implement custom operations when the already provided ones are not enough.
    pub fn aggregate<FO, R>(self, mut operation: FO) -> HashMap<K, R>
    where
        FO: FnMut(Option<R>, &K, V) -> Option<R>,
    {
        let mut destination_map = HashMap::new();

        for (key, val) in self.iter {
            let acc = destination_map.remove(&key);
            if let Some(op_res) = operation(acc, &key, val) {
                destination_map.insert(key, op_res);
            }
        }

        destination_map
    }

    /// Groups elements from the `GroupingMap` source by key and applies `operation` to the elements
    /// of each group sequentially, passing the previously accumulated value, a reference to the key
    /// and the current element as arguments, and stores the results in a new map.
    ///
    /// `init` is the value from which will be cloned the initial value of each accumulator.
    ///
    /// `operation` is a function that is invoked on each element with the following parameters:
    ///  - the current value of the accumulator of the group;
    ///  - a reference to the key of the group this element belongs to;
    ///  - the element from the source being accumulated.
    ///
    /// Return a `HashMap` associating the key of each group with the result of folding the group elements.
    pub fn fold<FO, R>(self, init: R, mut operation: FO) -> HashMap<K, R>
    where
        R: Clone,
        FO: FnMut(R, &K, V) -> R,
    {
        self.aggregate(|acc, key, val| {
            let acc = acc.unwrap_or_else(|| init.clone());
            Some(operation(acc, key, val))
        })
    }

    /// Groups elements from the `GroupingMap` source by key and applies `operation` to the elements
    /// of each group sequentially, passing the previously accumulated value, a reference to the key
    /// and the current element as arguments, and stores the results in a new map.
    ///
    /// This is similar to [`fold`] but the initial value of the accumulator is the first element of the group.
    ///
    /// `operation` is a function that is invoked on each element with the following parameters:
    ///  - the current value of the accumulator of the group;
    ///  - a reference to the key of the group this element belongs to;
    ///  - the element from the source being accumulated.
    ///
    /// Return a `HashMap` associating the key of each group with the result of folding the group elements.
    ///
    /// [`fold`]: #tymethod.fold
    pub fn fold_first<FO>(self, mut operation: FO) -> HashMap<K, V>
    where
        FO: FnMut(V, &K, V) -> V,
    {
        self.aggregate(|acc, key, val| {
            Some(match acc {
                Some(acc) => operation(acc, key, val),
                None => val,
            })
        })
    }

    /// Groups elements from the `GroupingMap` source by key and collects the elements of each group in
    /// an instance of `C`. The iteration order is preserved when inserting elements.
    ///
    /// Return a `HashMap` associating the key of each group with the collection containing the elements of that group.
    pub fn collect<C>(self) -> HashMap<K, C>
    where
        C: Default + Extend<V>,
    {
        self.aggregate(|acc, _, v| {
            let mut acc = acc.unwrap_or_else(C::default);
            acc.extend(Some(v));
            Some(acc)
        })
    }

    /// Groups elements from the `GroupingMap` source by key and counts them.
    ///
    /// Return a `HashMap` associating the key of each group with the number of elements in that group.
    pub fn count(self) -> HashMap<K, usize> {
        self.fold(0, |acc, _, _| acc + 1)
    }
}
<|endoftext|>


<commit_before>type Node<T> = Option<Box<Link<T>>>;

struct Link<T> {
    value: T,
    next: Node<T>,
}

struct LinkedList<T> {
    head: Node<T>,
}

impl<T> LinkedList<T> {
    pub fn new() -> LinkedList<T> {
        LinkedList{head: None}
    }

    pub fn insert(&mut self, value: T) {
        let h = self.head.take();
        self.head = Some(Box::new(Link{value: value, next: h}))
    }

    fn lookup<'a>(&'a self, base: &'a Node<T>, offset: usize) -> Option<&T> {
        match *base {
            Some(ref h) if offset == 0 => Some(&h.value),
            Some(ref h) => self.lookup(&h.next, offset - 1),
            _ => None,
        }
    }

    pub fn get(&self, index: usize) -> Option<&T> {
        self.lookup(&self.head, index)
    }
}

#[test]
fn it_works() {
    let mut ll: LinkedList<i32> = LinkedList::new();
    assert_eq!(ll.get(0), None);
}

#[test]
fn insertion() {
    let mut ll: LinkedList<i32> = LinkedList::new();
    assert_eq!(ll.get(0), None);

    ll.insert(1);
    assert_eq!(ll.get(0), Some(&1));

    ll.insert(2);
    assert_eq!(ll.get(0), Some(&2));
}

#[test]
fn lookup() {
    let mut ll: LinkedList<i32> = LinkedList::new();
    ll.insert(3);
    ll.insert(2);
    ll.insert(1);

    assert_eq!(ll.get(0), Some(&1));
    assert_eq!(ll.get(1), Some(&2));
    assert_eq!(ll.get(2), Some(&3));
    assert_eq!(ll.get(3), None);
}
<commit_msg>Implemented removal for linkedlist<commit_after>type Node<T> = Option<Box<Link<T>>>;

struct Link<T> {
    value: T,
    next: Node<T>,
}

struct LinkedList<T> {
    head: Node<T>,
}

impl<T> LinkedList<T> {
    fn lookup<'a>(&'a self, base: &'a Node<T>, offset: usize) -> Option<&Box<Link<T>>> {
        match *base {
            Some(ref n) if offset == 0 => Some(n),
            Some(ref n) => self.lookup(&n.next, offset - 1),
            _ => None,
        }
    }

    pub fn new() -> LinkedList<T> {
        LinkedList{head: None}
    }

    pub fn insert(&mut self, value: T) {
        let h = self.head.take();
        self.head = Some(Box::new(Link{value: value, next: h}))
    }

    pub fn remove(&mut self) {
        match self.head.take() {
            Some(h) => { self.head = h.next },
            None => { }
        }
    }

    pub fn get(&self, index: usize) -> Option<&T> {
        match self.lookup(&self.head, index) {
            Some(ref n) => Some(&n.value),
            None => None,
        }
    }
}

#[test]
fn it_works() {
    let mut ll: LinkedList<i32> = LinkedList::new();
    assert_eq!(ll.get(0), None);
}

#[test]
fn insertion() {
    let mut ll: LinkedList<i32> = LinkedList::new();
    assert_eq!(ll.get(0), None);

    ll.insert(1);
    assert_eq!(ll.get(0), Some(&1));

    ll.insert(2);
    assert_eq!(ll.get(0), Some(&2));
}

#[test]
fn removal() {
    let mut ll: LinkedList<i32> = LinkedList::new();
    ll.insert(1);
    ll.insert(2);

    assert_eq!(ll.get(0), Some(&2));

    ll.remove();
    assert_eq!(ll.get(0), Some(&1));

    ll.remove();
    assert_eq!(ll.get(0), None);
}

#[test]
fn lookup() {
    let mut ll: LinkedList<i32> = LinkedList::new();
    ll.insert(3);
    ll.insert(2);
    ll.insert(1);

    assert_eq!(ll.get(0), Some(&1));
    assert_eq!(ll.get(1), Some(&2));
    assert_eq!(ll.get(2), Some(&3));
    assert_eq!(ll.get(3), None);
}
<|endoftext|>


<commit_before>use std::iter::repeat;
use std::io::Read;
use byteorder::ReadBytesExt;

use image;
use image::ImageResult;

#[derive(Default, Clone)]
pub struct HuffTable {
    lut: Vec<(u8, u8)>,
    valptr: Vec<isize>,
    huffval: Vec<u8>,
    maxcode: Vec<isize>,
    mincode: Vec<isize>,
}

pub struct HuffDecoder {
    pub bits: u32,
    pub num_bits: u8,
    pub end: bool,
    pub marker: u8,
}

impl HuffDecoder {
    pub fn new() -> HuffDecoder {
        HuffDecoder {
            bits: 0,
            num_bits: 0,
            end: false,
            marker: 0
        }
    }

    fn guarantee<R: Read>(&mut self, r: &mut R, n: u8) -> ImageResult<()> {
        while self.num_bits < n && !self.end {
            let byte = try!(r.read_u8());

            if byte == 0xFF {
                let byte2 = try!(r.read_u8());
                if byte2 != 0 {
                    self.marker = byte2;
                    self.end = true;
                }
            }

            self.bits |= ((byte as u32) << (32 - 8)) >> self.num_bits as usize;
            self.num_bits += 8;
        }

        Ok(())
    }

    pub fn read_bit<R: Read>(&mut self, r: &mut R) -> ImageResult<u8> {
        let _   = try!(self.guarantee(r, 1));
        let bit = (self.bits & (1 << 31)) >> 31;
        self.consume(1);

        Ok(bit as u8)
    }

    // Section F.2.2.4
    // Figure F.17
    pub fn receive<R: Read>(&mut self, r: &mut R, ssss: u8) -> ImageResult<i32> {
        let _ = try!(self.guarantee(r, ssss));
        let bits = (self.bits & (0xFFFFFFFFu32 << (32 - ssss as usize))) >> (32 - ssss) as usize;
        self.consume(ssss);

        Ok(bits as i32)
    }

    fn consume(&mut self, n: u8) {
        self.bits <<= n as usize;
        self.num_bits -= n;
    }

    pub fn decode_symbol<R: Read>(&mut self, r: &mut R, table: &HuffTable) -> ImageResult<u8> {
        let _ = try!(self.guarantee(r, 8));

        let index = (self.bits & 0xFF000000) >> (32 - 8);
        let (val, size) = table.lut[index as usize];

        if index < 256 && size < 9 {
        self.consume(size);
            Ok(val)
        } else {
            let mut code = 0usize;

            for i in 0usize..16 {
                let b = try!(self.read_bit(r));
                code |= b as usize;

                if (code as isize) <= table.maxcode[i] {
                    let index = table.valptr[i] +
                                code as isize -
                                table.mincode[i];

                    return Ok(table.huffval[index as usize])
                }

                code <<= 1;
            }

            Err(image::ImageError::FormatError("Could not decode symbol.".to_string()))
        }
    }
}

/// Given an array containing the number of codes of each code length,
/// this function generates the huffman codes lengths and their respective
/// code lengths as specified by the JPEG spec.
fn derive_codes_and_sizes(bits: &[u8]) -> (Vec<u8>, Vec<u16>) {
    let mut huffsize = repeat(0u8).take(256).collect::<Vec<u8>>();
    let mut huffcode = repeat(0u16).take(256).collect::<Vec<u16>>();

    let mut k = 0;
    let mut j;

    // Annex C.2
    // Figure C.1
    // Generate table of individual code lengths
    for i in 0usize..16 {
        j = 0;

        while j < bits[i] {
            huffsize[k] = i as u8 + 1;
            k += 1;
            j += 1;
        }
    }

    huffsize[k] = 0;

    // Annex C.2
    // Figure C.2
    // Generate table of huffman codes
    k = 0;
    let mut code = 0u16;
    let mut size = huffsize[0];

    while huffsize[k] != 0 {
        huffcode[k] = code;
        code += 1;
        k += 1;

        if huffsize[k] == size {
            continue
        }

        // FIXME there is something wrong with this code
        let diff = huffsize[k].wrapping_sub(size);
        code = if diff < 16  { code << diff as usize } else { 0 };

        size = size.wrapping_add(diff);
    }

    (huffsize, huffcode)
}

pub fn build_huff_lut(bits: &[u8], huffval: &[u8]) -> Vec<(u8, u16)> {
    let mut lut = repeat((17u8, 0u16)).take(256).collect::<Vec<(u8, u16)>>();
    let (huffsize, huffcode) = derive_codes_and_sizes(bits);

    for (i, &v) in huffval.iter().enumerate() {
        lut[v as usize] = (huffsize[i], huffcode[i]);
    }

    lut
}

pub fn derive_tables(bits: Vec<u8>, huffval: Vec<u8>) -> HuffTable {
    let mut mincode = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut maxcode = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut valptr  = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut lut     = repeat((0u8, 17u8)).take(256).collect::<Vec<(u8, u8)>>();

    let (huffsize, huffcode) = derive_codes_and_sizes(&bits);

    // Annex F.2.2.3
    // Figure F.15
    let mut j = 0;

    for i in 0usize..16 {
        if bits[i] != 0 {
            valptr[i] = j;
            mincode[i] = huffcode[j as usize] as isize;
            j += bits[i] as isize - 1;
            maxcode[i] = huffcode[j as usize] as isize;

            j += 1;
        }
    }

    for (i, v) in huffval.iter().enumerate() {
        if huffsize[i] > 8 {
            break
        }

        let r = 8 - huffsize[i] as usize;

        for j in 0usize..1 << r {
            let index = (huffcode[i] << r) + j as u16;
            lut[index as usize] = (*v, huffsize[i]);
        }
    }

    HuffTable {
        lut: lut,
        huffval: huffval,
        maxcode: maxcode,
        mincode: mincode,
        valptr: valptr
    }
}
<commit_msg>fix indentation in entropy.rs<commit_after>use std::iter::repeat;
use std::io::Read;
use byteorder::ReadBytesExt;

use image;
use image::ImageResult;

#[derive(Default, Clone)]
pub struct HuffTable {
    lut: Vec<(u8, u8)>,
    valptr: Vec<isize>,
    huffval: Vec<u8>,
    maxcode: Vec<isize>,
    mincode: Vec<isize>,
}

pub struct HuffDecoder {
    pub bits: u32,
    pub num_bits: u8,
    pub end: bool,
    pub marker: u8,
}

impl HuffDecoder {
    pub fn new() -> HuffDecoder {
        HuffDecoder {
            bits: 0,
            num_bits: 0,
            end: false,
            marker: 0
        }
    }

    fn guarantee<R: Read>(&mut self, r: &mut R, n: u8) -> ImageResult<()> {
        while self.num_bits < n && !self.end {
            let byte = try!(r.read_u8());

            if byte == 0xFF {
                let byte2 = try!(r.read_u8());
                if byte2 != 0 {
                    self.marker = byte2;
                    self.end = true;
                }
            }

            self.bits |= ((byte as u32) << (32 - 8)) >> self.num_bits as usize;
            self.num_bits += 8;
        }

        Ok(())
    }

    pub fn read_bit<R: Read>(&mut self, r: &mut R) -> ImageResult<u8> {
        let _   = try!(self.guarantee(r, 1));
        let bit = (self.bits & (1 << 31)) >> 31;
        self.consume(1);

        Ok(bit as u8)
    }

    // Section F.2.2.4
    // Figure F.17
    pub fn receive<R: Read>(&mut self, r: &mut R, ssss: u8) -> ImageResult<i32> {
        let _ = try!(self.guarantee(r, ssss));
        let bits = (self.bits & (0xFFFFFFFFu32 << (32 - ssss as usize))) >> (32 - ssss) as usize;
        self.consume(ssss);

        Ok(bits as i32)
    }

    fn consume(&mut self, n: u8) {
        self.bits <<= n as usize;
        self.num_bits -= n;
    }

    pub fn decode_symbol<R: Read>(&mut self, r: &mut R, table: &HuffTable) -> ImageResult<u8> {
        let _ = try!(self.guarantee(r, 8));

        let index = (self.bits & 0xFF000000) >> (32 - 8);
        let (val, size) = table.lut[index as usize];

        if index < 256 && size < 9 {
            self.consume(size);
            Ok(val)
        } else {
            let mut code = 0usize;

            for i in 0usize..16 {
                let b = try!(self.read_bit(r));
                code |= b as usize;

                if (code as isize) <= table.maxcode[i] {
                    let index = table.valptr[i] +
                                code as isize -
                                table.mincode[i];

                    return Ok(table.huffval[index as usize])
                }

                code <<= 1;
            }

            Err(image::ImageError::FormatError("Could not decode symbol.".to_string()))
        }
    }
}

/// Given an array containing the number of codes of each code length,
/// this function generates the huffman codes lengths and their respective
/// code lengths as specified by the JPEG spec.
fn derive_codes_and_sizes(bits: &[u8]) -> (Vec<u8>, Vec<u16>) {
    let mut huffsize = repeat(0u8).take(256).collect::<Vec<u8>>();
    let mut huffcode = repeat(0u16).take(256).collect::<Vec<u16>>();

    let mut k = 0;
    let mut j;

    // Annex C.2
    // Figure C.1
    // Generate table of individual code lengths
    for i in 0usize..16 {
        j = 0;

        while j < bits[i] {
            huffsize[k] = i as u8 + 1;
            k += 1;
            j += 1;
        }
    }

    huffsize[k] = 0;

    // Annex C.2
    // Figure C.2
    // Generate table of huffman codes
    k = 0;
    let mut code = 0u16;
    let mut size = huffsize[0];

    while huffsize[k] != 0 {
        huffcode[k] = code;
        code += 1;
        k += 1;

        if huffsize[k] == size {
            continue
        }

        // FIXME there is something wrong with this code
        let diff = huffsize[k].wrapping_sub(size);
        code = if diff < 16  { code << diff as usize } else { 0 };

        size = size.wrapping_add(diff);
    }

    (huffsize, huffcode)
}

pub fn build_huff_lut(bits: &[u8], huffval: &[u8]) -> Vec<(u8, u16)> {
    let mut lut = repeat((17u8, 0u16)).take(256).collect::<Vec<(u8, u16)>>();
    let (huffsize, huffcode) = derive_codes_and_sizes(bits);

    for (i, &v) in huffval.iter().enumerate() {
        lut[v as usize] = (huffsize[i], huffcode[i]);
    }

    lut
}

pub fn derive_tables(bits: Vec<u8>, huffval: Vec<u8>) -> HuffTable {
    let mut mincode = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut maxcode = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut valptr  = repeat(-1isize).take(16).collect::<Vec<isize>>();
    let mut lut     = repeat((0u8, 17u8)).take(256).collect::<Vec<(u8, u8)>>();

    let (huffsize, huffcode) = derive_codes_and_sizes(&bits);

    // Annex F.2.2.3
    // Figure F.15
    let mut j = 0;

    for i in 0usize..16 {
        if bits[i] != 0 {
            valptr[i] = j;
            mincode[i] = huffcode[j as usize] as isize;
            j += bits[i] as isize - 1;
            maxcode[i] = huffcode[j as usize] as isize;

            j += 1;
        }
    }

    for (i, v) in huffval.iter().enumerate() {
        if huffsize[i] > 8 {
            break
        }

        let r = 8 - huffsize[i] as usize;

        for j in 0usize..1 << r {
            let index = (huffcode[i] << r) + j as u16;
            lut[index as usize] = (*v, huffsize[i]);
        }
    }

    HuffTable {
        lut: lut,
        huffval: huffval,
        maxcode: maxcode,
        mincode: mincode,
        valptr: valptr
    }
}
<|endoftext|>


<commit_before>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use libc::{c_void, c_int};
use option::Some;
use rt::uv::uvll;
use rt::uv::{Watcher, Loop, NativeHandle, TimerCallback, NullCallback};
use rt::uv::status_to_maybe_uv_error;

pub struct TimerWatcher(*uvll::uv_timer_t);
impl Watcher for TimerWatcher { }

impl TimerWatcher {
    pub fn new(loop_: &mut Loop) -> TimerWatcher {
        unsafe {
            let handle = uvll::malloc_handle(uvll::UV_TIMER);
            assert!(handle.is_not_null());
            assert!(0 == uvll::timer_init(loop_.native_handle(), handle));
            let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
            watcher.install_watcher_data();
            return watcher;
        }
    }

    pub fn start(&mut self, timeout: u64, repeat: u64, cb: TimerCallback) {
        {
            let data = self.get_watcher_data();
            data.timer_cb = Some(cb);
        }

        unsafe {
            uvll::timer_start(self.native_handle(), timer_cb, timeout, repeat);
        }

        extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
            let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
            let data = watcher.get_watcher_data();
            let cb = data.timer_cb.get_ref();
            let status = status_to_maybe_uv_error(handle, status);
            (*cb)(watcher, status);
        }
    }

    pub fn stop(&mut self) {
        unsafe {
            uvll::timer_stop(self.native_handle());
        }
    }

    pub fn close(self, cb: NullCallback) {
        let mut watcher = self;
        {
            let data = watcher.get_watcher_data();
            assert!(data.close_cb.is_none());
            data.close_cb = Some(cb);
        }

        unsafe {
            uvll::close(watcher.native_handle(), close_cb);
        }

        extern fn close_cb(handle: *uvll::uv_timer_t) {
            let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
            {
                let data = watcher.get_watcher_data();
                data.close_cb.swap_unwrap()();
            }
            watcher.drop_watcher_data();
            unsafe {
                uvll::free_handle(handle as *c_void);
            }
        }
    }
}

impl NativeHandle<*uvll::uv_timer_t> for TimerWatcher {
    fn from_native_handle(handle: *uvll::uv_timer_t) -> TimerWatcher {
        TimerWatcher(handle)
    }
    fn native_handle(&self) -> *uvll::uv_idle_t {
        match self { &TimerWatcher(ptr) => ptr }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use rt::uv::Loop;
    use unstable::run_in_bare_thread;

    #[test]
    fn smoke_test() {
        do run_in_bare_thread {
            let mut count = 0;
            let count_ptr: *mut int = &mut count;
            let mut loop_ = Loop::new();
            let mut timer = TimerWatcher::new(&mut loop_);
            do timer.start(10, 0) |timer, status| {
                assert!(status.is_none());
                unsafe { *count_ptr += 1 };
                timer.close(||());
            }
            loop_.run();
            loop_.close();
            assert!(count == 1);
        }
    }

    #[test]
    fn start_twice() {
        do run_in_bare_thread {
            let mut count = 0;
            let count_ptr: *mut int = &mut count;
            let mut loop_ = Loop::new();
            let mut timer = TimerWatcher::new(&mut loop_);
            do timer.start(10, 0) |timer, status| {
                let mut timer = timer;
                assert!(status.is_none());
                unsafe { *count_ptr += 1 };
                do timer.start(10, 0) |timer, status| {
                    assert!(status.is_none());
                    unsafe { *count_ptr += 1 };
                    timer.close(||());
                }
            }
            loop_.run();
            loop_.close();
            assert!(count == 2);
        }
    }

    #[test]
    fn repeat_stop() {
        do run_in_bare_thread {
            let mut count = 0;
            let count_ptr: *mut int = &mut count;
            let mut loop_ = Loop::new();
            let mut timer = TimerWatcher::new(&mut loop_);
            do timer.start(10, 20) |timer, status| {
                assert!(status.is_none());
                unsafe {
                    *count_ptr += 1;

                    if *count_ptr == 10 {

                        // Stop the timer and do something else
                        let mut timer = timer;
                        timer.stop();
                        // Freeze timer so it can be captured
                        let timer = timer;

                        let mut loop_ = timer.event_loop();
                        let mut timer2 = TimerWatcher::new(&mut loop_);
                        do timer2.start(10, 0) |timer2, _| {

                            unsafe { *count_ptr += 1; }

                            timer2.close(||());

                            // Restart the original timer
                            let mut timer = timer;
                            do timer.start(10, 0) |timer, _| {
                                unsafe { *count_ptr += 1; }
                                timer.close(||());
                            }
                        }
                    }
                };
            }
            loop_.run();
            loop_.close();
            assert!(count == 12);
        }
    }

}
<commit_msg>std::rt: Reduce the delay on a timer test. Slow<commit_after>// Copyright 2013 The Rust Project Developers. See the COPYRIGHT
// file at the top-level directory of this distribution and at
// http://rust-lang.org/COPYRIGHT.
//
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
// option. This file may not be copied, modified, or distributed
// except according to those terms.

use libc::{c_void, c_int};
use option::Some;
use rt::uv::uvll;
use rt::uv::{Watcher, Loop, NativeHandle, TimerCallback, NullCallback};
use rt::uv::status_to_maybe_uv_error;

pub struct TimerWatcher(*uvll::uv_timer_t);
impl Watcher for TimerWatcher { }

impl TimerWatcher {
    pub fn new(loop_: &mut Loop) -> TimerWatcher {
        unsafe {
            let handle = uvll::malloc_handle(uvll::UV_TIMER);
            assert!(handle.is_not_null());
            assert!(0 == uvll::timer_init(loop_.native_handle(), handle));
            let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
            watcher.install_watcher_data();
            return watcher;
        }
    }

    pub fn start(&mut self, timeout: u64, repeat: u64, cb: TimerCallback) {
        {
            let data = self.get_watcher_data();
            data.timer_cb = Some(cb);
        }

        unsafe {
            uvll::timer_start(self.native_handle(), timer_cb, timeout, repeat);
        }

        extern fn timer_cb(handle: *uvll::uv_timer_t, status: c_int) {
            let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
            let data = watcher.get_watcher_data();
            let cb = data.timer_cb.get_ref();
            let status = status_to_maybe_uv_error(handle, status);
            (*cb)(watcher, status);
        }
    }

    pub fn stop(&mut self) {
        unsafe {
            uvll::timer_stop(self.native_handle());
        }
    }

    pub fn close(self, cb: NullCallback) {
        let mut watcher = self;
        {
            let data = watcher.get_watcher_data();
            assert!(data.close_cb.is_none());
            data.close_cb = Some(cb);
        }

        unsafe {
            uvll::close(watcher.native_handle(), close_cb);
        }

        extern fn close_cb(handle: *uvll::uv_timer_t) {
            let mut watcher: TimerWatcher = NativeHandle::from_native_handle(handle);
            {
                let data = watcher.get_watcher_data();
                data.close_cb.swap_unwrap()();
            }
            watcher.drop_watcher_data();
            unsafe {
                uvll::free_handle(handle as *c_void);
            }
        }
    }
}

impl NativeHandle<*uvll::uv_timer_t> for TimerWatcher {
    fn from_native_handle(handle: *uvll::uv_timer_t) -> TimerWatcher {
        TimerWatcher(handle)
    }
    fn native_handle(&self) -> *uvll::uv_idle_t {
        match self { &TimerWatcher(ptr) => ptr }
    }
}

#[cfg(test)]
mod test {
    use super::*;
    use rt::uv::Loop;
    use unstable::run_in_bare_thread;

    #[test]
    fn smoke_test() {
        do run_in_bare_thread {
            let mut count = 0;
            let count_ptr: *mut int = &mut count;
            let mut loop_ = Loop::new();
            let mut timer = TimerWatcher::new(&mut loop_);
            do timer.start(10, 0) |timer, status| {
                assert!(status.is_none());
                unsafe { *count_ptr += 1 };
                timer.close(||());
            }
            loop_.run();
            loop_.close();
            assert!(count == 1);
        }
    }

    #[test]
    fn start_twice() {
        do run_in_bare_thread {
            let mut count = 0;
            let count_ptr: *mut int = &mut count;
            let mut loop_ = Loop::new();
            let mut timer = TimerWatcher::new(&mut loop_);
            do timer.start(10, 0) |timer, status| {
                let mut timer = timer;
                assert!(status.is_none());
                unsafe { *count_ptr += 1 };
                do timer.start(10, 0) |timer, status| {
                    assert!(status.is_none());
                    unsafe { *count_ptr += 1 };
                    timer.close(||());
                }
            }
            loop_.run();
            loop_.close();
            assert!(count == 2);
        }
    }

    #[test]
    fn repeat_stop() {
        do run_in_bare_thread {
            let mut count = 0;
            let count_ptr: *mut int = &mut count;
            let mut loop_ = Loop::new();
            let mut timer = TimerWatcher::new(&mut loop_);
            do timer.start(1, 2) |timer, status| {
                assert!(status.is_none());
                unsafe {
                    *count_ptr += 1;

                    if *count_ptr == 10 {

                        // Stop the timer and do something else
                        let mut timer = timer;
                        timer.stop();
                        // Freeze timer so it can be captured
                        let timer = timer;

                        let mut loop_ = timer.event_loop();
                        let mut timer2 = TimerWatcher::new(&mut loop_);
                        do timer2.start(10, 0) |timer2, _| {

                            unsafe { *count_ptr += 1; }

                            timer2.close(||());

                            // Restart the original timer
                            let mut timer = timer;
                            do timer.start(1, 0) |timer, _| {
                                unsafe { *count_ptr += 1; }
                                timer.close(||());
                            }
                        }
                    }
                };
            }
            loop_.run();
            loop_.close();
            assert!(count == 12);
        }
    }

}
<|endoftext|>