<commit_before>use std::cell::Cell;
use std::cell::RefCell;

use glib::translate::*;
use glib_sys;

use aspect_ratio::*;
use attributes::Attribute;
use drawing_ctx::DrawingCtx;
use error::RenderingError;
use float_eq_cairo::ApproxEqCairo;
use handle::RsvgHandle;
use length::*;
use libc;
use node::*;
use parsers::{parse, parse_and_validate, Parse};
use property_bag::{OwnedPropertyBag, PropertyBag};
use state::Overflow;
use viewbox::*;
use viewport::{draw_in_viewport, ClipMode};

pub struct NodeGroup();

impl NodeGroup {
    pub fn new() -> NodeGroup {
        NodeGroup()
    }
}

impl NodeTrait for NodeGroup {
    fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, _: &PropertyBag<'_>) -> NodeResult {
        Ok(())
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx<'_>,
        clipping: bool,
    ) -> Result<(), RenderingError> {
        let values = cascaded.get();

        draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
            node.draw_children(cascaded, dc, clipping)
        })
    }
}

pub struct NodeDefs();

impl NodeDefs {
    pub fn new() -> NodeDefs {
        NodeDefs()
    }
}

impl NodeTrait for NodeDefs {
    fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, _: &PropertyBag<'_>) -> NodeResult {
        Ok(())
    }
}

pub struct NodeSwitch();

impl NodeSwitch {
    pub fn new() -> NodeSwitch {
        NodeSwitch()
    }
}

impl NodeTrait for NodeSwitch {
    fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, _: &PropertyBag<'_>) -> NodeResult {
        Ok(())
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx<'_>,
        clipping: bool,
    ) -> Result<(), RenderingError> {
        let values = cascaded.get();

        draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
            if let Some(child) = node.children().find(|c| c.get_cond()) {
                dc.draw_node_from_stack(&CascadedValues::new(cascaded, &child), &child, clipping)
            } else {
                Ok(())
            }
        })
    }
}

pub struct NodeSvg {
    preserve_aspect_ratio: Cell<AspectRatio>,
    x: Cell<Length>,
    y: Cell<Length>,
    w: Cell<Length>,
    h: Cell<Length>,
    vbox: Cell<Option<ViewBox>>,
    pbag: RefCell<Option<OwnedPropertyBag>>,
}

impl NodeSvg {
    pub fn new() -> NodeSvg {
        NodeSvg {
            preserve_aspect_ratio: Cell::new(AspectRatio::default()),
            x: Cell::new(Length::parse_str("0", LengthDir::Horizontal).unwrap()),
            y: Cell::new(Length::parse_str("0", LengthDir::Vertical).unwrap()),
            w: Cell::new(Length::parse_str("100%", LengthDir::Horizontal).unwrap()),
            h: Cell::new(Length::parse_str("100%", LengthDir::Vertical).unwrap()),
            vbox: Cell::new(None),
            pbag: RefCell::new(None),
        }
    }

    pub fn parse_style_attributes(&self, node: &RsvgNode, handle: *const RsvgHandle) {
        if let Some(owned_pbag) = self.pbag.borrow().as_ref() {
            let pbag = PropertyBag::from_owned(owned_pbag);
            node.parse_style_attributes(handle, "svg", &pbag);
        }
    }
}

impl NodeTrait for NodeSvg {
    fn set_atts(
        &self,
        node: &RsvgNode,
        _: *const RsvgHandle,
        pbag: &PropertyBag<'_>,
    ) -> NodeResult {
        // SVG element has overflow:hidden
        // https://www.w3.org/TR/SVG/styling.html#UAStyleSheet
        node.set_overflow_hidden();

        // x & y attributes have no effect on outermost svg
        // http://www.w3.org/TR/SVG/struct.html#SVGElement
        let is_inner_svg = node.get_parent().is_some();

        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::PreserveAspectRatio => {
                    self.preserve_aspect_ratio
                        .set(parse("preserveAspectRatio", value, ())?)
                }

                Attribute::X => {
                    if is_inner_svg {
                        self.x.set(parse("x", value, LengthDir::Horizontal)?);
                    }
                }

                Attribute::Y => {
                    if is_inner_svg {
                        self.y.set(parse("y", value, LengthDir::Vertical)?);
                    }
                }

                Attribute::Width => self.w.set(parse_and_validate(
                    "width",
                    value,
                    LengthDir::Horizontal,
                    Length::check_nonnegative,
                )?),

                Attribute::Height => self.h.set(parse_and_validate(
                    "height",
                    value,
                    LengthDir::Vertical,
                    Length::check_nonnegative,
                )?),

                Attribute::ViewBox => self.vbox.set(parse("viewBox", value, ()).map(Some)?),

                _ => (),
            }
        }

        // The "style" sub-element is not loaded yet here, so we need
        // to store other attributes to be applied later.
        *self.pbag.borrow_mut() = Some(pbag.to_owned());

        Ok(())
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx<'_>,
        clipping: bool,
    ) -> Result<(), RenderingError> {
        let values = cascaded.get();

        let params = draw_ctx.get_view_params();

        let nx = self.x.get().normalize(values, &params);
        let ny = self.y.get().normalize(values, &params);
        let nw = self.w.get().normalize(values, &params);
        let nh = self.h.get().normalize(values, &params);

        let do_clip = !values.is_overflow() && node.get_parent().is_some();

        draw_in_viewport(
            nx,
            ny,
            nw,
            nh,
            ClipMode::ClipToViewport,
            do_clip,
            self.vbox.get(),
            self.preserve_aspect_ratio.get(),
            node,
            values,
            draw_ctx.get_cairo_context().get_matrix(),
            draw_ctx,
            clipping,
            &mut |dc| {
                // we don't push a layer because draw_in_viewport() already does it
                node.draw_children(cascaded, dc, clipping)
            },
        )
    }
}

pub struct NodeUse {
    link: RefCell<Option<String>>,
    x: Cell<Length>,
    y: Cell<Length>,
    w: Cell<Option<Length>>,
    h: Cell<Option<Length>>,
}

impl NodeUse {
    pub fn new() -> NodeUse {
        NodeUse {
            link: RefCell::new(None),
            x: Cell::new(Length::default()),
            y: Cell::new(Length::default()),
            w: Cell::new(None),
            h: Cell::new(None),
        }
    }
}

impl NodeTrait for NodeUse {
    fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag<'_>) -> NodeResult {
        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::XlinkHref => *self.link.borrow_mut() = Some(value.to_owned()),

                Attribute::X => self.x.set(parse("x", value, LengthDir::Horizontal)?),
                Attribute::Y => self.y.set(parse("y", value, LengthDir::Vertical)?),

                Attribute::Width => self.w.set(
                    parse_and_validate(
                        "width",
                        value,
                        LengthDir::Horizontal,
                        Length::check_nonnegative,
                    ).map(Some)?,
                ),
                Attribute::Height => self.h.set(
                    parse_and_validate(
                        "height",
                        value,
                        LengthDir::Vertical,
                        Length::check_nonnegative,
                    ).map(Some)?,
                ),

                _ => (),
            }
        }

        Ok(())
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx<'_>,
        clipping: bool,
    ) -> Result<(), RenderingError> {
        let values = cascaded.get();

        let link = self.link.borrow();

        if link.is_none() {
            return Ok(());
        }

        if let Some(acquired) = draw_ctx.get_acquired_node(link.as_ref().unwrap()) {
            let child = acquired.get();

            if Node::is_ancestor(node.clone(), child.clone()) {
                // or, if we're <use>'ing ourselves
                return Err(RenderingError::CircularReference);
            }

            draw_ctx.increase_num_elements_rendered_through_use(1);

            let params = draw_ctx.get_view_params();

            let nx = self.x.get().normalize(values, &params);
            let ny = self.y.get().normalize(values, &params);

            // If attributes ‘width’ and/or ‘height’ are not specified,
            // [...] use values of '100%' for these attributes.
            // From https://www.w3.org/TR/SVG/struct.html#UseElement in
            // "If the ‘use’ element references a ‘symbol’ element"

            let nw = self
                .w
                .get()
                .unwrap_or_else(|| Length::parse_str("100%", LengthDir::Horizontal).unwrap())
                .normalize(values, &params);
            let nh = self
                .h
                .get()
                .unwrap_or_else(|| Length::parse_str("100%", LengthDir::Vertical).unwrap())
                .normalize(values, &params);

            // width or height set to 0 disables rendering of the element
            // https://www.w3.org/TR/SVG/struct.html#UseElementWidthAttribute
            if nw.approx_eq_cairo(&0.0) || nh.approx_eq_cairo(&0.0) {
                return Ok(());
            }

            if child.get_type() != NodeType::Symbol {
                let cr = draw_ctx.get_cairo_context();
                cr.translate(nx, ny);

                draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
                    dc.draw_node_from_stack(
                        &CascadedValues::new_from_values(&child, values),
                        &child,
                        clipping,
                    )
                })
            } else {
                child.with_impl(|symbol: &NodeSymbol| {
                    let do_clip = !values.is_overflow()
                        || (values.overflow == Overflow::Visible && child.is_overflow());

                    draw_in_viewport(
                        nx,
                        ny,
                        nw,
                        nh,
                        ClipMode::ClipToVbox,
                        do_clip,
                        symbol.vbox.get(),
                        symbol.preserve_aspect_ratio.get(),
                        node,
                        values,
                        draw_ctx.get_cairo_context().get_matrix(),
                        draw_ctx,
                        clipping,
                        &mut |dc| {
                            // We don't push a layer because draw_in_viewport() already does it
                            child.draw_children(
                                &CascadedValues::new_from_values(&child, values),
                                dc,
                                clipping,
                            )
                        },
                    )
                })
            }
        } else {
            Ok(())
        }
    }
}

pub struct NodeSymbol {
    preserve_aspect_ratio: Cell<AspectRatio>,
    vbox: Cell<Option<ViewBox>>,
}

impl NodeSymbol {
    pub fn new() -> NodeSymbol {
        NodeSymbol {
            preserve_aspect_ratio: Cell::new(AspectRatio::default()),
            vbox: Cell::new(None),
        }
    }
}

impl NodeTrait for NodeSymbol {
    fn set_atts(
        &self,
        node: &RsvgNode,
        _: *const RsvgHandle,
        pbag: &PropertyBag<'_>,
    ) -> NodeResult {
        // symbol element has overflow:hidden
        // https://www.w3.org/TR/SVG/styling.html#UAStyleSheet
        node.set_overflow_hidden();

        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::PreserveAspectRatio => {
                    self.preserve_aspect_ratio
                        .set(parse("preserveAspectRatio", value, ())?)
                }

                Attribute::ViewBox => self.vbox.set(parse("viewBox", value, ()).map(Some)?),

                _ => (),
            }
        }

        Ok(())
    }
}

#[no_mangle]
pub extern "C" fn rsvg_node_svg_get_size(
    raw_node: *const RsvgNode,
    dpi_x: libc::c_double,
    dpi_y: libc::c_double,
    out_width: *mut i32,
    out_height: *mut i32,
) -> glib_sys::gboolean {
    assert!(!raw_node.is_null());
    let node: &RsvgNode = unsafe { &*raw_node };

    assert!(!out_width.is_null());
    assert!(!out_height.is_null());

    node.with_impl(
        |svg: &NodeSvg| match (svg.w.get(), svg.h.get(), svg.vbox.get()) {
            (w, h, Some(vb)) => {
                unsafe {
                    *out_width = w.hand_normalize(dpi_x, vb.0.width, 12.0).round() as i32;
                    *out_height = h.hand_normalize(dpi_y, vb.0.height, 12.0).round() as i32;
                }
                true.to_glib()
            }
            (w, h, None) if w.unit != LengthUnit::Percent && h.unit != LengthUnit::Percent => {
                unsafe {
                    *out_width = w.hand_normalize(dpi_x, 0.0, 12.0).round() as i32;
                    *out_height = h.hand_normalize(dpi_y, 0.0, 12.0).round() as i32;
                }
                true.to_glib()
            }
            (_, _, _) => false.to_glib(),
        },
    )
}
<commit_msg>NodeUse: release the acquired child as soon as possible<commit_after>use std::cell::Cell;
use std::cell::RefCell;

use glib::translate::*;
use glib_sys;

use aspect_ratio::*;
use attributes::Attribute;
use drawing_ctx::DrawingCtx;
use error::RenderingError;
use float_eq_cairo::ApproxEqCairo;
use handle::RsvgHandle;
use length::*;
use libc;
use node::*;
use parsers::{parse, parse_and_validate, Parse};
use property_bag::{OwnedPropertyBag, PropertyBag};
use state::Overflow;
use viewbox::*;
use viewport::{draw_in_viewport, ClipMode};

pub struct NodeGroup();

impl NodeGroup {
    pub fn new() -> NodeGroup {
        NodeGroup()
    }
}

impl NodeTrait for NodeGroup {
    fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, _: &PropertyBag<'_>) -> NodeResult {
        Ok(())
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx<'_>,
        clipping: bool,
    ) -> Result<(), RenderingError> {
        let values = cascaded.get();

        draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
            node.draw_children(cascaded, dc, clipping)
        })
    }
}

pub struct NodeDefs();

impl NodeDefs {
    pub fn new() -> NodeDefs {
        NodeDefs()
    }
}

impl NodeTrait for NodeDefs {
    fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, _: &PropertyBag<'_>) -> NodeResult {
        Ok(())
    }
}

pub struct NodeSwitch();

impl NodeSwitch {
    pub fn new() -> NodeSwitch {
        NodeSwitch()
    }
}

impl NodeTrait for NodeSwitch {
    fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, _: &PropertyBag<'_>) -> NodeResult {
        Ok(())
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx<'_>,
        clipping: bool,
    ) -> Result<(), RenderingError> {
        let values = cascaded.get();

        draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
            if let Some(child) = node.children().find(|c| c.get_cond()) {
                dc.draw_node_from_stack(&CascadedValues::new(cascaded, &child), &child, clipping)
            } else {
                Ok(())
            }
        })
    }
}

pub struct NodeSvg {
    preserve_aspect_ratio: Cell<AspectRatio>,
    x: Cell<Length>,
    y: Cell<Length>,
    w: Cell<Length>,
    h: Cell<Length>,
    vbox: Cell<Option<ViewBox>>,
    pbag: RefCell<Option<OwnedPropertyBag>>,
}

impl NodeSvg {
    pub fn new() -> NodeSvg {
        NodeSvg {
            preserve_aspect_ratio: Cell::new(AspectRatio::default()),
            x: Cell::new(Length::parse_str("0", LengthDir::Horizontal).unwrap()),
            y: Cell::new(Length::parse_str("0", LengthDir::Vertical).unwrap()),
            w: Cell::new(Length::parse_str("100%", LengthDir::Horizontal).unwrap()),
            h: Cell::new(Length::parse_str("100%", LengthDir::Vertical).unwrap()),
            vbox: Cell::new(None),
            pbag: RefCell::new(None),
        }
    }

    pub fn parse_style_attributes(&self, node: &RsvgNode, handle: *const RsvgHandle) {
        if let Some(owned_pbag) = self.pbag.borrow().as_ref() {
            let pbag = PropertyBag::from_owned(owned_pbag);
            node.parse_style_attributes(handle, "svg", &pbag);
        }
    }
}

impl NodeTrait for NodeSvg {
    fn set_atts(
        &self,
        node: &RsvgNode,
        _: *const RsvgHandle,
        pbag: &PropertyBag<'_>,
    ) -> NodeResult {
        // SVG element has overflow:hidden
        // https://www.w3.org/TR/SVG/styling.html#UAStyleSheet
        node.set_overflow_hidden();

        // x & y attributes have no effect on outermost svg
        // http://www.w3.org/TR/SVG/struct.html#SVGElement
        let is_inner_svg = node.get_parent().is_some();

        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::PreserveAspectRatio => {
                    self.preserve_aspect_ratio
                        .set(parse("preserveAspectRatio", value, ())?)
                }

                Attribute::X => {
                    if is_inner_svg {
                        self.x.set(parse("x", value, LengthDir::Horizontal)?);
                    }
                }

                Attribute::Y => {
                    if is_inner_svg {
                        self.y.set(parse("y", value, LengthDir::Vertical)?);
                    }
                }

                Attribute::Width => self.w.set(parse_and_validate(
                    "width",
                    value,
                    LengthDir::Horizontal,
                    Length::check_nonnegative,
                )?),

                Attribute::Height => self.h.set(parse_and_validate(
                    "height",
                    value,
                    LengthDir::Vertical,
                    Length::check_nonnegative,
                )?),

                Attribute::ViewBox => self.vbox.set(parse("viewBox", value, ()).map(Some)?),

                _ => (),
            }
        }

        // The "style" sub-element is not loaded yet here, so we need
        // to store other attributes to be applied later.
        *self.pbag.borrow_mut() = Some(pbag.to_owned());

        Ok(())
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx<'_>,
        clipping: bool,
    ) -> Result<(), RenderingError> {
        let values = cascaded.get();

        let params = draw_ctx.get_view_params();

        let nx = self.x.get().normalize(values, &params);
        let ny = self.y.get().normalize(values, &params);
        let nw = self.w.get().normalize(values, &params);
        let nh = self.h.get().normalize(values, &params);

        let do_clip = !values.is_overflow() && node.get_parent().is_some();

        draw_in_viewport(
            nx,
            ny,
            nw,
            nh,
            ClipMode::ClipToViewport,
            do_clip,
            self.vbox.get(),
            self.preserve_aspect_ratio.get(),
            node,
            values,
            draw_ctx.get_cairo_context().get_matrix(),
            draw_ctx,
            clipping,
            &mut |dc| {
                // we don't push a layer because draw_in_viewport() already does it
                node.draw_children(cascaded, dc, clipping)
            },
        )
    }
}

pub struct NodeUse {
    link: RefCell<Option<String>>,
    x: Cell<Length>,
    y: Cell<Length>,
    w: Cell<Option<Length>>,
    h: Cell<Option<Length>>,
}

impl NodeUse {
    pub fn new() -> NodeUse {
        NodeUse {
            link: RefCell::new(None),
            x: Cell::new(Length::default()),
            y: Cell::new(Length::default()),
            w: Cell::new(None),
            h: Cell::new(None),
        }
    }
}

impl NodeTrait for NodeUse {
    fn set_atts(&self, _: &RsvgNode, _: *const RsvgHandle, pbag: &PropertyBag<'_>) -> NodeResult {
        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::XlinkHref => *self.link.borrow_mut() = Some(value.to_owned()),

                Attribute::X => self.x.set(parse("x", value, LengthDir::Horizontal)?),
                Attribute::Y => self.y.set(parse("y", value, LengthDir::Vertical)?),

                Attribute::Width => self.w.set(
                    parse_and_validate(
                        "width",
                        value,
                        LengthDir::Horizontal,
                        Length::check_nonnegative,
                    ).map(Some)?,
                ),
                Attribute::Height => self.h.set(
                    parse_and_validate(
                        "height",
                        value,
                        LengthDir::Vertical,
                        Length::check_nonnegative,
                    ).map(Some)?,
                ),

                _ => (),
            }
        }

        Ok(())
    }

    fn draw(
        &self,
        node: &RsvgNode,
        cascaded: &CascadedValues<'_>,
        draw_ctx: &mut DrawingCtx<'_>,
        clipping: bool,
    ) -> Result<(), RenderingError> {
        let values = cascaded.get();

        let link = self.link.borrow();

        if link.is_none() {
            return Ok(());
        }

        let child = if let Some(acquired) = draw_ctx.get_acquired_node(link.as_ref().unwrap()) {
            // Here we clone the acquired child, so that we can drop the AcquiredNode as
            // early as possible.  This is so that the child's drawing method will be able
            // to re-acquire the child for other purposes.
            acquired.get().clone()
        } else {
            return Ok(());
        };

        if Node::is_ancestor(node.clone(), child.clone()) {
            // or, if we're <use>'ing ourselves
            return Err(RenderingError::CircularReference);
        }

        draw_ctx.increase_num_elements_rendered_through_use(1);

        let params = draw_ctx.get_view_params();

        let nx = self.x.get().normalize(values, &params);
        let ny = self.y.get().normalize(values, &params);

        // If attributes ‘width’ and/or ‘height’ are not specified,
        // [...] use values of '100%' for these attributes.
        // From https://www.w3.org/TR/SVG/struct.html#UseElement in
        // "If the ‘use’ element references a ‘symbol’ element"

        let nw = self
            .w
            .get()
            .unwrap_or_else(|| Length::parse_str("100%", LengthDir::Horizontal).unwrap())
            .normalize(values, &params);
        let nh = self
            .h
            .get()
            .unwrap_or_else(|| Length::parse_str("100%", LengthDir::Vertical).unwrap())
            .normalize(values, &params);

        // width or height set to 0 disables rendering of the element
        // https://www.w3.org/TR/SVG/struct.html#UseElementWidthAttribute
        if nw.approx_eq_cairo(&0.0) || nh.approx_eq_cairo(&0.0) {
            return Ok(());
        }

        if child.get_type() != NodeType::Symbol {
            let cr = draw_ctx.get_cairo_context();
            cr.translate(nx, ny);

            draw_ctx.with_discrete_layer(node, values, clipping, &mut |dc| {
                dc.draw_node_from_stack(
                    &CascadedValues::new_from_values(&child, values),
                    &child,
                    clipping,
                )
            })
        } else {
            child.with_impl(|symbol: &NodeSymbol| {
                let do_clip = !values.is_overflow()
                    || (values.overflow == Overflow::Visible && child.is_overflow());

                draw_in_viewport(
                    nx,
                    ny,
                    nw,
                    nh,
                    ClipMode::ClipToVbox,
                    do_clip,
                    symbol.vbox.get(),
                    symbol.preserve_aspect_ratio.get(),
                    node,
                    values,
                    draw_ctx.get_cairo_context().get_matrix(),
                    draw_ctx,
                    clipping,
                    &mut |dc| {
                        // We don't push a layer because draw_in_viewport() already does it
                        child.draw_children(
                            &CascadedValues::new_from_values(&child, values),
                            dc,
                            clipping,
                        )
                    },
                )
            })
        }
    }
}

pub struct NodeSymbol {
    preserve_aspect_ratio: Cell<AspectRatio>,
    vbox: Cell<Option<ViewBox>>,
}

impl NodeSymbol {
    pub fn new() -> NodeSymbol {
        NodeSymbol {
            preserve_aspect_ratio: Cell::new(AspectRatio::default()),
            vbox: Cell::new(None),
        }
    }
}

impl NodeTrait for NodeSymbol {
    fn set_atts(
        &self,
        node: &RsvgNode,
        _: *const RsvgHandle,
        pbag: &PropertyBag<'_>,
    ) -> NodeResult {
        // symbol element has overflow:hidden
        // https://www.w3.org/TR/SVG/styling.html#UAStyleSheet
        node.set_overflow_hidden();

        for (_key, attr, value) in pbag.iter() {
            match attr {
                Attribute::PreserveAspectRatio => {
                    self.preserve_aspect_ratio
                        .set(parse("preserveAspectRatio", value, ())?)
                }

                Attribute::ViewBox => self.vbox.set(parse("viewBox", value, ()).map(Some)?),

                _ => (),
            }
        }

        Ok(())
    }
}

#[no_mangle]
pub extern "C" fn rsvg_node_svg_get_size(
    raw_node: *const RsvgNode,
    dpi_x: libc::c_double,
    dpi_y: libc::c_double,
    out_width: *mut i32,
    out_height: *mut i32,
) -> glib_sys::gboolean {
    assert!(!raw_node.is_null());
    let node: &RsvgNode = unsafe { &*raw_node };

    assert!(!out_width.is_null());
    assert!(!out_height.is_null());

    node.with_impl(
        |svg: &NodeSvg| match (svg.w.get(), svg.h.get(), svg.vbox.get()) {
            (w, h, Some(vb)) => {
                unsafe {
                    *out_width = w.hand_normalize(dpi_x, vb.0.width, 12.0).round() as i32;
                    *out_height = h.hand_normalize(dpi_y, vb.0.height, 12.0).round() as i32;
                }
                true.to_glib()
            }
            (w, h, None) if w.unit != LengthUnit::Percent && h.unit != LengthUnit::Percent => {
                unsafe {
                    *out_width = w.hand_normalize(dpi_x, 0.0, 12.0).round() as i32;
                    *out_height = h.hand_normalize(dpi_y, 0.0, 12.0).round() as i32;
                }
                true.to_glib()
            }
            (_, _, _) => false.to_glib(),
        },
    )
}
<|endoftext|>


<commit_before>use mio::*;
use std::cell::RefCell;
use std::io;
use std::rc::Rc;
use std::time::Duration;
use slab::Slab;

pub trait EventHandler {
    fn on_ready(&self, selector: &mut Selector, event: Event);
}

impl<F> EventHandler for F where F: Fn(&mut Selector, Event) {
    fn on_ready(&self, selector: &mut Selector, event: Event) {
        self(selector, event);
    }
}

// for convenience
impl EventHandler for Rc<RefCell<EventHandler>> {
    fn on_ready(&self, selector: &mut Selector, event: Event) {
        let mut self_raw = self.borrow_mut();
        self_raw.on_ready(selector, event);
    }
}

pub struct Selector {
    poll: Poll,
    handlers: Slab<Rc<EventHandler>, Token>,
}

impl Selector {
    pub fn new() -> io::Result<Self> {
        Ok(Self {
            poll: Poll::new()?,
            handlers: Slab::with_capacity(1024),
        })
    }

    pub fn register<E, H>(&mut self, handle: &E, handler: H,
                   interest: Ready, opts: PollOpt) -> io::Result<Token>
            where E: Evented + ?Sized,
                  H: EventHandler + 'static {
        let token = self.handlers.insert(Rc::new(handler))
                        .map_err(|_| io::Error::new(io::ErrorKind::Other, "Cannot allocate slab slot"))?;
        self.poll.register(handle, token, interest, opts)?;
        Ok(token)
    }

    pub fn reregister<E>(&self, handle: &E, token: Token,
                   interest: Ready, opts: PollOpt) -> io::Result<()>
            where E: Evented + ?Sized {
        self.poll.reregister(handle, token, interest, opts)
    }

    pub fn deregister<E>(&mut self, handle: &E, token: Token) -> io::Result<()>
            where E: Evented + ?Sized {
        if self.handlers.remove(token).is_some() {
            panic!("Unknown token removed");
        }
        self.poll.deregister(handle)
    }

    pub fn poll(&mut self, events: &mut Events, timeout: Option<Duration>) -> io::Result<usize> {
        self.poll.poll(events, timeout)
    }

    pub fn run_handler(&mut self, event: Event) {
        let mut handler = self.handlers.get_mut(event.token()).unwrap().clone();
        handler.on_ready(self, event);
    }
}
<commit_msg>Improve Selector.deregister()<commit_after>use mio::*;
use std::cell::RefCell;
use std::io;
use std::rc::Rc;
use std::time::Duration;
use slab::Slab;

pub trait EventHandler {
    fn on_ready(&self, selector: &mut Selector, event: Event);
}

impl<F> EventHandler for F where F: Fn(&mut Selector, Event) {
    fn on_ready(&self, selector: &mut Selector, event: Event) {
        self(selector, event);
    }
}

// for convenience
impl EventHandler for Rc<RefCell<EventHandler>> {
    fn on_ready(&self, selector: &mut Selector, event: Event) {
        let mut self_raw = self.borrow_mut();
        self_raw.on_ready(selector, event);
    }
}

pub struct Selector {
    poll: Poll,
    handlers: Slab<Rc<EventHandler>, Token>,
}

impl Selector {
    pub fn new() -> io::Result<Self> {
        Ok(Self {
            poll: Poll::new()?,
            handlers: Slab::with_capacity(1024),
        })
    }

    pub fn register<E, H>(&mut self, handle: &E, handler: H,
                   interest: Ready, opts: PollOpt) -> io::Result<Token>
            where E: Evented + ?Sized,
                  H: EventHandler + 'static {
        let token = self.handlers.insert(Rc::new(handler))
                        .map_err(|_| io::Error::new(io::ErrorKind::Other, "Cannot allocate slab slot"))?;
        self.poll.register(handle, token, interest, opts)?;
        Ok(token)
    }

    pub fn reregister<E>(&self, handle: &E, token: Token,
                   interest: Ready, opts: PollOpt) -> io::Result<()>
            where E: Evented + ?Sized {
        self.poll.reregister(handle, token, interest, opts)
    }

    pub fn deregister<E>(&mut self, handle: &E, token: Token) -> io::Result<()>
            where E: Evented + ?Sized {
        self.handlers.remove(token).expect("Unknown token removed");
        self.poll.deregister(handle)
    }

    pub fn poll(&mut self, events: &mut Events, timeout: Option<Duration>) -> io::Result<usize> {
        self.poll.poll(events, timeout)
    }

    pub fn run_handler(&mut self, event: Event) {
        let mut handler = self.handlers.get_mut(event.token()).unwrap().clone();
        handler.on_ready(self, event);
    }
}
<|endoftext|>


<commit_before>// xfail-fast  (compile-flags unsupported on windows)
// compile-flags:--borrowck=err
// exec-env:RUST_POISON_ON_FREE=1

fn main() {
    let x: @mut @option<~int> = @mut @none;
    alt x {
      @@some(y) {
        // here, the refcount of `*x` is bumped so
        // `y` remains valid even if `*x` is modified.
        *x = @none;
      }

      @@none {
        // here, no bump of the ref count of `*x` is needed, but in
        // fact a bump occurs anyway because of how pattern marching
        // works.
      }
    }
}<commit_msg>remove line so that pretty printer doesn't mess it up<commit_after>// xfail-fast   (compile-flags unsupported on windows)
// compile-flags:--borrowck=err
// exec-env:RUST_POISON_ON_FREE=1

fn main() {
    let x: @mut @option<~int> = @mut @none;
    alt x {
      @@some(y) {
        // here, the refcount of `*x` is bumped so
        // `y` remains valid even if `*x` is modified.
        *x = @none;
      }
      @@none {
        // here, no bump of the ref count of `*x` is needed, but in
        // fact a bump occurs anyway because of how pattern marching
        // works.
      }
    }
}<|endoftext|>


<commit_before>use std::os::getenv;

struct HttpContext{
    request: Request,
    response: Response
}

impl HttpContext{
    fn create() -> HttpContext{
        HttpContext{
            request: Request::populate(),
            response: Response::new()
        }
    }
}

struct Request {
    path: ~str,
    querystring: ~str
}

impl Request {
    fn populate() -> Request {
        Request{
            path: getenv("PATH_INFO").unwrap_or(~""),
            querystring: getenv("QUERY_STRING").unwrap_or(~"")
        }
    }
}

struct Response{
    contenttype: ~str,
    body: ~str
}

impl Response{
    fn new() -> Response{
        Response{contenttype: ~"text/plain", body: ~""}
    }
}

struct Route {
    path: ~str,
    handler: ~fn(&Request, &mut Response)
}

struct Router{
    routes: ~[Route],
}

impl Router{
    fn new() -> Router{
        Router{routes: ~[]}
    }
    fn add(&mut self, r: Route){
        self.routes.push(r);
    }
    fn execute(&self, req: &Request, res: &mut Response) {
        for route in self.routes.iter(){
            if(route.path == req.path){
                (route.handler)(req, res);
            }
        }
    }
    fn controller<T>(@self, creator: ~fn(&HttpContext) -> T) -> ControllerBox<T>
    {
        ControllerBox{
            router: self,
            route: ~Route{path: ~"", handler: default_handler},
            creator: creator
        }
    }
}

trait HttpController{

}

struct ControllerBox<T>{
    router: @Router,
    route: ~Route,
    creator: ~fn(&HttpContext) -> T
}

impl<T> ControllerBox<T>{

}

fn default_handler(r: &Request, res: &mut Response){
    res.body.push_str("404 not found");
}

fn index(r: &Request,res: &mut Response){
    res.body.push_str("yay index");
}

fn foo(r: &Request, res: &mut Response){
    res.body.push_str("yay foo");
}

fn main() {
    let req=Request::populate();
    let mut res=Response::new();
    let mut router=Router::new();
    router.add(Route{path: ~"", handler: index});
    router.add(Route{path: ~"/foo", handler: foo});
    router.execute(&req, &mut res);
    println(res.contenttype);
    println("");
    println(res.body);
}<commit_msg>Very close, but doesn't compile :(<commit_after>use std::os::getenv;

struct HttpContext{
    request: Request,
    response: Response
}

impl HttpContext{
    fn create() -> HttpContext{
        HttpContext{
            request: Request::populate(),
            response: Response::new()
        }
    }
}

struct Request {
    path: ~str,
    querystring: ~str
}

impl Request {
    fn populate() -> Request {
        Request{
            path: getenv("PATH_INFO").unwrap_or(~""),
            querystring: getenv("QUERY_STRING").unwrap_or(~"")
        }
    }
}

struct Response{
    contenttype: ~str,
    body: ~str
}

impl Response{
    fn new() -> Response{
        Response{contenttype: ~"text/plain", body: ~""}
    }
}

struct Route {
    path: ~str,
    handler: ~fn(&mut HttpContext)
}

struct Router{
    routes: ~[Route],
}

impl Router{
    fn new() -> Router{
        Router{routes: ~[]}
    }
    fn add(&mut self, r: Route){
        self.routes.push(r);
    }
    fn execute(&self, c: &mut HttpContext) {
        for route in self.routes.iter(){
            if(route.path == c.request.path){
                (route.handler)(c);
            }
        }
    }
    fn controller<T>(~self, creator: ~fn(&HttpContext) -> T) -> ControllerBox<T>
    {
        ControllerBox{
            router: self,
            route: ~Route{path: ~"", handler: default_handler},
            creator: Some(creator)
        }
    }
}

trait HttpController{

}

struct ControllerBox<T>{
    router: ~Router,
    route: ~Route,
    creator: Option<~fn(&HttpContext) -> T>
}

impl<T> ControllerBox<T>{
    fn handles(@mut self, path: ~str) -> @mut ControllerBox<T>{
        self.route.path=path;
        self
    }
    fn with<'r>(&'r mut self, invoker: ~fn(&T)) -> &'r mut ControllerBox<T>{
        let tmp=self.creator.take();

        self.route.handler = |c| {
            match tmp {
                None => (),
                Some(t) => {
                    let ctrl=(t)(c);
                    invoker(&ctrl);
                }
            };
        };
        self
    }
}
/*
struct Meh{
    biz: ~fn(int) -> int
}

impl Meh{
    fn foo(@mut self
}
*/

fn default_handler(context: &mut HttpContext){
    context.response.body.push_str("404 not found");
}

fn index(context: &mut HttpContext){
    context.response.body.push_str("yay index");
}

fn foo(context: &mut HttpContext){
    context.response.body.push_str("yay foo");
}

fn main() {
    let mut context=HttpContext::create();
    let mut router=Router::new();
    router.add(Route{path: ~"", handler: index});
    router.add(Route{path: ~"/foo", handler: foo});
    router.execute(&mut context);
    println(context.response.contenttype);
    println("");
    println(context.response.body);
}<|endoftext|>


<commit_before>use std::iter;

pub type Domino = (usize, usize);

/// A table keeping track of available dominoes.
///
/// Effectively a 6x6 matrix. Each position denotes whether a domino is available with that column
/// dots and row dots. Positions are mirrored ((3,4) == (4,3)), except for positions with equal row
/// and column numbers.
struct AvailabilityTable {
    m: Vec<usize>
}

impl AvailabilityTable {
    fn new() -> AvailabilityTable {
        AvailabilityTable { m: iter::repeat(0).take(6 * 6).collect() }
    }

    fn get(&self, x: usize, y: usize) -> usize {
        self.m[(x-1) * 6 + (y-1)]
    }

    fn set(&mut self, x: usize, y: usize, v: usize) {
        let m = &mut self.m[..];
        m[(x-1) * 6 + (y-1)] = v;
    }

    fn add(&mut self, x: usize, y: usize) {
        if x == y {
            let n = self.get(x, y);
            self.set(x, y, n + 1) // Along the diagonal
        }
        else {
            let m = self.get(x, y);
            self.set(x, y, m + 1);
            let n = self.get(y, x);
            self.set(y, x, n + 1);
        }
    }

    fn remove(&mut self, x: usize, y: usize) {
        if self.get(x, y) > 0 {
            if x == y {
                let n = self.get(x, y);
                self.set(x, y, n - 1) // Along the diagonal
            }
            else {
                let m = self.get(x, y);
                self.set(x, y, m - 1);
                let n = self.get(y, x);
                self.set(y, x, n - 1);
            }
        }
        else {
            // For this toy code hard explicit fail is best
            panic!("remove for 0 stones: ({:?}, {:?})", x, y)
        }
    }

    fn pop_first(&mut self, x: usize) -> Option<usize> {
        for y in 1 .. 7 {
            if self.get(x, y) > 0 {
                self.remove(x, y);
                return Some(y)
            }
        }
        None
    }
}

pub fn chain(dominoes: &Vec<Domino>) -> Option<Vec<Domino>> {
    match dominoes.len() {
        0 => Some(vec!()),
        1 => if dominoes[0].0 == dominoes[0].1 { Some(vec![dominoes[0]]) } else { None },
        _ => {
            // First check if the total number of each amount of dots is even, if not it's not
            // possible to complete a cycle. This follows from that it's an Eulerian path.
            let mut v: Vec<usize> = vec!(0, 0, 0, 0, 0, 0);
            // Keep the mutable borrow in a small scope here to allow v.iter().
            {
                let vs = &mut v[..];
                for dom in dominoes.iter() {
                    vs[dom.0 - 1] += 1;
                    vs[dom.1 - 1] += 1;
                }
            }
            for n in v.iter() {
                if n % 2 != 0 {
                    return None
                }
            }
            let chain = chain_worker(dominoes);
            if chain.len() == dominoes.len() {
                Some(chain)
            }
            else {
                None
            }
        }
    }
}

fn chain_worker(dominoes: &Vec<Domino>) -> Vec<Domino> {
    let mut doms = dominoes.clone();
    let first = doms.pop().unwrap();
    let mut t = AvailabilityTable::new();
    for dom in doms.iter() {
        t.add(dom.0, dom.1)

    }
    let mut v: Vec<Domino> = Vec::new();
    v.push(first);
    let mut n = first.1; // Number to connect to
    loop {
        match t.pop_first(n) {
            None => break,
            Some(m) => {
                v.push((n, m));
                n = m;
            }
        }
    }
    v
}
<commit_msg>dominoes: Use while let<commit_after>use std::iter;

pub type Domino = (usize, usize);

/// A table keeping track of available dominoes.
///
/// Effectively a 6x6 matrix. Each position denotes whether a domino is available with that column
/// dots and row dots. Positions are mirrored ((3,4) == (4,3)), except for positions with equal row
/// and column numbers.
struct AvailabilityTable {
    m: Vec<usize>
}

impl AvailabilityTable {
    fn new() -> AvailabilityTable {
        AvailabilityTable { m: iter::repeat(0).take(6 * 6).collect() }
    }

    fn get(&self, x: usize, y: usize) -> usize {
        self.m[(x-1) * 6 + (y-1)]
    }

    fn set(&mut self, x: usize, y: usize, v: usize) {
        let m = &mut self.m[..];
        m[(x-1) * 6 + (y-1)] = v;
    }

    fn add(&mut self, x: usize, y: usize) {
        if x == y {
            let n = self.get(x, y);
            self.set(x, y, n + 1) // Along the diagonal
        }
        else {
            let m = self.get(x, y);
            self.set(x, y, m + 1);
            let n = self.get(y, x);
            self.set(y, x, n + 1);
        }
    }

    fn remove(&mut self, x: usize, y: usize) {
        if self.get(x, y) > 0 {
            if x == y {
                let n = self.get(x, y);
                self.set(x, y, n - 1) // Along the diagonal
            }
            else {
                let m = self.get(x, y);
                self.set(x, y, m - 1);
                let n = self.get(y, x);
                self.set(y, x, n - 1);
            }
        }
        else {
            // For this toy code hard explicit fail is best
            panic!("remove for 0 stones: ({:?}, {:?})", x, y)
        }
    }

    fn pop_first(&mut self, x: usize) -> Option<usize> {
        for y in 1 .. 7 {
            if self.get(x, y) > 0 {
                self.remove(x, y);
                return Some(y)
            }
        }
        None
    }
}

pub fn chain(dominoes: &Vec<Domino>) -> Option<Vec<Domino>> {
    match dominoes.len() {
        0 => Some(vec!()),
        1 => if dominoes[0].0 == dominoes[0].1 { Some(vec![dominoes[0]]) } else { None },
        _ => {
            // First check if the total number of each amount of dots is even, if not it's not
            // possible to complete a cycle. This follows from that it's an Eulerian path.
            let mut v: Vec<usize> = vec!(0, 0, 0, 0, 0, 0);
            // Keep the mutable borrow in a small scope here to allow v.iter().
            {
                let vs = &mut v[..];
                for dom in dominoes.iter() {
                    vs[dom.0 - 1] += 1;
                    vs[dom.1 - 1] += 1;
                }
            }
            for n in v.iter() {
                if n % 2 != 0 {
                    return None
                }
            }
            let chain = chain_worker(dominoes);
            if chain.len() == dominoes.len() {
                Some(chain)
            }
            else {
                None
            }
        }
    }
}

fn chain_worker(dominoes: &Vec<Domino>) -> Vec<Domino> {
    let mut doms = dominoes.clone();
    let first = doms.pop().unwrap();
    let mut t = AvailabilityTable::new();
    for dom in doms.iter() {
        t.add(dom.0, dom.1)

    }
    let mut v: Vec<Domino> = Vec::new();
    v.push(first);
    let mut n = first.1; // Number to connect to
    while let Some(m) = t.pop_first(n) {
        v.push((n, m));
        n = m;
    }
    v
}
<|endoftext|>


<commit_before>use std::fs;
use std::io;
use std::mem;
use std::path::Path;
use std::error;
use std::sync::Arc;
use std::cell::RefCell;
use std::collections::Bound::{Included, Unbounded};
// use std::iter::Iterator;

use leveldb::database::Database as LevelDatabase;
use leveldb::error::Error as LevelError;
use leveldb::database::iterator::Iterable as LevelIterable;
use leveldb::database::snapshots::Snapshot as LevelSnapshot;
use leveldb::options::{Options, WriteOptions, ReadOptions};
use leveldb::database::kv::KV;
use leveldb::database::batch::Writebatch;
use leveldb::batch::Batch;
use leveldb::snapshots::Snapshots;
// use leveldb::database::iterator::Iterator as LevelIterator;
use leveldb::iterator::LevelDBIterator;

use super::{Map, Database, Error, Patch, Change, Fork};
// use super::{Iterable, Seekable}

#[derive(Clone)]
pub struct LevelDB {
    db: Arc<LevelDatabase>,
}

pub struct LevelDBView {
    _db: Arc<LevelDatabase>,
    snap: LevelSnapshot<'static>,
    changes: RefCell<Patch>,
}

const LEVELDB_READ_OPTIONS: ReadOptions<'static> = ReadOptions {
    verify_checksums: false,
    fill_cache: true,
    snapshot: None,
};
const LEVELDB_WRITE_OPTIONS: WriteOptions = WriteOptions { sync: false };

impl From<LevelError> for Error {
    fn from(err: LevelError) -> Self {
        Error::new(error::Error::description(&err))
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Self {
        Error::new(error::Error::description(&err))
    }
}

impl LevelDB {
    pub fn new(path: &Path, options: Options) -> Result<LevelDB, Error> {
        if options.create_if_missing {
            fs::create_dir_all(path)?;
        }
        let database = LevelDatabase::open(path, options)?;
        Ok(LevelDB { db: Arc::new(database) })
    }
}

impl LevelDBView {
    pub fn new(from: &LevelDB) -> LevelDBView {
        LevelDBView {
            _db: from.db.clone(),
            snap: unsafe { mem::transmute(from.db.snapshot()) },
            changes: RefCell::default(),
        }
    }
}

// FIXME: remove this implementation
impl Map<[u8], Vec<u8>> for LevelDB {
    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        self.db
            .get(LEVELDB_READ_OPTIONS, key)
            .map_err(Into::into)
    }

    fn put(&self, key: &[u8], value: Vec<u8>) -> Result<(), Error> {
        let result = self.db.put(LEVELDB_WRITE_OPTIONS, key, &value);
        result.map_err(Into::into)
    }

    fn delete(&self, key: &[u8]) -> Result<(), Error> {
        let result = self.db.delete(LEVELDB_WRITE_OPTIONS, key);
        result.map_err(Into::into)
    }
    fn find_key(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        let it = self.db.keys_iter(LEVELDB_READ_OPTIONS);
        it.seek(key);
        if it.valid() {
            let key = it.key();
            return Ok(Some(key.to_vec()));
        }
        Ok(None)
    }
}

impl Map<[u8], Vec<u8>> for LevelDBView {
    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        match self.changes.borrow().get(key) {
            Some(change) => {
                let v = match *change {
                    Change::Put(ref v) => Some(v.clone()),
                    Change::Delete => None,
                };
                Ok(v)
            }
            None => {
                self.snap
                    .get(LEVELDB_READ_OPTIONS, key)
                    .map_err(Into::into)
            }
        }
    }

    fn put(&self, key: &[u8], value: Vec<u8>) -> Result<(), Error> {
        self.changes.borrow_mut().insert(key.to_vec(), Change::Put(value));
        Ok(())
    }

    fn delete(&self, key: &[u8]) -> Result<(), Error> {
        self.changes.borrow_mut().insert(key.to_vec(), Change::Delete);
        Ok(())
    }

    fn find_key(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        // TODO merge with the same function in memorydb
        let out = {
            let map = self.changes.borrow();
            let mut it = map.range::<[u8], [u8]>(Included(key), Unbounded);
            it.next().map(|x| x.0.to_vec())
        };
        if out.is_none() {
            let it = self.snap.keys_iter(LEVELDB_READ_OPTIONS);
            it.seek(key.to_vec());
            if it.valid() {
                let key = it.key();
                return Ok(Some(key.to_vec()));
            }
            Ok(None)
        } else {
            Ok(out)
        }
    }
}

impl Fork for LevelDBView {
    fn changes(&self) -> Patch {
        self.changes.borrow().clone()
    }
    fn merge(&self, patch: &Patch) {
        let iter = patch.into_iter().map(|(k, v)| (k.clone(), v.clone()));
        self.changes.borrow_mut().extend(iter);
    }
}

impl Database for LevelDB {
    type Fork = LevelDBView;

    fn fork(&self) -> Self::Fork {
        LevelDBView::new(self)
    }

    // fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
    //     self.db
    //         .get(LEVELDB_READ_OPTIONS, key)
    //         .map_err(Into::into)
    // }

    // fn put(&self, key: &[u8], value: Vec<u8>) -> Result<(), Error> {
    //     let result = self.db.put(LEVELDB_WRITE_OPTIONS, key, &value);
    //     result.map_err(Into::into)
    // }

    // fn delete(&self, key: &[u8]) -> Result<(), Error> {
    //     let result = self.db.delete(LEVELDB_WRITE_OPTIONS, key);
    //     result.map_err(Into::into)
    // }

    fn merge(&self, patch: &Patch) -> Result<(), Error> {
        let mut batch = Writebatch::new();
        for (key, change) in patch {
            match *change {
                Change::Put(ref v) => {
                    batch.put(key, v);
                }
                Change::Delete => {
                    batch.delete(key);
                }
            }
        }
        let write_opts = WriteOptions::new();
        let result = self.db.write(write_opts, &batch);
        result.map_err(Into::into)
    }
}

// pub struct DatabaseIterator<'a> {
//     iter: LevelIterator<'a, BinaryKey>
// }

// impl<'a> Iterator for DatabaseIterator<'a> {
//     type Item = (Vec<u8>, Vec<u8>);

//     fn next(&mut self) -> Option<Self::Item> {
//         let item = self.iter.next();
//         item.map(|x| ((x.0).0, x.1))
//     }
// }

// impl<'a> Iterable for &'a LevelDB {
//     type Iter = DatabaseIterator<'a>;

//     fn iter(self) -> Self::Iter {
//         DatabaseIterator {
//             iter: self.db.iter(LEVELDB_READ_OPTIONS)
//         }
//     }
// }

// impl<'a> Seekable<'a> for DatabaseIterator<'a> {
//     type Key = Vec<u8>;
//     type Item = (Vec<u8>, Vec<u8>);

//     // TODO I am not sure that optimizer will remove memory allocation here
//     fn seek(&mut self, key: &Self::Key) -> Option<Self::Item> {
//         let db_key = BinaryKey(key.to_vec());
//         self.iter.seek(&db_key);
//         Some((self.iter.key().0, self.iter.value()))
//     }
// }
<commit_msg>Starting work with iterators<commit_after>use std::fs;
use std::io;
use std::mem;
use std::path::Path;
use std::error;
use std::sync::Arc;
use std::cell::RefCell;
use std::collections::Bound::{Included, Unbounded};
use std::collections::btree_map::Range;
// use std::iter::Iterator;

use leveldb::database::Database as LevelDatabase;
use leveldb::error::Error as LevelError;
use leveldb::database::snapshots::Snapshot as LevelSnapshot;
use leveldb::options::{Options, WriteOptions, ReadOptions};
use leveldb::database::kv::KV;
use leveldb::database::batch::Writebatch;
use leveldb::batch::Batch;
use leveldb::snapshots::Snapshots;
use leveldb::database::iterator::{Iterable, LevelDBIterator as LevelDBIteratorTrait};
use leveldb::database::iterator::{Iterator as LevelIterator, KeyIterator as LevelKeys, ValueIterator as LevelValues};

use super::{Map, Database, Error, Patch, Change, Fork};
// use super::{Iterable, Seekable}

#[derive(Clone)]
pub struct LevelDB {
    db: Arc<LevelDatabase>,
}

pub struct LevelDBView {
    _db: Arc<LevelDatabase>,
    snap: LevelSnapshot<'static>,
    changes: RefCell<Patch>,
}

const LEVELDB_READ_OPTIONS: ReadOptions<'static> = ReadOptions {
    verify_checksums: false,
    fill_cache: true,
    snapshot: None,
};
const LEVELDB_WRITE_OPTIONS: WriteOptions = WriteOptions { sync: false };

impl From<LevelError> for Error {
    fn from(err: LevelError) -> Self {
        Error::new(error::Error::description(&err))
    }
}

impl From<io::Error> for Error {
    fn from(err: io::Error) -> Self {
        Error::new(error::Error::description(&err))
    }
}

impl LevelDB {
    pub fn new(path: &Path, options: Options) -> Result<LevelDB, Error> {
        if options.create_if_missing {
            fs::create_dir_all(path)?;
        }
        let database = LevelDatabase::open(path, options)?;
        Ok(LevelDB { db: Arc::new(database) })
    }
}

impl LevelDBView {
    pub fn new(from: &LevelDB) -> LevelDBView {
        LevelDBView {
            _db: from.db.clone(),
            snap: unsafe { mem::transmute(from.db.snapshot()) },
            changes: RefCell::default(),
        }
    }

    fn iter(&self) -> LevelDBIterator {
        LevelDBIterator {
            db: self.snap.iter(LEVELDB_READ_OPTIONS),
            // FIXME: remove this bullshit!
            changes: unsafe {
                self.changes.as_ptr().as_ref().unwrap().range::<Vec<u8>, Vec<u8>>(Unbounded, Unbounded)
            }
        }
    }
}

// FIXME: remove this implementation
impl Map<[u8], Vec<u8>> for LevelDB {
    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        self.db
            .get(LEVELDB_READ_OPTIONS, key)
            .map_err(Into::into)
    }

    fn put(&self, key: &[u8], value: Vec<u8>) -> Result<(), Error> {
        let result = self.db.put(LEVELDB_WRITE_OPTIONS, key, &value);
        result.map_err(Into::into)
    }

    fn delete(&self, key: &[u8]) -> Result<(), Error> {
        let result = self.db.delete(LEVELDB_WRITE_OPTIONS, key);
        result.map_err(Into::into)
    }
    fn find_key(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        let it = self.db.keys_iter(LEVELDB_READ_OPTIONS);
        it.seek(key);
        if it.valid() {
            let key = it.key();
            return Ok(Some(key.to_vec()));
        }
        Ok(None)
    }
}

impl Map<[u8], Vec<u8>> for LevelDBView {
    fn get(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        match self.changes.borrow().get(key) {
            Some(change) => {
                let v = match *change {
                    Change::Put(ref v) => Some(v.clone()),
                    Change::Delete => None,
                };
                Ok(v)
            }
            None => {
                self.snap
                    .get(LEVELDB_READ_OPTIONS, key)
                    .map_err(Into::into)
            }
        }
    }

    fn put(&self, key: &[u8], value: Vec<u8>) -> Result<(), Error> {
        self.changes.borrow_mut().insert(key.to_vec(), Change::Put(value));
        Ok(())
    }

    fn delete(&self, key: &[u8]) -> Result<(), Error> {
        self.changes.borrow_mut().insert(key.to_vec(), Change::Delete);
        Ok(())
    }

    fn find_key(&self, key: &[u8]) -> Result<Option<Vec<u8>>, Error> {
        // TODO merge with the same function in memorydb
        let out = {
            let map = self.changes.borrow();
            let mut it = map.range::<[u8], [u8]>(Included(key), Unbounded);
            it.next().map(|x| x.0.to_vec())
        };
        if out.is_none() {
            let it = self.snap.keys_iter(LEVELDB_READ_OPTIONS);
            it.seek(key);
            if it.valid() {
                let key = it.key();
                return Ok(Some(key.to_vec()));
            }
            Ok(None)
        } else {
            Ok(out)
        }
    }
}

impl Fork for LevelDBView {
    fn changes(&self) -> Patch {
        self.changes.borrow().clone()
    }

    fn merge(&self, patch: &Patch) {
        let iter = patch.into_iter().map(|(k, v)| (k.clone(), v.clone()));
        self.changes.borrow_mut().extend(iter);
    }
}

impl Database for LevelDB {
    type Fork = LevelDBView;

    fn fork(&self) -> Self::Fork {
        LevelDBView::new(self)
    }

    fn merge(&self, patch: &Patch) -> Result<(), Error> {
        let mut batch = Writebatch::new();
        for (key, change) in patch {
            match *change {
                Change::Put(ref v) => {
                    batch.put(key, v);
                }
                Change::Delete => {
                    batch.delete(key);
                }
            }
        }
        let write_opts = WriteOptions::new();
        let result = self.db.write(write_opts, &batch);
        result.map_err(Into::into)
    }
}

pub struct LevelDBIterator<'a> {
    db: LevelIterator<'a>,
    changes: Range<'a, Vec<u8>, Change>
}

impl<'a> Iterator for LevelDBIterator<'a> {
    type Item = (&'a[u8], Vec<u8>);

    fn next(&mut self) -> Option<Self::Item> {
        self.db.next()
    }
}

// pub struct LevelDBKeys<'a> {
//     iter: LevelKeys<'a>
// }

// impl<'a> Iterator for LevelDBKeys<'a> {
//     type Item = &'a[u8];

//     fn next(&mut self) -> Option<Self::Item> {
//         self.iter.next()
//     }
// }

// pub struct LevelDBValues<'a> {
//     iter: LevelValues<'a>
// }

// impl<'a> Iterator for LevelDBValues<'a> {
//     type Item = Vec<u8>;

//     fn next(&mut self) -> Option<Self::Item> {
//         self.iter.next()
//     }
// }
<|endoftext|>


<commit_before>pub struct KeyBuilder {
    key: Vec<u8>,
}

impl KeyBuilder {
    pub fn new() -> KeyBuilder {
        KeyBuilder {
            key: Vec::new(),
        }
    }

    pub fn with_capacity(size: usize) -> KeyBuilder {
        KeyBuilder {
            key: Vec::with_capacity(size),
        }
    }

    pub fn doc_key_mapping(key: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::with_capacity(1 + key.len());
        kb.push_char(b'k');
        kb.push_string(key);
        kb
    }

    pub fn term_dict_mapping(term: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::with_capacity(1 + term.len());
        kb.push_char(b't');
        kb.push_string(term);
        kb
    }

    pub fn chunk_active(chunk: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.chunk(chunk);
        kb.push_char(b'a');
        kb
    }

    pub fn chunk_dir_list(chunk: u32, field_ord: u32, term_ord: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.chunk(chunk);
        kb.push_char(b'd');
        kb.push_string(field_ord.to_string().as_bytes());
        kb.separator();
        kb.push_string(term_ord.to_string().as_bytes());
        kb
    }

    pub fn chunk_stat(chunk: u32, name: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.chunk(chunk);
        kb.push_char(b's');
        kb.push_string(name);
        kb
    }

    pub fn chunk_del_list(chunk: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.chunk(chunk);
        kb.push_char(b'x');
        kb
    }

    #[inline]
    pub fn key(&self) -> &[u8] {
        &self.key[..]
    }

    #[inline]
    pub fn push_char(&mut self, c: u8) {
        if c == b'/' || c == b'\\' {
            self.key.push(b'\\');
        }
        self.key.push(c);
    }

    pub fn push_string(&mut self, s: &[u8]) {
        for c in s {
            self.push_char(*c);
        }
    }

    pub fn separator(&mut self) {
        self.key.push(b'/');
    }

    pub fn chunk(&mut self, chunk: u32) {
        self.key.push(b'c');
        self.push_string(chunk.to_string().as_bytes());
    }
}<commit_msg>Revert "Change key format"<commit_after>pub struct KeyBuilder {
    key: Vec<u8>,
}

impl KeyBuilder {
    pub fn new() -> KeyBuilder {
        KeyBuilder {
            key: Vec::new(),
        }
    }

    pub fn with_capacity(size: usize) -> KeyBuilder {
        KeyBuilder {
            key: Vec::with_capacity(size),
        }
    }

    pub fn doc_key_mapping(key: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::with_capacity(1 + key.len());
        kb.push_char(b'k');
        kb.push_string(key);
        kb
    }

    pub fn term_dict_mapping(term: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::with_capacity(1 + term.len());
        kb.push_char(b't');
        kb.push_string(term);
        kb
    }

    pub fn chunk_active(chunk: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.push_char(b'a');
        kb.push_string(chunk.to_string().as_bytes());
        kb
    }

    pub fn chunk_dir_list(chunk: u32, field_ord: u32, term_ord: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.push_char(b'd');
        kb.push_string(field_ord.to_string().as_bytes());
        kb.separator();
        kb.push_string(term_ord.to_string().as_bytes());
        kb.separator();
        kb.push_string(chunk.to_string().as_bytes());
        kb
    }

    pub fn chunk_stat(chunk: u32, name: &[u8]) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.push_char(b's');
        kb.push_string(name);
        kb.separator();
        kb.push_string(chunk.to_string().as_bytes());
        kb
    }

    pub fn chunk_del_list(chunk: u32) -> KeyBuilder {
        let mut kb = KeyBuilder::new();
        kb.push_char(b'x');
        kb.push_string(chunk.to_string().as_bytes());
        kb
    }

    #[inline]
    pub fn key(&self) -> &[u8] {
        &self.key[..]
    }

    #[inline]
    pub fn push_char(&mut self, c: u8) {
        if c == b'/' || c == b'\\' {
            self.key.push(b'\\');
        }
        self.key.push(c);
    }

    pub fn push_string(&mut self, s: &[u8]) {
        for c in s {
            self.push_char(*c);
        }
    }

    pub fn separator(&mut self) {
        self.key.push(b'/');
    }
}<|endoftext|>


<commit_before>use std::os::getenv;

struct Request {
    path: ~str,
    querystring: ~str
}

fn main() {
    print("content-type: text/plain\r\n\r\n");
    println("hello from rust!");
    let req=Request{ path: getenv("PATH_INFO").unwrap_or(~""), querystring: getenv("QUERY_STRING").unwrap_or(~"")};
    println!("path: {:s}", req.path);
    println!("querystring: {:s}", req.querystring);
    println("done!");
}<commit_msg>Add route structure and handlers<commit_after>use std::os::getenv;

struct Request {
    path: ~str,
    querystring: ~str
}

impl Request {
    fn populate() -> Request {
        Request{
            path: getenv("PATH_INFO").unwrap_or(~""),
            querystring: getenv("QUERY_STRING").unwrap_or(~"")
        }
    }
}

struct Route {
    path: ~str,
    handler: ~fn(&Request)
}

fn index(r: &Request){
    println("yay index");
}

fn foo(r: &Request){
    println("yay foo");
}

fn main() {
    print("content-type: text/plain\r\n\r\n");

    let req=Request::populate();
    let routes: &[Route] = &[
            Route{path: ~"", handler: index},
            Route{path: ~"/foo", handler: foo}];
    for route in routes.iter(){
        if(route.path == req.path){
            (route.handler)(&req);
        }
    }
    println("hello from rust!");
    println!("path: {:s}", req.path);
    println!("querystring: {:s}", req.querystring);
    println("done!");
}<|endoftext|>


<commit_before>use collections::VecDeque;
// Temporary hack until libredox get hashmaps
use redox::*;

#[derive(Clone, PartialEq, Copy, Hash)]
pub enum InsertMode {
    Append,
    Insert,
    Replace,
}

#[derive(Clone, PartialEq, Copy, Hash)]
pub struct InsertOptions {
    mode: InsertMode,
}

/// A mode
#[derive(Clone, PartialEq, Copy, Hash)]
pub enum Mode {
    /// A primitive mode (no repeat, no delimiters, no preprocessing)
    Primitive(PrimitiveMode),
    /// Command mode
    Command(CommandMode),
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A command mode
pub enum CommandMode {
//    Visual(VisualOptions),
    /// Normal mode
    Normal,
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A primitive mode
pub enum PrimitiveMode {
    /// Insert mode
    Insert(InsertOptions),
}

#[derive(Clone, PartialEq, Hash)]
/// The state of the editor
pub struct State {
    /// The current cursor
    pub current_cursor: u8,
    /// The cursors
    pub cursors: Vec<Cursor>,
    /// The text (document)
    pub text: VecDeque<VecDeque<char>>,
    /// The x coordinate of the scroll
    pub scroll_x: u32,
    /// The y coordinate of the scroll
    pub scroll_y: u32,
    /// Number of repeation entered
    pub n: u16,
}

impl State {
    fn insert(&mut self, c: char) {

    }
    fn new() -> State {
        State {
            current_cursor: 0,
            cursors: Vec::new(),
            text: VecDeque::new(),
            scroll_x: 0,
            scroll_y: 0,
        }
    }
}

/// A command char
#[derive(Clone, Copy, Hash, PartialEq)]
pub enum CommandChar {
    /// A char
    Char(char),
    /// A wildcard
    Wildcard,
}

/// The editor
pub struct Editor {
    /// The state of the editor
    pub state: State,
}

impl Editor {
    pub fn new() -> Self {
        Editor {
            state: State::new(),
        }
    }

    /// Execute a instruction n times
    pub fn exec(&mut self, n: u16, cmd: char) {

        match cmd {

        }
    }

    /// Feed a char to the editor (as input)
    fn feed(&mut self, c: char) {
        match self.state.cursors[self.state.current_cursor as usize].mode {
            Mode::Primitive(_) => {
                self.exec(0, c);
            },
            Mode::Command(_) => {
                self.n = match c {
                    '0' if self.n != 0 => self.n * 10,
                    '1'           => self.n * 10 + 1,
                    '2'           => self.n * 10 + 2,
                    '3'           => self.n * 10 + 3,
                    '4'           => self.n * 10 + 4,
                    '5'           => self.n * 10 + 5,
                    '6'           => self.n * 10 + 6,
                    '7'           => self.n * 10 + 7,
                    '8'           => self.n * 10 + 8,
                    '9'           => self.n * 10 + 9,
                    _             => {
                        self.exec(if self.n == 0 { 1 } else { self.n }, c);
                        self.n
                    }
                }

            }
        }
    }
}

#[derive(Clone, PartialEq, Hash)]
/// A cursor
pub struct Cursor {
    /// The x coordinate of the cursor
    pub x: u32,
    /// The y coordinate of the cursor
    pub y: u32,
    /// The mode of the cursor
    pub mode: Mode,
    /// The history of the cursor
    pub history: Vec<Unit>,

<commit_msg>Refactor<commit_after>use collections::VecDeque;
// Temporary hack until libredox get hashmaps
use redox::*;

#[derive(Clone, PartialEq, Copy, Hash)]
pub enum InsertMode {
    Append,
    Insert,
    Replace,
}

#[derive(Clone, PartialEq, Copy, Hash)]
pub struct InsertOptions {
    mode: InsertMode,
}

/// A mode
#[derive(Clone, PartialEq, Copy, Hash)]
pub enum Mode {
    /// A primitive mode (no repeat, no delimiters, no preprocessing)
    Primitive(PrimitiveMode),
    /// Command mode
    Command(CommandMode),
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A command mode
pub enum CommandMode {
//    Visual(VisualOptions),
    /// Normal mode
    Normal,
}

#[derive(Clone, PartialEq, Copy, Hash)]
/// A primitive mode
pub enum PrimitiveMode {
    /// Insert mode
    Insert(InsertOptions),
}

#[derive(Clone, PartialEq, Hash)]
/// The state of the editor
pub struct Editor {
    /// The current cursor
    pub current_cursor: u8,
    /// The cursors
    pub cursors: Vec<Cursor>,
    /// The text (document)
    pub text: VecDeque<VecDeque<char>>,
    /// The x coordinate of the scroll
    pub scroll_x: u32,
    /// The y coordinate of the scroll
    pub scroll_y: u32,
    /// Number of repeation entered
    pub n: u16,
}

impl Editor {

    /// Execute a instruction n times
    pub fn exec(&mut self, n: u16, cmd: char) {

        match cmd {

        }
    }

    /// Feed a char to the editor (as input)
    fn feed(&mut self, c: char) {
        match self.cursors[self.current_cursor as usize].mode {
            Mode::Primitive(_) => {
                self.exec(0, c);
            },
            Mode::Command(_) => {
                self.n = match c {
                    '0' if self.n != 0 => self.n * 10,
                    '1'           => self.n * 10 + 1,
                    '2'           => self.n * 10 + 2,
                    '3'           => self.n * 10 + 3,
                    '4'           => self.n * 10 + 4,
                    '5'           => self.n * 10 + 5,
                    '6'           => self.n * 10 + 6,
                    '7'           => self.n * 10 + 7,
                    '8'           => self.n * 10 + 8,
                    '9'           => self.n * 10 + 9,
                    _             => {
                        self.exec(if self.n == 0 { 1 } else { self.n }, c);
                        self.n
                    }
                }

            }
        }
    }

    /// Insert text
    fn insert(&mut self, c: char) {

    }

    /// Create new default state editor
    fn new() -> Editor {
        Editor {
            current_cursor: 0,
            cursors: Vec::new(),
            text: VecDeque::new(),
            scroll_x: 0,
            scroll_y: 0,
            n: 0,
        }
    }
}

/// A command char
#[derive(Clone, Copy, Hash, PartialEq)]
pub enum CommandChar {
    /// A char
    Char(char),
    /// A wildcard
    Wildcard,
}

#[derive(Clone, PartialEq, Hash)]
/// A cursor
pub struct Cursor {
    /// The x coordinate of the cursor
    pub x: u32,
    /// The y coordinate of the cursor
    pub y: u32,
    /// The mode of the cursor
    pub mode: Mode,
    /// The history of the cursor
    pub history: Vec<Unit>,

<|endoftext|>


<commit_before>//! Enviroment data

use alloc::boxed::Box;

use fs::File;
use path::{Path, PathBuf};
use io::Result;
use string::{String, ToString};
use vec::Vec;

use system::error::{Error, ENOENT};
use system::syscall::sys_chdir;

static mut _args: *mut Vec<&'static str> = 0 as *mut Vec<&'static str>;

pub struct Args {
    i: usize
}

impl Iterator for Args {
    //Yes, this is supposed to be String, do not change it!
    //Only change it if https://doc.rust-lang.org/std/env/struct.Args.html changes from String
    type Item = String;
    fn next(&mut self) -> Option<String> {
        if let Some(arg) = unsafe { (*_args).get(self.i) } {
            self.i += 1;
            Some(arg.to_string())
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = if self.i <= unsafe { (*_args).len() } {
            unsafe { (*_args).len() - self.i }
        } else {
            0
        };
        (len, Some(len))
    }
}

impl ExactSizeIterator for Args {}

/// Arguments
pub fn args() -> Args {
    Args {
        i: 0
    }
}

/// Initialize arguments
pub unsafe fn args_init(args: Vec<&'static str>) {
    _args = Box::into_raw(box args);
}

/// Destroy arguments
pub unsafe fn args_destroy() {
    if _args as usize > 0 {
        drop(Box::from_raw(_args));
    }
}

/// Private function to get the path from a custom location
/// If the custom directory cannot be found, None will be returned
fn get_path_from(location : &str) -> Result<PathBuf> {
    match File::open(dir) {
        Ok(file) => {
            match file.path() {
                Ok(path) => Ok(path),
                Err(err) => Err(err),
            }
        }
        Err(err) => Err(err),
    }
}

/// Method to return the current directory
pub fn current_dir() -> Result<PathBuf> {
    // Return the current path
    get_dir("./")
}

/// Method to return the home directory
pub fn home_dir() -> Result<PathBuf> {
    get_dir("/home/")
}

/// Set the current directory
pub fn set_current_dir<P: AsRef<Path>>(path: P) -> Result<()> {
    let file_result = if path.as_ref().inner.is_empty() || path.as_ref().inner.ends_with('/') {
        File::open(&path.as_ref().inner)
    } else {
        File::open(&(path.as_ref().inner.to_string() + "/"))
    };

    match file_result {
        Ok(file) => {
            match file.path() {
                Ok(path) => {
                    if let Some(path_str) = path.to_str() {
                        let path_c = path_str.to_string() + "\0";
                        match Error::demux(unsafe { sys_chdir(path_c.as_ptr()) }) {
                            Ok(_) => Ok(()),
                            Err(err) => Err(err),
                        }
                    } else {
                        Err(Error::new(ENOENT))
                    }
                }
                Err(err) => Err(err),
            }
        }
        Err(err) => Err(err),
    }
}

// TODO: Fully implement `env::var()`
pub fn var(_key: &str) -> Result<String> {
    Ok("This is code filler".to_string())
}
<commit_msg>Fixed a mistake about method name<commit_after>//! Enviroment data

use alloc::boxed::Box;

use fs::File;
use path::{Path, PathBuf};
use io::Result;
use string::{String, ToString};
use vec::Vec;

use system::error::{Error, ENOENT};
use system::syscall::sys_chdir;

static mut _args: *mut Vec<&'static str> = 0 as *mut Vec<&'static str>;

pub struct Args {
    i: usize
}

impl Iterator for Args {
    //Yes, this is supposed to be String, do not change it!
    //Only change it if https://doc.rust-lang.org/std/env/struct.Args.html changes from String
    type Item = String;
    fn next(&mut self) -> Option<String> {
        if let Some(arg) = unsafe { (*_args).get(self.i) } {
            self.i += 1;
            Some(arg.to_string())
        } else {
            None
        }
    }

    fn size_hint(&self) -> (usize, Option<usize>) {
        let len = if self.i <= unsafe { (*_args).len() } {
            unsafe { (*_args).len() - self.i }
        } else {
            0
        };
        (len, Some(len))
    }
}

impl ExactSizeIterator for Args {}

/// Arguments
pub fn args() -> Args {
    Args {
        i: 0
    }
}

/// Initialize arguments
pub unsafe fn args_init(args: Vec<&'static str>) {
    _args = Box::into_raw(box args);
}

/// Destroy arguments
pub unsafe fn args_destroy() {
    if _args as usize > 0 {
        drop(Box::from_raw(_args));
    }
}

/// Private function to get the path from a custom location
/// If the custom directory cannot be found, None will be returned
fn get_path_from(location : &str) -> Result<PathBuf> {
    match File::open(dir) {
        Ok(file) => {
            match file.path() {
                Ok(path) => Ok(path),
                Err(err) => Err(err),
            }
        }
        Err(err) => Err(err),
    }
}

/// Method to return the current directory
pub fn current_dir() -> Result<PathBuf> {
    // Return the current path
    get_path_from("./")
}

/// Method to return the home directory
pub fn home_dir() -> Result<PathBuf> {
    get_path_from("/home/")
}

/// Set the current directory
pub fn set_current_dir<P: AsRef<Path>>(path: P) -> Result<()> {
    let file_result = if path.as_ref().inner.is_empty() || path.as_ref().inner.ends_with('/') {
        File::open(&path.as_ref().inner)
    } else {
        File::open(&(path.as_ref().inner.to_string() + "/"))
    };

    match file_result {
        Ok(file) => {
            match file.path() {
                Ok(path) => {
                    if let Some(path_str) = path.to_str() {
                        let path_c = path_str.to_string() + "\0";
                        match Error::demux(unsafe { sys_chdir(path_c.as_ptr()) }) {
                            Ok(_) => Ok(()),
                            Err(err) => Err(err),
                        }
                    } else {
                        Err(Error::new(ENOENT))
                    }
                }
                Err(err) => Err(err),
            }
        }
        Err(err) => Err(err),
    }
}

// TODO: Fully implement `env::var()`
pub fn var(_key: &str) -> Result<String> {
    Ok("This is code filler".to_string())
}
<|endoftext|>


<commit_before>// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

//! iced-x86 Python bindings (native module written in Rust). Don't reference this module directly.

#![allow(unknown_lints)]
#![warn(absolute_paths_not_starting_with_crate)]
#![warn(anonymous_parameters)]
#![warn(elided_lifetimes_in_paths)]
#![warn(explicit_outlives_requirements)]
#![warn(invalid_html_tags)]
#![warn(keyword_idents)]
#![warn(macro_use_extern_crate)]
#![warn(meta_variable_misuse)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#![warn(non_ascii_idents)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_lifetimes)]
#![warn(unused_must_use)]
#![warn(unused_qualifications)]
#![warn(unused_results)]
#![allow(clippy::cast_lossless)]
#![allow(clippy::collapsible_else_if)]
#![allow(clippy::collapsible_if)]
#![allow(clippy::field_reassign_with_default)]
#![allow(clippy::manual_range_contains)]
#![allow(clippy::match_ref_pats)]
#![allow(clippy::ptr_eq)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::type_complexity)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::wrong_self_convention)]
#![warn(clippy::cloned_instead_of_copied)]
#![warn(clippy::dbg_macro)]
#![warn(clippy::debug_assert_with_mut_call)]
#![warn(clippy::default_trait_access)]
#![warn(clippy::doc_markdown)]
#![warn(clippy::empty_line_after_outer_attr)]
#![warn(clippy::expect_used)]
#![warn(clippy::explicit_into_iter_loop)]
#![warn(clippy::explicit_iter_loop)]
#![warn(clippy::fallible_impl_from)]
#![warn(clippy::get_unwrap)]
#![warn(clippy::implicit_saturating_sub)]
#![warn(clippy::large_digit_groups)]
#![warn(clippy::let_unit_value)]
#![warn(clippy::match_bool)]
#![warn(clippy::match_on_vec_items)]
#![warn(clippy::match_wild_err_arm)]
#![warn(clippy::missing_errors_doc)]
#![warn(clippy::needless_borrow)]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
#![warn(clippy::rc_buffer)]
#![warn(clippy::redundant_closure)]
#![warn(clippy::redundant_closure_for_method_calls)]
#![warn(clippy::same_functions_in_if_condition)]
#![warn(clippy::todo)]
#![warn(clippy::unimplemented)]
#![warn(clippy::unreadable_literal)]
#![warn(clippy::unused_self)]
#![warn(clippy::unwrap_in_result)]
#![warn(clippy::unwrap_used)]
#![warn(clippy::useless_let_if_seq)]
#![warn(clippy::useless_transmute)]
#![warn(clippy::zero_sized_map_values)]

mod block_encoder;
mod constant_offsets;
mod decoder;
mod encoder;
mod enum_utils;
mod fast_formatter;
mod formatter;
mod info;
mod instruction;
mod memory_operand;
mod memory_size_ext;
mod memory_size_info;
mod op_code_info;
mod register_ext;
mod register_info;
mod utils;

use block_encoder::BlockEncoder;
use constant_offsets::ConstantOffsets;
use decoder::Decoder;
use encoder::Encoder;
use fast_formatter::FastFormatter;
use formatter::Formatter;
use info::{InstructionInfo, InstructionInfoFactory, UsedMemory, UsedRegister};
use instruction::{FpuStackIncrementInfo, Instruction};
use memory_operand::MemoryOperand;
use memory_size_ext::MemorySizeExt;
use memory_size_info::MemorySizeInfo;
use op_code_info::OpCodeInfo;
use pyo3::prelude::*;
use register_ext::RegisterExt;
use register_info::RegisterInfo;

// GENERATOR-BEGIN: EnumClassDefs
// ⚠This was generated by GENERATOR!🦹♂
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_a {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_ae {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_b {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_be {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_e {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_g {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_ge {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_l {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_le {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_ne {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_np {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_p {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct Code {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CodeSize {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct ConditionCode {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CpuidFeature {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct DecoderError {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct DecoderOptions {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct EncodingKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct FlowControl {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct FormatMnemonicOptions {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct FormatterSyntax {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MandatoryPrefix {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MemorySize {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MemorySizeOptions {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct Mnemonic {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MvexConvFn {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MvexEHBit {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MvexRegMemConv {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MvexTupleTypeLutKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct OpAccess {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct OpCodeOperandKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct OpCodeTableKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct OpKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct Register {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct RepPrefixKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct RflagsBits {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct RoundingControl {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct TupleType {}
// GENERATOR-END: EnumClassDefs

#[pymodule]
fn _iced_x86_py(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
	// GENERATOR-BEGIN: ClassExport
	// ⚠This was generated by GENERATOR!🦹♂
	m.add_class::<BlockEncoder>()?;
	m.add_class::<CC_a>()?;
	m.add_class::<CC_ae>()?;
	m.add_class::<CC_b>()?;
	m.add_class::<CC_be>()?;
	m.add_class::<CC_e>()?;
	m.add_class::<CC_g>()?;
	m.add_class::<CC_ge>()?;
	m.add_class::<CC_l>()?;
	m.add_class::<CC_le>()?;
	m.add_class::<CC_ne>()?;
	m.add_class::<CC_np>()?;
	m.add_class::<CC_p>()?;
	m.add_class::<Code>()?;
	m.add_class::<CodeSize>()?;
	m.add_class::<ConditionCode>()?;
	m.add_class::<ConstantOffsets>()?;
	m.add_class::<CpuidFeature>()?;
	m.add_class::<Decoder>()?;
	m.add_class::<DecoderError>()?;
	m.add_class::<DecoderOptions>()?;
	m.add_class::<Encoder>()?;
	m.add_class::<EncodingKind>()?;
	m.add_class::<FastFormatter>()?;
	m.add_class::<FlowControl>()?;
	m.add_class::<FormatMnemonicOptions>()?;
	m.add_class::<Formatter>()?;
	m.add_class::<FormatterSyntax>()?;
	m.add_class::<FpuStackIncrementInfo>()?;
	m.add_class::<Instruction>()?;
	m.add_class::<InstructionInfo>()?;
	m.add_class::<InstructionInfoFactory>()?;
	m.add_class::<MandatoryPrefix>()?;
	m.add_class::<MemoryOperand>()?;
	m.add_class::<MemorySize>()?;
	m.add_class::<MemorySizeExt>()?;
	m.add_class::<MemorySizeInfo>()?;
	m.add_class::<MemorySizeOptions>()?;
	m.add_class::<Mnemonic>()?;
	m.add_class::<MvexConvFn>()?;
	m.add_class::<MvexEHBit>()?;
	m.add_class::<MvexRegMemConv>()?;
	m.add_class::<MvexTupleTypeLutKind>()?;
	m.add_class::<OpAccess>()?;
	m.add_class::<OpCodeInfo>()?;
	m.add_class::<OpCodeOperandKind>()?;
	m.add_class::<OpCodeTableKind>()?;
	m.add_class::<OpKind>()?;
	m.add_class::<Register>()?;
	m.add_class::<RegisterExt>()?;
	m.add_class::<RegisterInfo>()?;
	m.add_class::<RepPrefixKind>()?;
	m.add_class::<RflagsBits>()?;
	m.add_class::<RoundingControl>()?;
	m.add_class::<TupleType>()?;
	m.add_class::<UsedMemory>()?;
	m.add_class::<UsedRegister>()?;
	// GENERATOR-END: ClassExport

	Ok(())
}
<commit_msg>Fix clippy warning when using new `const (): _ = assert!()` code<commit_after>// SPDX-License-Identifier: MIT
// Copyright (C) 2018-present iced project and contributors

//! iced-x86 Python bindings (native module written in Rust). Don't reference this module directly.

#![allow(unknown_lints)]
#![warn(absolute_paths_not_starting_with_crate)]
#![warn(anonymous_parameters)]
#![warn(elided_lifetimes_in_paths)]
#![warn(explicit_outlives_requirements)]
#![warn(invalid_html_tags)]
#![warn(keyword_idents)]
#![warn(macro_use_extern_crate)]
#![warn(meta_variable_misuse)]
#![warn(missing_copy_implementations)]
#![warn(missing_debug_implementations)]
#![warn(missing_docs)]
#![warn(non_ascii_idents)]
#![warn(trivial_casts)]
#![warn(trivial_numeric_casts)]
#![warn(unused_extern_crates)]
#![warn(unused_import_braces)]
#![warn(unused_lifetimes)]
#![warn(unused_must_use)]
#![warn(unused_qualifications)]
#![warn(unused_results)]
#![allow(clippy::assertions_on_constants)]
#![allow(clippy::cast_lossless)]
#![allow(clippy::collapsible_else_if)]
#![allow(clippy::collapsible_if)]
#![allow(clippy::field_reassign_with_default)]
#![allow(clippy::manual_range_contains)]
#![allow(clippy::match_ref_pats)]
#![allow(clippy::ptr_eq)]
#![allow(clippy::too_many_arguments)]
#![allow(clippy::type_complexity)]
#![allow(clippy::upper_case_acronyms)]
#![allow(clippy::wrong_self_convention)]
#![warn(clippy::cloned_instead_of_copied)]
#![warn(clippy::dbg_macro)]
#![warn(clippy::debug_assert_with_mut_call)]
#![warn(clippy::default_trait_access)]
#![warn(clippy::doc_markdown)]
#![warn(clippy::empty_line_after_outer_attr)]
#![warn(clippy::expect_used)]
#![warn(clippy::explicit_into_iter_loop)]
#![warn(clippy::explicit_iter_loop)]
#![warn(clippy::fallible_impl_from)]
#![warn(clippy::get_unwrap)]
#![warn(clippy::implicit_saturating_sub)]
#![warn(clippy::large_digit_groups)]
#![warn(clippy::let_unit_value)]
#![warn(clippy::match_bool)]
#![warn(clippy::match_on_vec_items)]
#![warn(clippy::match_wild_err_arm)]
#![warn(clippy::missing_errors_doc)]
#![warn(clippy::needless_borrow)]
#![warn(clippy::print_stderr)]
#![warn(clippy::print_stdout)]
#![warn(clippy::rc_buffer)]
#![warn(clippy::redundant_closure)]
#![warn(clippy::redundant_closure_for_method_calls)]
#![warn(clippy::same_functions_in_if_condition)]
#![warn(clippy::todo)]
#![warn(clippy::unimplemented)]
#![warn(clippy::unreadable_literal)]
#![warn(clippy::unused_self)]
#![warn(clippy::unwrap_in_result)]
#![warn(clippy::unwrap_used)]
#![warn(clippy::useless_let_if_seq)]
#![warn(clippy::useless_transmute)]
#![warn(clippy::zero_sized_map_values)]

mod block_encoder;
mod constant_offsets;
mod decoder;
mod encoder;
mod enum_utils;
mod fast_formatter;
mod formatter;
mod info;
mod instruction;
mod memory_operand;
mod memory_size_ext;
mod memory_size_info;
mod op_code_info;
mod register_ext;
mod register_info;
mod utils;

use block_encoder::BlockEncoder;
use constant_offsets::ConstantOffsets;
use decoder::Decoder;
use encoder::Encoder;
use fast_formatter::FastFormatter;
use formatter::Formatter;
use info::{InstructionInfo, InstructionInfoFactory, UsedMemory, UsedRegister};
use instruction::{FpuStackIncrementInfo, Instruction};
use memory_operand::MemoryOperand;
use memory_size_ext::MemorySizeExt;
use memory_size_info::MemorySizeInfo;
use op_code_info::OpCodeInfo;
use pyo3::prelude::*;
use register_ext::RegisterExt;
use register_info::RegisterInfo;

// GENERATOR-BEGIN: EnumClassDefs
// ⚠This was generated by GENERATOR!🦹♂
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_a {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_ae {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_b {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_be {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_e {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_g {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_ge {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_l {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_le {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_ne {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_np {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CC_p {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct Code {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CodeSize {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct ConditionCode {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct CpuidFeature {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct DecoderError {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct DecoderOptions {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct EncodingKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct FlowControl {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct FormatMnemonicOptions {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct FormatterSyntax {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MandatoryPrefix {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MemorySize {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MemorySizeOptions {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct Mnemonic {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MvexConvFn {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MvexEHBit {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MvexRegMemConv {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct MvexTupleTypeLutKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct OpAccess {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct OpCodeOperandKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct OpCodeTableKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct OpKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct Register {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct RepPrefixKind {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct RflagsBits {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct RoundingControl {}
/// DO NOT USE
#[pyclass(module = "iced_x86._iced_x86_py")]
#[allow(non_camel_case_types)]
struct TupleType {}
// GENERATOR-END: EnumClassDefs

#[pymodule]
fn _iced_x86_py(_py: Python<'_>, m: &PyModule) -> PyResult<()> {
	// GENERATOR-BEGIN: ClassExport
	// ⚠This was generated by GENERATOR!🦹♂
	m.add_class::<BlockEncoder>()?;
	m.add_class::<CC_a>()?;
	m.add_class::<CC_ae>()?;
	m.add_class::<CC_b>()?;
	m.add_class::<CC_be>()?;
	m.add_class::<CC_e>()?;
	m.add_class::<CC_g>()?;
	m.add_class::<CC_ge>()?;
	m.add_class::<CC_l>()?;
	m.add_class::<CC_le>()?;
	m.add_class::<CC_ne>()?;
	m.add_class::<CC_np>()?;
	m.add_class::<CC_p>()?;
	m.add_class::<Code>()?;
	m.add_class::<CodeSize>()?;
	m.add_class::<ConditionCode>()?;
	m.add_class::<ConstantOffsets>()?;
	m.add_class::<CpuidFeature>()?;
	m.add_class::<Decoder>()?;
	m.add_class::<DecoderError>()?;
	m.add_class::<DecoderOptions>()?;
	m.add_class::<Encoder>()?;
	m.add_class::<EncodingKind>()?;
	m.add_class::<FastFormatter>()?;
	m.add_class::<FlowControl>()?;
	m.add_class::<FormatMnemonicOptions>()?;
	m.add_class::<Formatter>()?;
	m.add_class::<FormatterSyntax>()?;
	m.add_class::<FpuStackIncrementInfo>()?;
	m.add_class::<Instruction>()?;
	m.add_class::<InstructionInfo>()?;
	m.add_class::<InstructionInfoFactory>()?;
	m.add_class::<MandatoryPrefix>()?;
	m.add_class::<MemoryOperand>()?;
	m.add_class::<MemorySize>()?;
	m.add_class::<MemorySizeExt>()?;
	m.add_class::<MemorySizeInfo>()?;
	m.add_class::<MemorySizeOptions>()?;
	m.add_class::<Mnemonic>()?;
	m.add_class::<MvexConvFn>()?;
	m.add_class::<MvexEHBit>()?;
	m.add_class::<MvexRegMemConv>()?;
	m.add_class::<MvexTupleTypeLutKind>()?;
	m.add_class::<OpAccess>()?;
	m.add_class::<OpCodeInfo>()?;
	m.add_class::<OpCodeOperandKind>()?;
	m.add_class::<OpCodeTableKind>()?;
	m.add_class::<OpKind>()?;
	m.add_class::<Register>()?;
	m.add_class::<RegisterExt>()?;
	m.add_class::<RegisterInfo>()?;
	m.add_class::<RepPrefixKind>()?;
	m.add_class::<RflagsBits>()?;
	m.add_class::<RoundingControl>()?;
	m.add_class::<TupleType>()?;
	m.add_class::<UsedMemory>()?;
	m.add_class::<UsedRegister>()?;
	// GENERATOR-END: ClassExport

	Ok(())
}
<|endoftext|>