<commit_before>use environment::Environment;
use options::Options;
use parser::ast;
use std::fs::File;
use std::fs;
use std::io::Write;
use naming::{self, FromNaming};
use std::collections::HashMap;
use std::collections::hash_map::Entry;

#[macro_use]
use codegen::python::*;

use errors::*;

pub trait Listeners {
    fn class_added(&self,
                   processor: &Processor,
                   package: &ast::Package,
                   fields: &Vec<(ast::Type, String)>,
                   class: &mut ClassSpec)
                   -> Result<()>;

    fn tuple_added(&self,
                   processor: &Processor,
                   package: &ast::Package,
                   fields: &Vec<(ast::Type, String)>,
                   class: &mut ClassSpec)
                   -> Result<()>;

    fn interface_added(&self,
                       processor: &Processor,
                       package: &ast::Package,
                       interface: &ast::InterfaceDecl,
                       interface_spec: &mut ClassSpec)
                       -> Result<()>;
}

pub struct Processor<'a> {
    options: &'a Options,
    env: &'a Environment,
    package_prefix: Option<ast::Package>,
    to_lower_snake: Box<naming::Naming>,
}

const PYTHON_CONTEXT: &str = "python";

impl<'a> Processor<'a> {
    pub fn new(options: &'a Options,
               env: &'a Environment,
               package_prefix: Option<ast::Package>)
               -> Processor<'a> {
        Processor {
            options: options,
            env: env,
            package_prefix: package_prefix,
            to_lower_snake: naming::SnakeCase::new().to_lower_snake(),
        }
    }

    pub fn is_native(&self, ty: &ast::Type) -> bool {
        match *ty {
            ast::Type::I32 | ast::Type::U32 => true,
            ast::Type::I64 | ast::Type::U64 => true,
            ast::Type::Float | ast::Type::Double => true,
            ast::Type::String => true,
            ast::Type::Any => true,
            ast::Type::Tuple(ref elements) => elements.iter().all(|e| self.is_native(&e.ty)),
            ast::Type::Array(ref inner) => self.is_native(inner),
            _ => false,
        }
    }

    fn custom_name(&self, package: &ast::Package, custom: &str) -> Name {
        let package = self.package(package);
        let key = &(package.clone(), custom.to_owned());
        let _ = self.env.types.get(key);
        Name::local(&custom).as_name()
    }

    fn used_name(&self, package: &ast::Package, used: &str, custom: &str) -> Result<Name> {
        let package = self.env.lookup_used(package, used)?;
        let package = self.package(package);
        let package = package.parts.join(".");
        Ok(Name::imported_alias(&package, &custom, used).as_name())
    }

    pub fn encode(&self,
                  package: &ast::Package,
                  ty: &ast::Type,
                  stmt: Statement)
                  -> Result<Statement> {
        // TODO: do not skip conversion if strict type checking is enabled
        if self.is_native(ty) {
            return Ok(stmt);
        }

        let stmt = match *ty {
            ast::Type::I32 | ast::Type::U32 => stmt,
            ast::Type::I64 | ast::Type::U64 => stmt,
            ast::Type::Float | ast::Type::Double => stmt,
            ast::Type::String => stmt,
            ast::Type::Any => stmt,
            ast::Type::Custom(ref _custom) => python_stmt![stmt, ".encode()"],
            ast::Type::UsedType(ref _used, ref _custom) => python_stmt![stmt, ".encode()"],
            ast::Type::Array(ref inner) => {
                let inner = self.encode(package, inner, python_stmt!["v"])?;
                python_stmt!["map(lambda v: ", inner, ", ", stmt, ")"]
            }
            _ => stmt,
        };

        Ok(stmt)
    }

    pub fn decode(&self,
                  package: &ast::Package,
                  ty: &ast::Type,
                  stmt: Statement)
                  -> Result<Statement> {
        // TODO: do not skip conversion if strict type checking is enabled
        if self.is_native(ty) {
            return Ok(stmt);
        }

        let stmt = match *ty {
            ast::Type::I32 | ast::Type::U32 => stmt,
            ast::Type::I64 | ast::Type::U64 => stmt,
            ast::Type::Float | ast::Type::Double => stmt,
            ast::Type::String => stmt,
            ast::Type::Any => stmt,
            ast::Type::Custom(ref custom) => {
                let name = self.custom_name(package, custom);
                python_stmt![name, ".decode(", stmt, ")"]
            }
            ast::Type::UsedType(ref used, ref custom) => {
                let name = self.used_name(package, used, custom)?;
                python_stmt![name, ".decode(", stmt, ")"]
            }
            ast::Type::Array(ref inner) => {
                let inner = self.decode(package, inner, python_stmt!["v"])?;
                python_stmt!["map(lambda v: ", inner, ", ", stmt, ")"]
            }
            _ => stmt,
        };

        Ok(stmt)
    }

    /// Build the java package of a given package.
    ///
    /// This includes the prefixed configured in `self.options`, if specified.
    fn package(&self, package: &ast::Package) -> ast::Package {
        self.package_prefix
            .clone()
            .map(|prefix| prefix.join(package))
            .unwrap_or_else(|| package.clone())
    }

    fn build_constructor(&self, fields: &Vec<(ast::Type, String)>) -> MethodSpec {
        let mut constructor = MethodSpec::new("__init__");
        constructor.push_argument(python_stmt!["self"]);

        for &(_, ref field_name) in fields {
            constructor.push_argument(python_stmt![field_name]);
            constructor.push(python_stmt!["self.", field_name, " = ", field_name]);
        }

        constructor
    }

    fn process_type<L>(&self,
                       package: &ast::Package,
                       ty: &ast::TypeDecl,
                       listeners: &L)
                       -> Result<ClassSpec>
        where L: Listeners
    {
        match ty.value {
            ast::Type::Tuple(ref elements) => {
                let mut class = ClassSpec::new(&ty.name);
                let mut fields: Vec<(ast::Type, String)> = Vec::new();

                let mut index = 0;

                for element in elements {
                    let index_name = match index {
                        0 => "first".to_owned(),
                        1 => "second".to_owned(),
                        2 => "third".to_owned(),
                        n => format!("field{}", n),
                    };

                    let name = element.name.clone().unwrap_or(index_name);
                    fields.push((element.ty.clone(), name));
                    index += 1;
                }

                class.push(self.build_constructor(&fields));

                // TODO: make configurable
                if false {
                    for getter in self.build_getters(&fields)? {
                        class.push(&getter);
                    }
                }

                listeners.tuple_added(self, package, &fields, &mut class)?;
                Ok(class)
            }
            _ => Err(format!("unsupported type: {:?}", ty).into()),
        }
    }

    fn build_getters(&self, fields: &Vec<(ast::Type, String)>) -> Result<Vec<MethodSpec>> {
        let mut result = Vec::new();

        for &(_, ref field_name) in fields {
            let name = self.to_lower_snake.convert(field_name);
            let getter_name = format!("get_{}", name);
            let mut method_spec = MethodSpec::new(&getter_name);
            method_spec.push_argument(python_stmt!["self"]);
            method_spec.push(python_stmt!["return self.", name]);
            result.push(method_spec);
        }

        Ok(result)
    }

    fn process_message<L>(&self,
                          package: &ast::Package,
                          message: &ast::MessageDecl,
                          listeners: &L)
                          -> Result<ClassSpec>
        where L: Listeners
    {
        let mut class = ClassSpec::new(&message.name);
        let mut fields = Vec::new();

        for member in &message.members {
            if let ast::MessageMember::Field(ref field, _) = *member {
                fields.push((field.ty.clone(), field.name.clone()));
                continue;
            }
        }

        let constructor = self.build_constructor(&fields);
        class.push(&constructor);

        // TODO: make configurable
        if false {
            for getter in self.build_getters(&fields)? {
                class.push(getter);
            }
        }

        for member in &message.members {
            if let ast::MessageMember::Code(ref context, ref content, _) = *member {
                if context == PYTHON_CONTEXT {
                    class.push(ElementSpec::Literal(content.clone()));
                }
            }
        }

        listeners.class_added(self, package, &fields, &mut class)?;
        Ok(class)
    }

    fn process_interface<L>(&self,
                            package: &ast::Package,
                            interface: &ast::InterfaceDecl,
                            listeners: &L)
                            -> Result<Vec<ClassSpec>>
        where L: Listeners
    {
        let mut classes = Vec::new();

        let mut interface_spec = ClassSpec::new(&interface.name);

        listeners.interface_added(self, package, interface, &mut interface_spec)?;

        classes.push(interface_spec);

        let mut interface_fields: Vec<(ast::Type, String)> = Vec::new();

        for member in &interface.members {
            if let ast::InterfaceMember::Field(ref field, _) = *member {
                interface_fields.push((field.ty.clone(), field.name.clone()));
            }
        }

        for (_, ref sub_type) in &interface.sub_types {
            let mut class = ClassSpec::new(&sub_type.name);
            class.extends(Name::local(&interface.name));

            let mut fields = interface_fields.clone();

            for member in &sub_type.members {
                if let ast::SubTypeMember::Field(ref field) = *member {
                    fields.push((field.ty.clone(), field.name.clone()));
                }
            }

            let constructor = self.build_constructor(&fields);
            class.push(&constructor);

            // TODO: make configurable
            if false {
                for getter in self.build_getters(&fields)? {
                    class.push(&getter);
                }
            }

            listeners.class_added(self, package, &fields, &mut class)?;
            classes.push(class);
        }

        Ok(classes)
    }

    pub fn process<L>(&self, listeners: &L) -> Result<()>
        where L: Listeners
    {
        let root_dir = &self.options.out_path;

        let mut files = HashMap::new();

        // Process all types discovered so far.
        for (&(ref package, _), decl) in &self.env.types {
            let class_specs = match *decl {
                ast::Decl::Interface(ref interface) => {
                    self.process_interface(package, interface, listeners)?
                }
                ast::Decl::Message(ref message) => {
                    vec![self.process_message(package, message, listeners)?]
                }
                ast::Decl::Type(ref ty) => vec![self.process_type(package, ty, listeners)?],
            };

            match files.entry(package) {
                Entry::Vacant(entry) => {
                    let mut file_spec = FileSpec::new();

                    for class_spec in class_specs {
                        file_spec.push(class_spec);
                    }

                    entry.insert(file_spec);
                }
                Entry::Occupied(entry) => {
                    let mut file_spec = entry.into_mut();

                    for class_spec in class_specs {
                        file_spec.push(class_spec);
                    }
                }
            }
        }

        for (package, file_spec) in files.into_iter() {
            let package = self.package(package);

            let mut full_path = root_dir.to_owned();
            let mut it = package.parts.iter().peekable();

            while let Some(part) = it.next() {
                full_path = full_path.join(part);

                if it.peek().is_none() {
                    continue;
                }

                let init = full_path.join("__init__.py");

                if !init.is_file() {
                    if let Some(parent) = init.parent() {
                        if !parent.is_dir() {
                            debug!("Creating directory: {}", init.display());
                            fs::create_dir_all(&parent)?;
                        }
                    }

                    debug!("Writing: {}", init.display());
                    File::create(init)?;
                }
            }

            // path to final file
            full_path.set_extension("py");

            debug!("Writing: {}", full_path.display());

            let out = file_spec.format();
            let mut f = File::create(full_path)?;
            let bytes = out.into_bytes();

            f.write_all(&bytes)?;
            f.flush()?;
        }

        Ok(())
    }
}
<commit_msg>fix typo<commit_after>use environment::Environment;
use options::Options;
use parser::ast;
use std::fs::File;
use std::fs;
use std::io::Write;
use naming::{self, FromNaming};
use std::collections::HashMap;
use std::collections::hash_map::Entry;

#[macro_use]
use codegen::python::*;

use errors::*;

pub trait Listeners {
    fn class_added(&self,
                   processor: &Processor,
                   package: &ast::Package,
                   fields: &Vec<(ast::Type, String)>,
                   class: &mut ClassSpec)
                   -> Result<()>;

    fn tuple_added(&self,
                   processor: &Processor,
                   package: &ast::Package,
                   fields: &Vec<(ast::Type, String)>,
                   class: &mut ClassSpec)
                   -> Result<()>;

    fn interface_added(&self,
                       processor: &Processor,
                       package: &ast::Package,
                       interface: &ast::InterfaceDecl,
                       interface_spec: &mut ClassSpec)
                       -> Result<()>;
}

pub struct Processor<'a> {
    options: &'a Options,
    env: &'a Environment,
    package_prefix: Option<ast::Package>,
    to_lower_snake: Box<naming::Naming>,
}

const PYTHON_CONTEXT: &str = "python";

impl<'a> Processor<'a> {
    pub fn new(options: &'a Options,
               env: &'a Environment,
               package_prefix: Option<ast::Package>)
               -> Processor<'a> {
        Processor {
            options: options,
            env: env,
            package_prefix: package_prefix,
            to_lower_snake: naming::SnakeCase::new().to_lower_snake(),
        }
    }

    pub fn is_native(&self, ty: &ast::Type) -> bool {
        match *ty {
            ast::Type::I32 | ast::Type::U32 => true,
            ast::Type::I64 | ast::Type::U64 => true,
            ast::Type::Float | ast::Type::Double => true,
            ast::Type::String => true,
            ast::Type::Any => true,
            ast::Type::Tuple(ref elements) => elements.iter().all(|e| self.is_native(&e.ty)),
            ast::Type::Array(ref inner) => self.is_native(inner),
            _ => false,
        }
    }

    fn custom_name(&self, package: &ast::Package, custom: &str) -> Name {
        let package = self.package(package);
        let key = &(package.clone(), custom.to_owned());
        let _ = self.env.types.get(key);
        Name::local(&custom).as_name()
    }

    fn used_name(&self, package: &ast::Package, used: &str, custom: &str) -> Result<Name> {
        let package = self.env.lookup_used(package, used)?;
        let package = self.package(package);
        let package = package.parts.join(".");
        Ok(Name::imported_alias(&package, &custom, used).as_name())
    }

    pub fn encode(&self,
                  package: &ast::Package,
                  ty: &ast::Type,
                  stmt: Statement)
                  -> Result<Statement> {
        // TODO: do not skip conversion if strict type checking is enabled
        if self.is_native(ty) {
            return Ok(stmt);
        }

        let stmt = match *ty {
            ast::Type::I32 | ast::Type::U32 => stmt,
            ast::Type::I64 | ast::Type::U64 => stmt,
            ast::Type::Float | ast::Type::Double => stmt,
            ast::Type::String => stmt,
            ast::Type::Any => stmt,
            ast::Type::Custom(ref _custom) => python_stmt![stmt, ".encode()"],
            ast::Type::UsedType(ref _used, ref _custom) => python_stmt![stmt, ".encode()"],
            ast::Type::Array(ref inner) => {
                let inner = self.encode(package, inner, python_stmt!["v"])?;
                python_stmt!["map(lambda v: ", inner, ", ", stmt, ")"]
            }
            _ => stmt,
        };

        Ok(stmt)
    }

    pub fn decode(&self,
                  package: &ast::Package,
                  ty: &ast::Type,
                  stmt: Statement)
                  -> Result<Statement> {
        // TODO: do not skip conversion if strict type checking is enabled
        if self.is_native(ty) {
            return Ok(stmt);
        }

        let stmt = match *ty {
            ast::Type::I32 | ast::Type::U32 => stmt,
            ast::Type::I64 | ast::Type::U64 => stmt,
            ast::Type::Float | ast::Type::Double => stmt,
            ast::Type::String => stmt,
            ast::Type::Any => stmt,
            ast::Type::Custom(ref custom) => {
                let name = self.custom_name(package, custom);
                python_stmt![name, ".decode(", stmt, ")"]
            }
            ast::Type::UsedType(ref used, ref custom) => {
                let name = self.used_name(package, used, custom)?;
                python_stmt![name, ".decode(", stmt, ")"]
            }
            ast::Type::Array(ref inner) => {
                let inner = self.decode(package, inner, python_stmt!["v"])?;
                python_stmt!["map(lambda v: ", inner, ", ", stmt, ")"]
            }
            _ => stmt,
        };

        Ok(stmt)
    }

    /// Build the java package of a given package.
    ///
    /// This includes the prefixed configured in `self.options`, if specified.
    fn package(&self, package: &ast::Package) -> ast::Package {
        self.package_prefix
            .clone()
            .map(|prefix| prefix.join(package))
            .unwrap_or_else(|| package.clone())
    }

    fn build_constructor(&self, fields: &Vec<(ast::Type, String)>) -> MethodSpec {
        let mut constructor = MethodSpec::new("__init__");
        constructor.push_argument(python_stmt!["self"]);

        for &(_, ref field_name) in fields {
            constructor.push_argument(python_stmt![field_name]);
            constructor.push(python_stmt!["self.", field_name, " = ", field_name]);
        }

        constructor
    }

    fn process_type<L>(&self,
                       package: &ast::Package,
                       ty: &ast::TypeDecl,
                       listeners: &L)
                       -> Result<ClassSpec>
        where L: Listeners
    {
        match ty.value {
            ast::Type::Tuple(ref elements) => {
                let mut class = ClassSpec::new(&ty.name);
                let mut fields: Vec<(ast::Type, String)> = Vec::new();

                let mut index = 0;

                for element in elements {
                    let index_name = match index {
                        0 => "first".to_owned(),
                        1 => "second".to_owned(),
                        2 => "third".to_owned(),
                        n => format!("field{}", n),
                    };

                    let name = element.name.clone().unwrap_or(index_name);
                    fields.push((element.ty.clone(), name));
                    index += 1;
                }

                class.push(self.build_constructor(&fields));

                // TODO: make configurable
                if false {
                    for getter in self.build_getters(&fields)? {
                        class.push(&getter);
                    }
                }

                listeners.tuple_added(self, package, &fields, &mut class)?;
                Ok(class)
            }
            _ => Err(format!("unsupported type: {:?}", ty).into()),
        }
    }

    fn build_getters(&self, fields: &Vec<(ast::Type, String)>) -> Result<Vec<MethodSpec>> {
        let mut result = Vec::new();

        for &(_, ref field_name) in fields {
            let name = self.to_lower_snake.convert(field_name);
            let getter_name = format!("get_{}", name);
            let mut method_spec = MethodSpec::new(&getter_name);
            method_spec.push_argument(python_stmt!["self"]);
            method_spec.push(python_stmt!["return self.", name]);
            result.push(method_spec);
        }

        Ok(result)
    }

    fn process_message<L>(&self,
                          package: &ast::Package,
                          message: &ast::MessageDecl,
                          listeners: &L)
                          -> Result<ClassSpec>
        where L: Listeners
    {
        let mut class = ClassSpec::new(&message.name);
        let mut fields = Vec::new();

        for member in &message.members {
            if let ast::MessageMember::Field(ref field, _) = *member {
                fields.push((field.ty.clone(), field.name.clone()));
                continue;
            }
        }

        let constructor = self.build_constructor(&fields);
        class.push(&constructor);

        // TODO: make configurable
        if false {
            for getter in self.build_getters(&fields)? {
                class.push(getter);
            }
        }

        for member in &message.members {
            if let ast::MessageMember::Code(ref context, ref content, _) = *member {
                if context == PYTHON_CONTEXT {
                    class.push(ElementSpec::Literal(content.clone()));
                }
            }
        }

        listeners.class_added(self, package, &fields, &mut class)?;
        Ok(class)
    }

    fn process_interface<L>(&self,
                            package: &ast::Package,
                            interface: &ast::InterfaceDecl,
                            listeners: &L)
                            -> Result<Vec<ClassSpec>>
        where L: Listeners
    {
        let mut classes = Vec::new();

        let mut interface_spec = ClassSpec::new(&interface.name);

        listeners.interface_added(self, package, interface, &mut interface_spec)?;

        classes.push(interface_spec);

        let mut interface_fields: Vec<(ast::Type, String)> = Vec::new();

        for member in &interface.members {
            if let ast::InterfaceMember::Field(ref field, _) = *member {
                interface_fields.push((field.ty.clone(), field.name.clone()));
            }
        }

        for (_, ref sub_type) in &interface.sub_types {
            let mut class = ClassSpec::new(&sub_type.name);
            class.extends(Name::local(&interface.name));

            let mut fields = interface_fields.clone();

            for member in &sub_type.members {
                if let ast::SubTypeMember::Field(ref field) = *member {
                    fields.push((field.ty.clone(), field.name.clone()));
                }
            }

            let constructor = self.build_constructor(&fields);
            class.push(&constructor);

            // TODO: make configurable
            if false {
                for getter in self.build_getters(&fields)? {
                    class.push(&getter);
                }
            }

            listeners.class_added(self, package, &fields, &mut class)?;
            classes.push(class);
        }

        Ok(classes)
    }

    pub fn process<L>(&self, listeners: &L) -> Result<()>
        where L: Listeners
    {
        let root_dir = &self.options.out_path;

        let mut files = HashMap::new();

        // Process all types discovered so far.
        for (&(ref package, _), decl) in &self.env.types {
            let class_specs = match *decl {
                ast::Decl::Interface(ref interface) => {
                    self.process_interface(package, interface, listeners)?
                }
                ast::Decl::Message(ref message) => {
                    vec![self.process_message(package, message, listeners)?]
                }
                ast::Decl::Type(ref ty) => vec![self.process_type(package, ty, listeners)?],
            };

            match files.entry(package) {
                Entry::Vacant(entry) => {
                    let mut file_spec = FileSpec::new();

                    for class_spec in class_specs {
                        file_spec.push(class_spec);
                    }

                    entry.insert(file_spec);
                }
                Entry::Occupied(entry) => {
                    let mut file_spec = entry.into_mut();

                    for class_spec in class_specs {
                        file_spec.push(class_spec);
                    }
                }
            }
        }

        for (package, file_spec) in files.into_iter() {
            let package = self.package(package);

            let mut full_path = root_dir.to_owned();
            let mut it = package.parts.iter().peekable();

            while let Some(part) = it.next() {
                full_path = full_path.join(part);

                if it.peek().is_none() {
                    continue;
                }

                let init = full_path.join("__init__.py");

                if !init.is_file() {
                    if let Some(parent) = init.parent() {
                        if !parent.is_dir() {
                            debug!("Creating directory: {}", parent.display());
                            fs::create_dir_all(&parent)?;
                        }
                    }

                    debug!("Writing: {}", init.display());
                    File::create(init)?;
                }
            }

            // path to final file
            full_path.set_extension("py");

            debug!("Writing: {}", full_path.display());

            let out = file_spec.format();
            let mut f = File::create(full_path)?;
            let bytes = out.into_bytes();

            f.write_all(&bytes)?;
            f.flush()?;
        }

        Ok(())
    }
}
<|endoftext|>


<commit_before>/*
 * Binarization filter using Otsu's method
 */

#pragma version(1)
#pragma rs java_package_name(se.embargo.onebit.filter)

rs_allocation gIn;
rs_allocation gOut;
rs_script gScript;

const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};

void root(const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) {
	float4 f4 = rsUnpackColor8888(*v_in);
	float3 mono = dot(f4.rgb, gMonoMult);
	float3 binary = step(*(const float3 *)usrData, mono);
	*v_out = rsPackColorTo8888(binary);
}

void filter() {
	int64_t t1 = rsUptimeMillis();

	int32_t width = rsAllocationGetDimX(gIn),
			height = rsAllocationGetDimY(gIn);
	int32_t pixels = width * height;

	rsDebug("Otsu image dimensions", width, height);

	// Build the histogram
	int32_t hist[256] = {0};
	for (int x = 0; x < width; x++) {
		for (int y = 0; y < height; y++) {
			const uchar4 *v_in = (const uchar4 *)rsGetElementAt(gIn, x, y);
			float4 f4 = rsUnpackColor8888(*v_in);
			float mono = dot(f4.rgb, gMonoMult);
			hist[(int)(mono * 255.0f) & 0xff]++;
		}
	}

	// Calculate the global threshold
	float sum = 0;
	for (int i = 0; i < 256; i++) {
		sum += (float)(hist[i] * i);
	}

	rsDebug("Otsu histogram sum", sum);

	float csum = 0;
	int wB = 0;
	int wF = 0;

	float fmax = -1.0;
	float threshold = 0;

	for (int i = 0; i < 255; i++) {
		// Weight background
		wB += hist[i];
		if (wB == 0) {
			continue;
		}

		// Weight foreground
		wF = pixels - wB;
		if (wF == 0) {
			break;
		}

		csum += (float)(hist[i] * i);

		float mB = csum / wB;
		float mF = (sum - csum) / wF;
		float sb = (float)wB * (float)wF * (mB - mF) * (mB - mF);
		//float sb = (float)wB * (float)wF * (mF - mB);

		// Check if new maximum found
		if (sb > fmax) {
			fmax = sb;
			threshold = i + 1;
		}
	}

	int64_t t2 = rsUptimeMillis();
	rsDebug("Otsu threshold found in (ms)", t2 - t1);
	rsDebug("Otsu global threshold", threshold);

	// Binarize the image
	float3 usrData = (float)threshold / 255.0f;
	rsForEach(gScript, gIn, gOut, &usrData);

	int64_t t3 = rsUptimeMillis();
	rsDebug("Otsu binarization filter in (ms)", t3 - t2);
	rsDebug("Otsu filter in (ms)", t3 - t1);
}
<commit_msg>Fixed problem in Otsu method causing fluctuations in the threshold<commit_after>/*
 * Binarization filter using Otsu's method
 */

#pragma version(1)
#pragma rs java_package_name(se.embargo.onebit.filter)

rs_allocation gIn;
rs_allocation gOut;
rs_script gScript;

const static float3 gMonoMult = {0.299f, 0.587f, 0.114f};

void root(const uchar4 *v_in, uchar4 *v_out, const void *usrData, uint32_t x, uint32_t y) {
	float4 f4 = rsUnpackColor8888(*v_in);
	float3 mono = dot(f4.rgb, gMonoMult);
	float3 binary = step(*(const float3 *)usrData, mono);
	*v_out = rsPackColorTo8888(binary);
}

void filter() {
	int64_t t1 = rsUptimeMillis();

	int32_t width = rsAllocationGetDimX(gIn),
			height = rsAllocationGetDimY(gIn);
	int32_t pixels = width * height;

	rsDebug("Otsu image dimensions", width, height);

	// Build the histogram
	int32_t hist[256] = {0};
	for (int x = 0; x < width; x++) {
		for (int y = 0; y < height; y++) {
			const uchar4 *v_in = (const uchar4 *)rsGetElementAt(gIn, x, y);
			float4 f4 = rsUnpackColor8888(*v_in);
			float mono = dot(f4.rgb, gMonoMult);
			hist[(int)(mono * 255.0f) & 0xff]++;
		}
	}

	// Calculate the global threshold
	float sum = 0;
	for (int i = 0; i < 256; i++) {
		sum += (float)(hist[i] * i);
	}

	rsDebug("Otsu histogram sum", sum);

	float csum = 0;
	int wB = 0;
	int wF = 0;

	float fmax = -1.0;
	float threshold = 0;

	for (int i = 0; i < 255; i++) {
		// Weight background
		wB += hist[i];
		if (wB == 0) {
			continue;
		}

		// Weight foreground
		wF = pixels - wB;
		if (wF == 0) {
			break;
		}

		csum += (float)(hist[i] * i);

		float mB = csum / wB;
		float mF = (sum - csum) / wF;
		float sb = (float)wB * (float)wF * (mF - mB);

		// Check if new maximum found
		if (sb > fmax) {
			fmax = sb;
			threshold = i + 1;
		}
	}

	int64_t t2 = rsUptimeMillis();
	rsDebug("Otsu threshold found in (ms)", t2 - t1);
	rsDebug("Otsu global threshold", threshold);

	// Binarize the image
	float3 usrData = (float)threshold / 255.0f;
	rsForEach(gScript, gIn, gOut, &usrData);

	int64_t t3 = rsUptimeMillis();
	rsDebug("Otsu binarization filter in (ms)", t3 - t2);
	rsDebug("Otsu filter in (ms)", t3 - t1);
}
<|endoftext|>


<commit_before>use std::collections::HashMap;

use serial_support::errors::*;

/// Manages tracking of write locks
pub struct WriteLockManager {
  /// Map of port to subscription ids
  write_locks: HashMap<String, String>,
}

impl WriteLockManager {
  /// Create a new WriteLockManager instance
  pub fn new() -> WriteLockManager {
    WriteLockManager { write_locks: HashMap::new() }
  }

  /// Is the port write locked by the given sub_id
  pub fn is_port_write_locked_by(&self, port_name: &String, sub_id: &String) -> bool {
    match self.write_locks.get(port_name) {
      None => false,
      Some(sid) => sid == sub_id,
    }
  }

  /// Is the port write locked at all
  pub fn is_port_write_locked(&self, port_name: &String) -> bool {
    self.write_locks.get(port_name).is_some()
  }

  pub fn is_port_locked_by_someone_else(&self, port_name: &String, sub_id: &String) -> bool {
    match self.write_locks.get(port_name) {
      None => false,
      Some(sid) => sid != sub_id,
    }
  }

  /// Check if sub id has write lock on this port, if it doesn't,
  /// return error
  pub fn check_owns_write_lock(&self, port_name: &String, sub_id: &String) -> Result<()> {
    match self.write_locks.get(port_name) {
      None => Ok(()),
      Some(sid) => {
        if sid != sub_id {
          Err(ErrorKind::AlreadyWriteLocked(port_name.to_string()).into())
        } else {
          Ok(())
        }
      }
    }
  }

  // Clear a write lock, without checking subscriber id
  pub fn clear_lock(&mut self, port_name: &String) {
    self.write_locks.remove(port_name);
  }

  // Release the write lock for the given port and sub id
  pub fn unlock_port(&mut self, port_name: &String, sub_id: &String) -> Result<()> {
    self.check_owns_write_lock(port_name, sub_id)?;
    self.write_locks.remove(port_name);
    Ok(())
  }

  // Release the write lock for the given port and sub id
  pub fn unlock_all_ports_for_sub(&mut self, sub_id: &String) {
    let mut to_delete = Vec::<String>::new();
    for port_name in self.write_locks.keys() {
      if self
           .write_locks
           .get(port_name)
           .map(|sid| sid == sub_id)
           .unwrap_or(false) {
        to_delete.push(port_name.to_string());
      }
    }
    for delete_port in to_delete.iter() {
      self.write_locks.remove(delete_port);
    }
  }

  // Try and lock the port
  pub fn lock_port(&mut self, port_name: &String, sub_id: &String) -> Result<()> {
    self.check_owns_write_lock(port_name, sub_id)?;
    self
      .write_locks
      .insert(port_name.to_string(), sub_id.to_string());
    Ok(())
  }
}
<commit_msg>Added tests for writelock_manager<commit_after>use std::collections::HashMap;

use serial_support::errors::*;

/// Manages tracking of write locks
pub struct WriteLockManager {
  /// Map of port to subscription ids
  write_locks: HashMap<String, String>,
}

impl WriteLockManager {
  /// Create a new WriteLockManager instance
  pub fn new() -> WriteLockManager {
    WriteLockManager { write_locks: HashMap::new() }
  }

  /// Is the port write locked by the given sub_id
  pub fn is_port_write_locked_by(&self, port_name: &String, sub_id: &String) -> bool {
    match self.write_locks.get(port_name) {
      None => false,
      Some(sid) => sid == sub_id,
    }
  }

  /// Is the port write locked at all
  pub fn is_port_write_locked(&self, port_name: &String) -> bool {
    self.write_locks.get(port_name).is_some()
  }

  pub fn is_port_locked_by_someone_else(&self, port_name: &String, sub_id: &String) -> bool {
    match self.write_locks.get(port_name) {
      None => false,
      Some(sid) => sid != sub_id,
    }
  }

  /// Check if sub id has write lock on this port, if it doesn't,
  /// return error
  pub fn check_owns_write_lock(&self, port_name: &String, sub_id: &String) -> Result<()> {
    match self.write_locks.get(port_name) {
      None => Ok(()),
      Some(sid) => {
        if sid != sub_id {
          Err(ErrorKind::AlreadyWriteLocked(port_name.to_string()).into())
        } else {
          Ok(())
        }
      }
    }
  }

  // Clear a write lock, without checking subscriber id
  pub fn clear_lock(&mut self, port_name: &String) {
    self.write_locks.remove(port_name);
  }

  // Release the write lock for the given port and sub id
  pub fn unlock_port(&mut self, port_name: &String, sub_id: &String) -> Result<()> {
    self.check_owns_write_lock(port_name, sub_id)?;
    self.write_locks.remove(port_name);
    Ok(())
  }

  // Release the write lock for the given port and sub id
  pub fn unlock_all_ports_for_sub(&mut self, sub_id: &String) {
    let mut to_delete = Vec::<String>::new();
    for port_name in self.write_locks.keys() {
      if self
           .write_locks
           .get(port_name)
           .map(|sid| sid == sub_id)
           .unwrap_or(false) {
        to_delete.push(port_name.to_string());
      }
    }
    for delete_port in to_delete.iter() {
      self.write_locks.remove(delete_port);
    }
  }

  // Try and lock the port
  pub fn lock_port(&mut self, port_name: &String, sub_id: &String) -> Result<()> {
    self.check_owns_write_lock(port_name, sub_id)?;
    self
      .write_locks
      .insert(port_name.to_string(), sub_id.to_string());
    Ok(())
  }
}

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

  fn check_not_locked_by_anyone(wl_manager: &WriteLockManager,
                                port: &String,
                                sub_ids: Vec<&String>) {
    for sub_id in sub_ids.iter() {
      assert_eq!(false,
                 wl_manager.is_port_write_locked_by(port, sub_id),
                 "Port '{}' should not be locked by '{}'",
                 port,
                 sub_id);
      assert_eq!(false,
                 wl_manager.is_port_locked_by_someone_else(port, sub_id),
                 "Port '{}' should not be locked by someone else",
                 port);

    }
  }

  fn check_locked_by_sub(wl_manager: &WriteLockManager,
                         port: &String,
                         sub_locker: &String,
                         sub_ids: Vec<&String>) {
    assert_eq!(true,
               wl_manager.is_port_write_locked_by(port, sub_locker),
               "Port '{}' should not be locked by '{}'",
               port,
               sub_locker);
    for sub_id in sub_ids.iter() {
      assert_eq!(true,
                 wl_manager.is_port_locked_by_someone_else(port, sub_id),
                 "Port '{}' should not be locked by someone else",
                 port);
    }
  }

  #[test]
  fn test_locking() {
    let wl_manager = &mut WriteLockManager::new();
    let sub_id1: String = "SUB_ID1".to_owned();
    let sub_id3: String = "SUB_ID2".to_owned();
    let sub_id2: String = "SUB_ID3".to_owned();
    let port: String = "/dev/TTY_USB".to_owned();
    // Ports should not be locked
    check_not_locked_by_anyone(&wl_manager, &port, vec![&sub_id1, &sub_id2, &sub_id3]);
    // sub_id1 locking a port should work
    assert_eq!(true,
               wl_manager
                 .lock_port(&port, &sub_id1)
                 .map(|_| true)
                 .unwrap_or(false),
               "Sub_id '{}' locking port '{}' should succeed",
               sub_id1,
               port);
    //Port should now be locked by sub_id1
    check_locked_by_sub(&wl_manager, &port, &sub_id1, vec![&sub_id2, &sub_id3]);
    // sub_id2 should fail locking port already locked
    assert_eq!(true,
               wl_manager
                 .lock_port(&port, &sub_id2)
                 .map(|_| false)
                 .unwrap_or(true),
               "Sub_id '{}' locking port '{}' should fail",
               sub_id1,
               port);
    // sub_id2 should fail unlocking port locked by sub_id1
    assert_eq!(true,
               wl_manager
                 .unlock_port(&port, &sub_id2)
                 .map(|_| false)
                 .unwrap_or(true),
               "Sub_id '{}' unlocking port '{}' should fail",
               sub_id1,
               port);
    // sub_id1 should be able to unlock it
    assert_eq!(true,
               wl_manager
                 .unlock_port(&port, &sub_id1)
                 .map(|_| true)
                 .unwrap_or(false),
               "Sub_id '{}' unlocking port '{}' should succeed",
               sub_id1,
               port);
    // Ports should not be locked
    check_not_locked_by_anyone(&wl_manager, &port, vec![&sub_id1, &sub_id2, &sub_id3]);
    // TODO: Finish testing all other methods
  }

}
<|endoftext|>


<commit_before>use scaly::memory::page::_Page;
use scaly::memory::page::_PAGE_SIZE;

pub const _STACK_PAGES: isize = 0x100;

pub struct _Region<'a> {
    page: &'a mut _Page,
}

impl<'a> _Region<'a> {
    pub fn create(page: & _Page) -> _Region<'a> {
        let our_page_address = page as *const _Page as usize + _PAGE_SIZE;
        let base_stack_bucket_address = our_page_address & !(_PAGE_SIZE * _STACK_PAGES as usize - 1);
        let overflowed_page_address = base_stack_bucket_address + _PAGE_SIZE * _STACK_PAGES as usize;
        if overflowed_page_address == our_page_address {
            panic!("Page stack overflow.");
        }
        _Region {
            page: unsafe { &mut *(our_page_address as *mut _Page) }
        }
    }
}

impl<'a>  Drop for  _Region<'a> {
    fn drop(&mut self) {
        self.page.deallocate_extensions();
    }
}

#[test]
fn test_region() {
    use std::ptr::null_mut;
    use std::alloc::alloc;
    use std::alloc::Layout;
    use scaly::memory::page::_PAGE_SIZE;

    unsafe {
        let memory = alloc(Layout::from_size_align_unchecked(_PAGE_SIZE * _STACK_PAGES as usize, _PAGE_SIZE));
        assert_ne!(memory, null_mut());
        let r1 = _Region::create(& *(memory as *const _Page));
        {
            let r2 = _Region::create(r1.page);
            {
                let _ = _Region::create(r2.page);

            }
        }
    }
}
<commit_msg>StackBucket<commit_after>use scaly::memory::page::_Page;
use scaly::memory::page::_PAGE_SIZE;
use std::alloc::alloc;
use std::alloc::dealloc;
use std::alloc::Layout;
use std::mem::size_of;
use std::ptr::null_mut;

const _STACK_BUCKET_PAGES: usize = 0x100;

pub struct _Region<'a> {
    page: &'a mut _Page,
}

impl<'a> _Region<'a> {
    pub fn create(page: &_Page) -> _Region<'a> {
        let our_page_address = _StackBucket::new_page(page);
        _Region {
            page: unsafe { &mut *(our_page_address as *mut _Page) },
        }
    }
}

impl<'a> Drop for _Region<'a> {
    fn drop(&mut self) {
        self.page.deallocate_extensions();
    }
}

struct _StackBucket {
    next_bucket: *mut _StackBucket,
}

impl _StackBucket {
    pub fn new_page(page: &_Page) -> *mut _Page {
        let page_address = page as *const _Page as usize;
        let stack_bucket_page_address = page_address & !(_PAGE_SIZE * _STACK_BUCKET_PAGES - 1);
        _StackBucket::get_next_page(stack_bucket_page_address, page_address)
    }

    fn get_next_page(stack_bucket_page_address: usize, page_address: usize) -> *mut _Page {
        let overflowed_page_address = stack_bucket_page_address + _PAGE_SIZE * _STACK_BUCKET_PAGES;
        let our_page_address = page_address + _PAGE_SIZE;
        if overflowed_page_address == our_page_address {
            let stack_bucket =
                (stack_bucket_page_address + size_of::<_Page>()) as *mut _StackBucket;
            unsafe { (*stack_bucket).get_page_from_next_bucket() }
        } else {
            our_page_address as *mut _Page
        }
    }

    fn get_page_from_next_bucket(self: &mut _StackBucket) -> *mut _Page {
        if self.next_bucket == null_mut() {
            self.next_bucket = _StackBucket::create();
        }
        _Page::get_page(self.next_bucket as usize)
    }

    fn create() -> *mut _StackBucket {
        unsafe {
            let memory = alloc(Layout::from_size_align_unchecked(
                _PAGE_SIZE * _STACK_BUCKET_PAGES,
                _PAGE_SIZE * _STACK_BUCKET_PAGES,
            ));
            if memory == null_mut() {
                panic!("Unable to crete a new stack bucket: Out of memory.");
            }
            let page = &mut *(memory as *mut _Page);
            page.reset();
            let bucket = page.allocate(_StackBucket {
                next_bucket: null_mut(),
            });
            bucket
        }
    }

    pub fn deallocate(& self) {
        let mut bucket = self as *const _StackBucket;
        unsafe {
            while !(*bucket).next_bucket.is_null() {
                let next_bucket = (*bucket).next_bucket;
                let page = _Page::get_page(bucket as usize);
                dealloc (
                    page as *mut u8,
                    Layout::from_size_align_unchecked(
                    _PAGE_SIZE * _STACK_BUCKET_PAGES,
                    _PAGE_SIZE * _STACK_BUCKET_PAGES,
                ));

                bucket = next_bucket;
            }
        }
    }
}

impl Drop for _StackBucket {
    fn drop(&mut self) {
        self.deallocate();
    }
}

#[test]
fn test_region() {
    unsafe {
        let root_stack_bucket = _StackBucket::create();
        let r1 = _Region::create(&*_Page::get_page(root_stack_bucket as usize));
        {
            let r2 = _Region::create(r1.page);
            {
                let _ = _Region::create(r2.page);
            }
        }
        (*root_stack_bucket).deallocate();
    }
    unsafe {
        let root_stack_bucket = _StackBucket::create();

        let mut r = _Region::create(&*_Page::get_page(root_stack_bucket as usize));
        for _ in 1.._STACK_BUCKET_PAGES * 2 {
            r = _Region::create(r.page);
        }

        (*root_stack_bucket).deallocate();
    }
}
<|endoftext|>


<commit_before>use std::convert::From;
use std::error;
use std::error::Error as StdError;
use std::fmt;
use std::fs;
use std::io;
use std::process::{Command, exit};

use ElmMakeError::{CouldNotRun, Failed};

#[derive(Debug)]
enum ElmMakeError {
    CouldNotRun(io::Error),
    Failed,
}

impl fmt::Display for ElmMakeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        let desc = self.description();
        match self {
            &CouldNotRun(ref e) =>
                write!(f, "{}: {}\nAre the elm tools installed?", desc, e),
            &Failed => write!(f, "{}", desc),
        }
    }
}

impl error::Error for ElmMakeError {
    fn description(&self) -> &str {
        match self {
            &CouldNotRun(_) => "Could not run `elm make`",
            &Failed => "elm-make build failed",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match self {
            &CouldNotRun(ref e) => Some(e),
            &Failed => None,
        }
    }
}

impl From<io::Error> for ElmMakeError {
    fn from(err: io::Error) -> ElmMakeError {
        CouldNotRun(err)
    }
}

fn elm_make_once() -> Result<(), ElmMakeError> {
    // Build the command to run.
    let mut process = Command::new("elm");
    process
        .arg("make")
        .arg("Main.elm")
        .arg("--warn").arg("--yes")
        .arg("--output").arg("../assets/elm.js")
        .current_dir("ui");

    // Try to run the command.
    let status = try!(process.status());
    if !status.success() {
        return Err(Failed);
    }
    Ok(())
}

fn elm_make() -> Result<(), ElmMakeError> {
    if fs::metadata("site/elm-stuff").is_err() {
        println!("Will retry `elm make` if it fails.");
        for i in 0..2 {
            match elm_make_once() {
                Err(Failed) => {
                    println!("Build {} failed, perhaps because of network.", i);
                    println!("Retrying...");
                    continue
                }
                result => return result,
            }
        }
    }
    elm_make_once()
}

fn main() {
    match elm_make() {
        Ok(()) => {}
        Err(ref err) => {
            println!("{}", err);
            exit(1);
        }
    }
}

<commit_msg>Fix path to ui in build script<commit_after>use std::convert::From;
use std::error;
use std::error::Error as StdError;
use std::fmt;
use std::fs;
use std::io;
use std::process::{Command, exit};

use ElmMakeError::{CouldNotRun, Failed};

#[derive(Debug)]
enum ElmMakeError {
    CouldNotRun(io::Error),
    Failed,
}

impl fmt::Display for ElmMakeError {
    fn fmt(&self, f: &mut fmt::Formatter) -> Result<(), fmt::Error> {
        let desc = self.description();
        match self {
            &CouldNotRun(ref e) =>
                write!(f, "{}: {}\nAre the elm tools installed?", desc, e),
            &Failed => write!(f, "{}", desc),
        }
    }
}

impl error::Error for ElmMakeError {
    fn description(&self) -> &str {
        match self {
            &CouldNotRun(_) => "Could not run `elm make`",
            &Failed => "elm-make build failed",
        }
    }

    fn cause(&self) -> Option<&error::Error> {
        match self {
            &CouldNotRun(ref e) => Some(e),
            &Failed => None,
        }
    }
}

impl From<io::Error> for ElmMakeError {
    fn from(err: io::Error) -> ElmMakeError {
        CouldNotRun(err)
    }
}

fn elm_make_once() -> Result<(), ElmMakeError> {
    // Build the command to run.
    let mut process = Command::new("elm");
    process
        .arg("make")
        .arg("Main.elm")
        .arg("--warn").arg("--yes")
        .arg("--output").arg("../assets/elm.js")
        .current_dir("ui");

    // Try to run the command.
    let status = try!(process.status());
    if !status.success() {
        return Err(Failed);
    }
    Ok(())
}

fn elm_make() -> Result<(), ElmMakeError> {
    if fs::metadata("ui/elm-stuff").is_err() {
        println!("Will retry `elm make` if it fails.");
        for i in 0..2 {
            match elm_make_once() {
                Err(Failed) => {
                    println!("Build {} failed, perhaps because of network.", i);
                    println!("Retrying...");
                    continue
                }
                result => return result,
            }
        }
    }
    elm_make_once()
}

fn main() {
    match elm_make() {
        Ok(()) => {}
        Err(ref err) => {
            println!("{}", err);
            exit(1);
        }
    }
}

<|endoftext|>


<commit_before>///
/// Macro to mimick Python's slicing.
///
macro_rules! slice {
    ( $e:expr , [ ; $end_expr:expr ] ) => {
        $e [..$end_expr]
    };
    ( $e:expr , [ $start_expr:expr ; $end_expr:expr] ) => {
        $e [$start_expr..$end_expr]
    };
    ( $e:expr , [ $start_expr:expr ; ] ) => {
        $e [$start_expr..]
    };
    ( $e:expr , [ $start_expr:expr ; $end_expr:expr ; $steps_expr:expr] ) => {
        std::unimplemented();
    };
    ( $e:expr , [ ; $end_expr:expr ; $steps_expr:expr ] ) => {
        std::unimplemented();
    };
    ( $e:expr , [ ; ] ) => {
        std::unimplemented();
    };
}

///
/// Trait for cohercing values types to 'bool', like it is done in
/// the Python's `if`.
///
pub trait Boolable {
    fn get_bool_value(self) -> bool;
}

/*

Wanted to do this (but it conflicted with my other impls:

use num;

impl<T> Boolable for T where T : num::Zero {
    fn get_bool_value(&self) -> bool {
        !self.is_zero()
    }
}
*/

impl     Boolable for     u32 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a u32 { fn get_bool_value(self) -> bool { *self != 0 }}
impl     Boolable for     u16 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a u16 { fn get_bool_value(self) -> bool { *self != 0 }}
impl     Boolable for      u8 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a  u8 { fn get_bool_value(self) -> bool { *self != 0 }}
impl     Boolable for     i32 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a i32 { fn get_bool_value(self) -> bool { *self != 0 }}
impl     Boolable for     i16 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a i16 { fn get_bool_value(self) -> bool { *self != 0 }}
impl     Boolable for      i8 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a  i8 { fn get_bool_value(self) -> bool { *self != 0 }}
impl<'a, T>
         Boolable for &'a [T] { fn get_bool_value(self) -> bool { self.len() != 0 }}
impl<'a>
         Boolable for &'a str { fn get_bool_value(self) -> bool { self.len() != 0 }}
impl     Boolable for bool    { fn get_bool_value(self) -> bool { self }}
impl     Boolable for ()      { fn get_bool_value(self) -> bool { false }}
impl<T1> Boolable for (T1, )  { fn get_bool_value(self) -> bool { true  }}
impl<T1, T2> Boolable for (T1, T2)
                              { fn get_bool_value(self) -> bool { true  }}
impl<T1, T2, T3> Boolable for (T1, T2, T3)
                              { fn get_bool_value(self) -> bool { true  }}

/// Similar to the Python [all](https://docs.python.org/2/library/functions.html#all) builtin.
pub fn all<T, Z>(x : T) -> bool where Z : Boolable, T : Iterator<Item = Z> {
    for v in x {
        if !v.get_bool_value() {
            return false
        }
    }
    true
}

/// Similar to the Python [any](https://docs.python.org/2/library/functions.html#any) builtin.
pub fn any<T, Z>(x : T) -> bool where Z : Boolable, T : Iterator<Item = Z> {
    for v in x {
        if v.get_bool_value() {
            return true
        }
    }
    false
}

#[cfg(test)]
mod tests {
    #[test]
    fn slice() {
        let v : Vec<u32> = vec![1,2,3,4,5,6];

        assert_eq!(&v[2..4], [3, 4]);
        assert_eq!(&slice!(v, [;4]), [1, 2, 3, 4]);
        assert_eq!(&slice!(v, [4;]), [5, 6]);
    }

    #[test]
    fn bool() {
        use super::{Boolable};

        assert_eq!(3.get_bool_value(), true);
        assert_eq!(0.get_bool_value(), false);
        let x : [u32; 0] = [];
        assert_eq!(x.get_bool_value(), false);
        let y : [u32; 1] = [1];
        assert_eq!(y.get_bool_value(), true);
        assert_eq!(true.get_bool_value(), true);
        assert_eq!(false.get_bool_value(), false);
        assert_eq!(" xx".get_bool_value(), true);
        assert_eq!("".get_bool_value(), false);
    }

    #[test]
    fn all_and_any() {
        let empty : [u32;0] = [];
        assert_eq!(super::all(empty.into_iter()), true);
        assert_eq!(super::all([2, 3, 4].into_iter()), true);
        assert_eq!(super::all([2, 0, 4].into_iter()), false);
        assert_eq!(super::any(empty.into_iter()), false);
        assert_eq!(super::any([2, 3, 4].into_iter()), true);
        assert_eq!(super::any([2, 0, 4].into_iter()), true);
        assert_eq!(super::any([0, 0, 0].into_iter()), false);
    }
}
<commit_msg>builtins: reuse 'all' and 'any' intrinsics<commit_after>///
/// Macro to mimick Python's slicing.
///
macro_rules! slice {
    ( $e:expr , [ ; $end_expr:expr ] ) => {
        $e [..$end_expr]
    };
    ( $e:expr , [ $start_expr:expr ; $end_expr:expr] ) => {
        $e [$start_expr..$end_expr]
    };
    ( $e:expr , [ $start_expr:expr ; ] ) => {
        $e [$start_expr..]
    };
    ( $e:expr , [ $start_expr:expr ; $end_expr:expr ; $steps_expr:expr] ) => {
        std::unimplemented();
    };
    ( $e:expr , [ ; $end_expr:expr ; $steps_expr:expr ] ) => {
        std::unimplemented();
    };
    ( $e:expr , [ ; ] ) => {
        std::unimplemented();
    };
}

///
/// Trait for cohercing values types to 'bool', like it is done in
/// the Python's `if`.
///
pub trait Boolable {
    fn get_bool_value(self) -> bool;
}

/*

Wanted to do this (but it conflicted with my other impls:

use num;

impl<T> Boolable for T where T : num::Zero {
    fn get_bool_value(&self) -> bool {
        !self.is_zero()
    }
}
*/

impl     Boolable for     u32 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a u32 { fn get_bool_value(self) -> bool { *self != 0 }}
impl     Boolable for     u16 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a u16 { fn get_bool_value(self) -> bool { *self != 0 }}
impl     Boolable for      u8 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a  u8 { fn get_bool_value(self) -> bool { *self != 0 }}
impl     Boolable for     i32 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a i32 { fn get_bool_value(self) -> bool { *self != 0 }}
impl     Boolable for     i16 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a i16 { fn get_bool_value(self) -> bool { *self != 0 }}
impl     Boolable for      i8 { fn get_bool_value(self) -> bool { self != 0 }}
impl<'a> Boolable for &'a  i8 { fn get_bool_value(self) -> bool { *self != 0 }}
impl<'a, T>
         Boolable for &'a [T] { fn get_bool_value(self) -> bool { self.len() != 0 }}
impl<'a>
         Boolable for &'a str { fn get_bool_value(self) -> bool { self.len() != 0 }}
impl     Boolable for bool    { fn get_bool_value(self) -> bool { self }}
impl     Boolable for ()      { fn get_bool_value(self) -> bool { false }}
impl<T1> Boolable for (T1, )  { fn get_bool_value(self) -> bool { true  }}
impl<T1, T2> Boolable for (T1, T2)
                              { fn get_bool_value(self) -> bool { true  }}
impl<T1, T2, T3> Boolable for (T1, T2, T3)
                              { fn get_bool_value(self) -> bool { true  }}

/// Similar to the Python [all](https://docs.python.org/2/library/functions.html#all) builtin.
pub fn all<I, T>(i : I) -> bool where T : Boolable, I : IntoIterator<Item = T> {
    i.into_iter().all(|e| e.get_bool_value())
}

/// Similar to the Python [any](https://docs.python.org/2/library/functions.html#any) builtin.
pub fn any<I, T>(i : I) -> bool where T : Boolable, I : IntoIterator<Item = T> {
    i.into_iter().any(|e| e.get_bool_value())
}

#[cfg(test)]
mod tests {
    #[test]
    fn slice() {
        let v : Vec<u32> = vec![1,2,3,4,5,6];

        assert_eq!(&v[2..4], [3, 4]);
        assert_eq!(&slice!(v, [;4]), [1, 2, 3, 4]);
        assert_eq!(&slice!(v, [4;]), [5, 6]);
    }

    #[test]
    fn bool() {
        use super::{Boolable};

        assert_eq!(3.get_bool_value(), true);
        assert_eq!(0.get_bool_value(), false);
        let x : [u32; 0] = [];
        assert_eq!(x.get_bool_value(), false);
        let y : [u32; 1] = [1];
        assert_eq!(y.get_bool_value(), true);
        assert_eq!(true.get_bool_value(), true);
        assert_eq!(false.get_bool_value(), false);
        assert_eq!(" xx".get_bool_value(), true);
        assert_eq!("".get_bool_value(), false);
    }

    #[test]
    fn all_and_any() {
        let empty : [u32;0] = [];
        assert_eq!(super::all(empty.iter()), true);
        assert_eq!(super::all([2, 3, 4].iter()), true);
        assert_eq!(super::all([2, 0, 4].iter()), false);
        assert_eq!(super::any(empty.iter()), false);
        assert_eq!(super::any([2, 3, 4].iter()), true);
        assert_eq!(super::any([2, 0, 4].iter()), true);
        assert_eq!(super::any([0, 0, 0].iter()), false);
    }
}
<|endoftext|>


<commit_before>// Implements the `zakopane checksum` subcommand.

use crate::structs::ZakopaneError;

const MAX_TASKS: usize = 8;

struct ChecksumWithPath {
    checksum: String,
    path: std::path::PathBuf,
}

impl ChecksumWithPath {
    pub fn new(checksum: String, path: std::path::PathBuf) -> Self {
        Self { checksum, path }
    }
}

type ChecksumResult = Result<ChecksumWithPath, ZakopaneError>;
type ChecksumTaskJoinHandle = tokio::task::JoinHandle<Vec<ChecksumWithPath>>;

struct ChecksumTaskDispatcherData {
    path: std::path::PathBuf,

    // Rate-limiter for spawned checksum tasks.
    semaphore: std::sync::Arc<tokio::sync::Semaphore>,

    // Counts total number of spawned checksum tasks.
    spawn_counter: std::sync::Arc<std::sync::atomic::AtomicUsize>,

    sender: tokio::sync::mpsc::Sender<ChecksumResult>,
}

impl ChecksumTaskDispatcherData {
    pub fn new(
        path: std::path::PathBuf,
        spawn_counter: std::sync::Arc<std::sync::atomic::AtomicUsize>,
        sender: tokio::sync::mpsc::Sender<ChecksumResult>,
    ) -> Self {
        Self {
            path,
            semaphore: std::sync::Arc::new(tokio::sync::Semaphore::new(MAX_TASKS)),
            spawn_counter,
            sender,
        }
    }
}

// Sends a checksum task result downstream to the collector task.
fn checksum_task_send_result(
    result: ChecksumResult,
    sender: tokio::sync::mpsc::Sender<ChecksumResult>,
) {
    if let Err(e) = sender.blocking_send(result) {
        eprintln!("BUG: Sender::send() failed: {}", e);
    }
}

// Separated from `checksum_task()` to ensure the `add_permits()` call is
// always hit.
fn checksum_task_impl(path: std::path::PathBuf, sender: tokio::sync::mpsc::Sender<ChecksumResult>) {
    let contents = match crate::helpers::ingest_file(path.to_str().unwrap()) {
        Ok(contents) => contents,
        Err(e) => return checksum_task_send_result(Err(e), sender),
    };
    let checksum = crypto_hash::hex_digest(crypto_hash::Algorithm::SHA256, contents.as_ref());
    checksum_task_send_result(Ok(ChecksumWithPath::new(checksum, path)), sender);
}

fn checksum_task(
    path: std::path::PathBuf,
    sender: tokio::sync::mpsc::Sender<ChecksumResult>,
    semaphore_clone: std::sync::Arc<tokio::sync::Semaphore>,
) {
    checksum_task_impl(path, sender);

    // See comment in `ChecksumTaskManager::spawn_task()`.
    semaphore_clone.add_permits(1);
}

async fn collector_task(
    mut receiver: tokio::sync::mpsc::Receiver<ChecksumResult>,
    spawn_counter: std::sync::Arc<std::sync::atomic::AtomicUsize>,
) -> Vec<ChecksumWithPath> {
    let mut sums: Vec<ChecksumWithPath> = Vec::new();
    let mut errors: usize = 0;
    loop {
        while let Some(result) = receiver.recv().await {
            match result {
                Ok(digest_with_path) => sums.push(digest_with_path),
                Err(_) => errors += 1,
            }
        }
        if sums.len() + errors == spawn_counter.load(std::sync::atomic::Ordering::SeqCst) {
            return sums;
        }
    }
}

// Spawns the collector task that listens for checksum results
// provided by the checksum tasks.
async fn spawn_collector(
    path: std::path::PathBuf,
) -> (ChecksumTaskDispatcherData, ChecksumTaskJoinHandle) {
    let (sender, receiver) = tokio::sync::mpsc::channel(MAX_TASKS);
    let spawn_counter = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0));
    let spawn_counter_clone = spawn_counter.clone();
    let join_handle =
        tokio::task::spawn(async move { collector_task(receiver, spawn_counter_clone).await });
    (
        ChecksumTaskDispatcherData::new(path, spawn_counter, sender),
        join_handle,
    )
}

async fn spawn_checksum_tasks(context: ChecksumTaskDispatcherData) {
    let walk_iter = walkdir::WalkDir::new(context.path).into_iter();
    for entry in walk_iter.filter_entry(|e| {
        !e.file_name()
            .to_str()
            .map(|path| path.starts_with(".")) // XXX(j39m)
            .unwrap_or(false)
    }) {
        if let Ok(direntry) = entry {
            let path = direntry.into_path();
            if !path.is_file() {
                continue;
            }

            context
                .spawn_counter
                .fetch_add(1, std::sync::atomic::Ordering::SeqCst);
            let permit = context.semaphore.acquire().await.unwrap();

            // Icky workaround for not being able to pass `SemaphorePermit`
            // directly into a spawned task. Note that new permits are added
            // later in the checksum task.
            //
            // See also: https://github.com/tokio-rs/tokio/issues/1998
            permit.forget();

            let sender = context.sender.clone();
            let semaphore_clone = context.semaphore.clone();
            tokio::task::spawn_blocking(move || checksum_task(path, sender, semaphore_clone))
                .await
                .unwrap();
        }
    }
}

fn pretty_format_checksums(path: std::path::PathBuf, checksums: Vec<ChecksumWithPath>) -> String {
    let mut buffer: Vec<String> = Vec::new();
    for digest_line in checksums {
        buffer.push(format!(
            "{}  ./{}",
            digest_line.checksum,
            digest_line
                .path
                .strip_prefix(&path)
                .unwrap()
                .to_str()
                .unwrap()
        ));
    }
    buffer.join("\n")
}

async fn checksum_impl(path: std::path::PathBuf) -> String {
    let (dispatcher_data, join_handle) = spawn_collector(path.clone()).await;
    spawn_checksum_tasks(dispatcher_data).await;
    let mut checksums: Vec<ChecksumWithPath> = join_handle.await.unwrap();
    checksums.sort_by(|a, b| a.path.cmp(&b.path));
    pretty_format_checksums(path, checksums)
}

pub fn checksum(path: std::path::PathBuf) -> String {
    let runtime = tokio::runtime::Runtime::new().unwrap();
    runtime.block_on(checksum_impl(path))
}
<commit_msg>checksum: Add comments<commit_after>// Implements the `zakopane checksum` subcommand.

use crate::structs::ZakopaneError;

const MAX_TASKS: usize = 8;

struct ChecksumWithPath {
    checksum: String,
    path: std::path::PathBuf,
}

impl ChecksumWithPath {
    pub fn new(checksum: String, path: std::path::PathBuf) -> Self {
        Self { checksum, path }
    }
}

type ChecksumResult = Result<ChecksumWithPath, ZakopaneError>;
type ChecksumTaskJoinHandle = tokio::task::JoinHandle<Vec<ChecksumWithPath>>;

struct ChecksumTaskDispatcherData {
    path: std::path::PathBuf,

    // Rate-limiter for spawned checksum tasks.
    semaphore: std::sync::Arc<tokio::sync::Semaphore>,

    // Counts total number of spawned checksum tasks.
    spawn_counter: std::sync::Arc<std::sync::atomic::AtomicUsize>,

    sender: tokio::sync::mpsc::Sender<ChecksumResult>,
}

impl ChecksumTaskDispatcherData {
    pub fn new(
        path: std::path::PathBuf,
        spawn_counter: std::sync::Arc<std::sync::atomic::AtomicUsize>,
        sender: tokio::sync::mpsc::Sender<ChecksumResult>,
    ) -> Self {
        Self {
            path,
            semaphore: std::sync::Arc::new(tokio::sync::Semaphore::new(MAX_TASKS)),
            spawn_counter,
            sender,
        }
    }
}

// Sends a checksum task result downstream to the collector task.
fn checksum_task_send_result(
    result: ChecksumResult,
    sender: tokio::sync::mpsc::Sender<ChecksumResult>,
) {
    if let Err(e) = sender.blocking_send(result) {
        eprintln!("BUG: Sender::send() failed: {}", e);
    }
}

// Separated from `checksum_task()` to ensure the `add_permits()` call is
// always hit.
fn checksum_task_impl(path: std::path::PathBuf, sender: tokio::sync::mpsc::Sender<ChecksumResult>) {
    let contents = match crate::helpers::ingest_file(path.to_str().unwrap()) {
        Ok(contents) => contents,
        Err(e) => return checksum_task_send_result(Err(e), sender),
    };
    let checksum = crypto_hash::hex_digest(crypto_hash::Algorithm::SHA256, contents.as_ref());
    checksum_task_send_result(Ok(ChecksumWithPath::new(checksum, path)), sender);
}

// Represents a spawned checksum task.
fn checksum_task(
    path: std::path::PathBuf,
    sender: tokio::sync::mpsc::Sender<ChecksumResult>,
    semaphore_clone: std::sync::Arc<tokio::sync::Semaphore>,
) {
    checksum_task_impl(path, sender);

    // See comment in `ChecksumTaskManager::spawn_task()`.
    semaphore_clone.add_permits(1);
}

// Represents the spawned collection task.
async fn collector_task(
    mut receiver: tokio::sync::mpsc::Receiver<ChecksumResult>,
    spawn_counter: std::sync::Arc<std::sync::atomic::AtomicUsize>,
) -> Vec<ChecksumWithPath> {
    let mut sums: Vec<ChecksumWithPath> = Vec::new();
    let mut errors: usize = 0;
    loop {
        while let Some(result) = receiver.recv().await {
            match result {
                Ok(digest_with_path) => sums.push(digest_with_path),
                Err(_) => errors += 1,
            }
        }
        if sums.len() + errors == spawn_counter.load(std::sync::atomic::Ordering::SeqCst) {
            return sums;
        }
    }
}

// Spawns the collector task that listens for checksum results
// provided by the checksum tasks.
async fn spawn_collector(
    path: std::path::PathBuf,
) -> (ChecksumTaskDispatcherData, ChecksumTaskJoinHandle) {
    let (sender, receiver) = tokio::sync::mpsc::channel(MAX_TASKS);
    let spawn_counter = std::sync::Arc::new(std::sync::atomic::AtomicUsize::new(0));
    let spawn_counter_clone = spawn_counter.clone();
    let join_handle =
        tokio::task::spawn(async move { collector_task(receiver, spawn_counter_clone).await });
    (
        ChecksumTaskDispatcherData::new(path, spawn_counter, sender),
        join_handle,
    )
}

async fn spawn_checksum_tasks(context: ChecksumTaskDispatcherData) {
    let walk_iter = walkdir::WalkDir::new(context.path).into_iter();
    for entry in walk_iter.filter_entry(|e| {
        !e.file_name()
            .to_str()
            .map(|path| path.starts_with(".")) // XXX(j39m)
            .unwrap_or(false)
    }) {
        if let Ok(direntry) = entry {
            let path = direntry.into_path();
            if !path.is_file() {
                continue;
            }

            context
                .spawn_counter
                .fetch_add(1, std::sync::atomic::Ordering::SeqCst);
            let permit = context.semaphore.acquire().await.unwrap();

            // Icky workaround for not being able to pass `SemaphorePermit`
            // directly into a spawned task. Note that new permits are added
            // later in the checksum task.
            //
            // See also: https://github.com/tokio-rs/tokio/issues/1998
            permit.forget();

            let sender = context.sender.clone();
            let semaphore_clone = context.semaphore.clone();
            tokio::task::spawn_blocking(move || checksum_task(path, sender, semaphore_clone))
                .await
                .unwrap();
        }
    }
}

// Pretty-prints the sorted `checksums` in a format much like what the
// `sha256sum` binary outputs.
//
// Note that the standard zakopane snapshot header is not added here.
fn pretty_format_checksums(path: std::path::PathBuf, checksums: Vec<ChecksumWithPath>) -> String {
    let mut buffer: Vec<String> = Vec::new();
    for digest_line in checksums {
        buffer.push(format!(
            "{}  ./{}",
            digest_line.checksum,
            digest_line
                .path
                .strip_prefix(&path)
                .unwrap()
                .to_str()
                .unwrap()
        ));
    }
    buffer.join("\n")
}

async fn checksum_impl(path: std::path::PathBuf) -> String {
    let (dispatcher_data, join_handle) = spawn_collector(path.clone()).await;
    spawn_checksum_tasks(dispatcher_data).await;
    let mut checksums: Vec<ChecksumWithPath> = join_handle.await.unwrap();
    checksums.sort_by(|a, b| a.path.cmp(&b.path));
    pretty_format_checksums(path, checksums)
}

pub fn checksum(path: std::path::PathBuf) -> String {
    let runtime = tokio::runtime::Runtime::new().unwrap();
    runtime.block_on(checksum_impl(path))
}
<|endoftext|>


<commit_before>extern crate sql;

pub use sql::lexer::Lexer;
pub use sql::lexer::Token::*;

describe! lexer_test {

    it "create lexer" {
        Lexer::new("some line here");
    }

    it "emptyline" {
        let mut lexer = Lexer::new("");

        assert_eq!(lexer.next_lexem(), None);
    }

    it "word token" {
        let mut lexer = Lexer::new("iNseRt");

        assert_eq!(lexer.next_lexem(), Some(Word("insert".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "left parenthesis" {
        let mut lexer = Lexer::new("(");

        assert_eq!(lexer.next_lexem(), Some(LeftParenthesis));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "right parenthesis" {
        let mut lexer = Lexer::new(")");

        assert_eq!(lexer.next_lexem(), Some(RightParenthesis));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "semicolon" {
        let mut lexer = Lexer::new(";");

        assert_eq!(lexer.next_lexem(), Some(SemiColon));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "single quote" {
        let mut lexer = Lexer::new("'");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "new lines between words" {
        let mut lexer = Lexer::new("one\n\n\n\ntwo\n\n\nthree");

        assert_eq!(lexer.next_lexem(), Some(Word("one".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("two".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("three".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "new lines in the end of lexer line" {
        let mut lexer = Lexer::new("one two three\n\n\n");

        assert_eq!(lexer.next_lexem(), Some(Word("one".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("two".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("three".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "bunch of single quotes separetad spaces as lexer string" {
        let mut lexer = Lexer::new("' '' '' '' '");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), Some(Word(" ' ' ' ".to_string())));
        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }
}
<commit_msg>test: add single quotes test<commit_after>extern crate sql;

pub use sql::lexer::Lexer;
pub use sql::lexer::Token::*;

describe! lexer_test {

    it "create lexer" {
        Lexer::new("some line here");
    }

    it "emptyline" {
        let mut lexer = Lexer::new("");

        assert_eq!(lexer.next_lexem(), None);
    }

    it "word token" {
        let mut lexer = Lexer::new("iNseRt");

        assert_eq!(lexer.next_lexem(), Some(Word("insert".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "left parenthesis" {
        let mut lexer = Lexer::new("(");

        assert_eq!(lexer.next_lexem(), Some(LeftParenthesis));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "right parenthesis" {
        let mut lexer = Lexer::new(")");

        assert_eq!(lexer.next_lexem(), Some(RightParenthesis));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "semicolon" {
        let mut lexer = Lexer::new(";");

        assert_eq!(lexer.next_lexem(), Some(SemiColon));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "single quote" {
        let mut lexer = Lexer::new("'");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "new lines between words" {
        let mut lexer = Lexer::new("one\n\n\n\ntwo\n\n\nthree");

        assert_eq!(lexer.next_lexem(), Some(Word("one".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("two".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("three".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "new lines in the end of lexer line" {
        let mut lexer = Lexer::new("one two three\n\n\n");

        assert_eq!(lexer.next_lexem(), Some(Word("one".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("two".to_string())));
        assert_eq!(lexer.next_lexem(), Some(Word("three".to_string())));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "bunch of single quotes separeted by spaces as lexer string" {
        let mut lexer = Lexer::new("' '' '' '' '");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), Some(Word(" ' ' ' ".to_string())));
        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }

    it "bunch of signle quotes in begin and end of string expression" {
        let mut lexer = Lexer::new("''''' '' '' '''''");

        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), Some(Word("'' ' ' ''".to_string())));
        assert_eq!(lexer.next_lexem(), Some(SingleQuote));
        assert_eq!(lexer.next_lexem(), None);
    }
}
<|endoftext|>


<commit_before><commit_msg>Add support for ‘foo.bar’ style expressions in the parser<commit_after><|endoftext|>


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

use crate::{Coffer, PublicInfo};
use diem_sdk::{
    client::BlockingClient,
    transaction_builder::TransactionFactory,
    types::{chain_id::ChainId, LocalAccount},
};

#[derive(Debug)]
pub struct ChainInfo<'t> {
    pub root_account: &'t mut LocalAccount,
    pub treasury_compliance_account: &'t mut LocalAccount,
    pub designated_dealer_account: &'t mut LocalAccount,
    pub json_rpc_url: String,
    pub chain_id: ChainId,
}

impl<'t> ChainInfo<'t> {
    pub fn new(
        root_account: &'t mut LocalAccount,
        treasury_compliance_account: &'t mut LocalAccount,
        designated_dealer_account: &'t mut LocalAccount,
        json_rpc_url: String,
        chain_id: ChainId,
    ) -> Self {
        Self {
            root_account,
            treasury_compliance_account,
            designated_dealer_account,
            json_rpc_url,
            chain_id,
        }
    }

    pub fn designated_dealer_account(&mut self) -> &mut LocalAccount {
        self.designated_dealer_account
    }

    pub fn root_account(&mut self) -> &mut LocalAccount {
        self.root_account
    }

    pub fn tc_account(&mut self) -> &mut LocalAccount {
        self.treasury_compliance_account
    }

    pub fn json_rpc(&self) -> &str {
        &self.json_rpc_url
    }

    pub fn chain_id(&self) -> ChainId {
        self.chain_id
    }

    pub fn into_public_info(self) -> PublicInfo<'t> {
        PublicInfo::new(
            self.json_rpc_url.clone(),
            self.chain_id,
            Coffer::TreasuryCompliance {
                transaction_factory: TransactionFactory::new(self.chain_id),
                json_rpc_client: BlockingClient::new(self.json_rpc_url),
                treasury_compliance_account: self.treasury_compliance_account,
                designated_dealer_account: self.designated_dealer_account,
            },
        )
    }
}
<commit_msg>forge: rename tc_account -> treasury_compliance_account<commit_after>// Copyright (c) The Diem Core Contributors
// SPDX-License-Identifier: Apache-2.0

use crate::{Coffer, PublicInfo};
use diem_sdk::{
    client::BlockingClient,
    transaction_builder::TransactionFactory,
    types::{chain_id::ChainId, LocalAccount},
};

#[derive(Debug)]
pub struct ChainInfo<'t> {
    pub root_account: &'t mut LocalAccount,
    pub treasury_compliance_account: &'t mut LocalAccount,
    pub designated_dealer_account: &'t mut LocalAccount,
    pub json_rpc_url: String,
    pub chain_id: ChainId,
}

impl<'t> ChainInfo<'t> {
    pub fn new(
        root_account: &'t mut LocalAccount,
        treasury_compliance_account: &'t mut LocalAccount,
        designated_dealer_account: &'t mut LocalAccount,
        json_rpc_url: String,
        chain_id: ChainId,
    ) -> Self {
        Self {
            root_account,
            treasury_compliance_account,
            designated_dealer_account,
            json_rpc_url,
            chain_id,
        }
    }

    pub fn designated_dealer_account(&mut self) -> &mut LocalAccount {
        self.designated_dealer_account
    }

    pub fn root_account(&mut self) -> &mut LocalAccount {
        self.root_account
    }

    pub fn treasury_compliance_account(&mut self) -> &mut LocalAccount {
        self.treasury_compliance_account
    }

    pub fn json_rpc(&self) -> &str {
        &self.json_rpc_url
    }

    pub fn chain_id(&self) -> ChainId {
        self.chain_id
    }

    pub fn into_public_info(self) -> PublicInfo<'t> {
        PublicInfo::new(
            self.json_rpc_url.clone(),
            self.chain_id,
            Coffer::TreasuryCompliance {
                transaction_factory: TransactionFactory::new(self.chain_id),
                json_rpc_client: BlockingClient::new(self.json_rpc_url),
                treasury_compliance_account: self.treasury_compliance_account,
                designated_dealer_account: self.designated_dealer_account,
            },
        )
    }
}
<|endoftext|>


<commit_before>//! An asynchronous, pipelined, PostgreSQL client.
//!
//! # Example
//!
//! ```no_run
//! #![feature(async_await)]
//!
//! use futures::{FutureExt, TryStreamExt};
//! use tokio_postgres::{NoTls, Error, Row};
//!
//! # #[cfg(not(feature = "runtime"))] fn main() {}
//! # #[cfg(feature = "runtime")]
//! #[tokio::main] // By default, tokio_postgres uses the tokio crate as its runtime.
//! async fn main() -> Result<(), Error> {
//!     // Connect to the database.
//!     let (mut client, connection) =
//!         tokio_postgres::connect("host=localhost user=postgres", NoTls).await?;
//!
//!     // The connection object performs the actual communication with the database,
//!     // so spawn it off to run on its own.
//!     let connection = connection.map(|r| {
//!         if let Err(e) = r {
//!             eprintln!("connection error: {}", e);
//!         }
//!     });
//!     tokio::spawn(connection);
//!
//!     // Now we can prepare a simple statement that just returns its parameter.
//!     let stmt = client.prepare("SELECT $1::TEXT").await?;
//!
//!     // And then execute it, returning a Stream of Rows which we collect into a Vec.
//!     let rows: Vec<Row> = client
//!         .query(&stmt, &[&"hello world"])
//!         .try_collect()
//!         .await?;
//!
//!     // Now we can check that we got back the same string we sent over.
//!     let value: &str = rows[0].get(0);
//!     assert_eq!(value, "hello world");
//!
//!     Ok(())
//! }
//! ```
//!
//! # Behavior
//!
//! Calling a method like `Client::query` on its own does nothing. The associated request is not sent to the database
//! until the future returned by the method is first polled. Requests are executed in the order that they are first
//! polled, not in the order that their futures are created.
//!
//! # Pipelining
//!
//! The client supports *pipelined* requests. Pipelining can improve performance in use cases in which multiple,
//! independent queries need to be executed. In a traditional workflow, each query is sent to the server after the
//! previous query completes. In contrast, pipelining allows the client to send all of the queries to the server up
//! front, minimizing time spent by one side waiting for the other to finish sending data:
//!
//! ```not_rust
//!             Sequential                              Pipelined
//! | Client         | Server          |    | Client         | Server          |
//! |----------------|-----------------|    |----------------|-----------------|
//! | send query 1   |                 |    | send query 1   |                 |
//! |                | process query 1 |    | send query 2   | process query 1 |
//! | receive rows 1 |                 |    | send query 3   | process query 2 |
//! | send query 2   |                 |    | receive rows 1 | process query 3 |
//! |                | process query 2 |    | receive rows 2 |                 |
//! | receive rows 2 |                 |    | receive rows 3 |                 |
//! | send query 3   |                 |
//! |                | process query 3 |
//! | receive rows 3 |                 |
//! ```
//!
//! In both cases, the PostgreSQL server is executing the queries sequentially - pipelining just allows both sides of
//! the connection to work concurrently when possible.
//!
//! Pipelining happens automatically when futures are polled concurrently (for example, by using the futures `join`
//! combinator):
//!
//! ```rust
//! use futures::future;
//! use std::future::Future;
//! use tokio_postgres::{Client, Error, Statement};
//!
//! fn pipelined_prepare(
//!     client: &mut Client,
//! ) -> impl Future<Output = Result<(Statement, Statement), Error>>
//! {
//!     future::try_join(
//!         client.prepare("SELECT * FROM foo"),
//!         client.prepare("INSERT INTO bar (id, name) VALUES ($1, $2)")
//!     )
//! }
//! ```
//!
//! # Runtime
//!
//! The client works with arbitrary `AsyncRead + AsyncWrite` streams. Convenience APIs are provided to handle the
//! connection process, but these are gated by the `runtime` Cargo feature, which is enabled by default. If disabled,
//! all dependence on the tokio runtime is removed.
//!
//! # SSL/TLS support
//!
//! TLS support is implemented via external libraries. `Client::connect` and `Config::connect` take a TLS implementation
//! as an argument. The `NoTls` type in this crate can be used when TLS is not required. Otherwise, the
//! `postgres-openssl` and `postgres-native-tls` crates provide implementations backed by the `openssl` and `native-tls`
//! crates, respectively.
#![doc(html_root_url = "https://docs.rs/tokio-postgres/0.4.0-rc.3")]
#![warn(rust_2018_idioms, clippy::all, missing_docs)]

pub use crate::client::Client;
pub use crate::config::Config;
pub use crate::connection::Connection;
use crate::error::DbError;
pub use crate::error::Error;
pub use crate::portal::Portal;
pub use crate::row::{Row, SimpleQueryRow};
#[cfg(feature = "runtime")]
pub use crate::socket::Socket;
#[cfg(feature = "runtime")]
use crate::tls::MakeTlsConnect;
pub use crate::tls::NoTls;
pub use crate::transaction::Transaction;
pub use statement::{Column, Statement};

mod bind;
#[cfg(feature = "runtime")]
mod cancel_query;
mod cancel_query_raw;
mod client;
mod codec;
pub mod config;
#[cfg(feature = "runtime")]
mod connect;
mod connect_raw;
#[cfg(feature = "runtime")]
mod connect_socket;
mod connect_tls;
mod connection;
mod copy_in;
mod copy_out;
pub mod error;
mod maybe_tls_stream;
mod portal;
mod prepare;
mod query;
pub mod row;
mod simple_query;
#[cfg(feature = "runtime")]
mod socket;
mod statement;
pub mod tls;
mod transaction;
pub mod types;

/// A convenience function which parses a connection string and connects to the database.
///
/// See the documentation for [`Config`] for details on the connection string format.
///
/// Requires the `runtime` Cargo feature (enabled by default).
///
/// [`Config`]: ./Config.t.html
#[cfg(feature = "runtime")]
pub async fn connect<T>(
    config: &str,
    tls: T,
) -> Result<(Client, Connection<Socket, T::Stream>), Error>
where
    T: MakeTlsConnect<Socket>,
{
    let config = config.parse::<Config>()?;
    config.connect(tls).await
}

/// An asynchronous notification.
#[derive(Clone, Debug)]
pub struct Notification {
    process_id: i32,
    channel: String,
    payload: String,
}

impl Notification {
    /// The process ID of the notifying backend process.
    pub fn process_id(&self) -> i32 {
        self.process_id
    }

    /// The name of the channel that the notify has been raised on.
    pub fn channel(&self) -> &str {
        &self.channel
    }

    /// The "payload" string passed from the notifying process.
    pub fn payload(&self) -> &str {
        &self.payload
    }
}

/// An asynchronous message from the server.
#[allow(clippy::large_enum_variant)]
pub enum AsyncMessage {
    /// A notice.
    ///
    /// Notices use the same format as errors, but aren't "errors" per-se.
    Notice(DbError),
    /// A notification.
    ///
    /// Connections can subscribe to notifications with the `LISTEN` command.
    Notification(Notification),
    #[doc(hidden)]
    __NonExhaustive,
}

/// Message returned by the `SimpleQuery` stream.
pub enum SimpleQueryMessage {
    /// A row of data.
    Row(SimpleQueryRow),
    /// A statement in the query has completed.
    ///
    /// The number of rows modified or selected is returned.
    CommandComplete(u64),
    #[doc(hidden)]
    __NonExhaustive,
}
<commit_msg>Fix doc link<commit_after>//! An asynchronous, pipelined, PostgreSQL client.
//!
//! # Example
//!
//! ```no_run
//! #![feature(async_await)]
//!
//! use futures::{FutureExt, TryStreamExt};
//! use tokio_postgres::{NoTls, Error, Row};
//!
//! # #[cfg(not(feature = "runtime"))] fn main() {}
//! # #[cfg(feature = "runtime")]
//! #[tokio::main] // By default, tokio_postgres uses the tokio crate as its runtime.
//! async fn main() -> Result<(), Error> {
//!     // Connect to the database.
//!     let (mut client, connection) =
//!         tokio_postgres::connect("host=localhost user=postgres", NoTls).await?;
//!
//!     // The connection object performs the actual communication with the database,
//!     // so spawn it off to run on its own.
//!     let connection = connection.map(|r| {
//!         if let Err(e) = r {
//!             eprintln!("connection error: {}", e);
//!         }
//!     });
//!     tokio::spawn(connection);
//!
//!     // Now we can prepare a simple statement that just returns its parameter.
//!     let stmt = client.prepare("SELECT $1::TEXT").await?;
//!
//!     // And then execute it, returning a Stream of Rows which we collect into a Vec.
//!     let rows: Vec<Row> = client
//!         .query(&stmt, &[&"hello world"])
//!         .try_collect()
//!         .await?;
//!
//!     // Now we can check that we got back the same string we sent over.
//!     let value: &str = rows[0].get(0);
//!     assert_eq!(value, "hello world");
//!
//!     Ok(())
//! }
//! ```
//!
//! # Behavior
//!
//! Calling a method like `Client::query` on its own does nothing. The associated request is not sent to the database
//! until the future returned by the method is first polled. Requests are executed in the order that they are first
//! polled, not in the order that their futures are created.
//!
//! # Pipelining
//!
//! The client supports *pipelined* requests. Pipelining can improve performance in use cases in which multiple,
//! independent queries need to be executed. In a traditional workflow, each query is sent to the server after the
//! previous query completes. In contrast, pipelining allows the client to send all of the queries to the server up
//! front, minimizing time spent by one side waiting for the other to finish sending data:
//!
//! ```not_rust
//!             Sequential                              Pipelined
//! | Client         | Server          |    | Client         | Server          |
//! |----------------|-----------------|    |----------------|-----------------|
//! | send query 1   |                 |    | send query 1   |                 |
//! |                | process query 1 |    | send query 2   | process query 1 |
//! | receive rows 1 |                 |    | send query 3   | process query 2 |
//! | send query 2   |                 |    | receive rows 1 | process query 3 |
//! |                | process query 2 |    | receive rows 2 |                 |
//! | receive rows 2 |                 |    | receive rows 3 |                 |
//! | send query 3   |                 |
//! |                | process query 3 |
//! | receive rows 3 |                 |
//! ```
//!
//! In both cases, the PostgreSQL server is executing the queries sequentially - pipelining just allows both sides of
//! the connection to work concurrently when possible.
//!
//! Pipelining happens automatically when futures are polled concurrently (for example, by using the futures `join`
//! combinator):
//!
//! ```rust
//! use futures::future;
//! use std::future::Future;
//! use tokio_postgres::{Client, Error, Statement};
//!
//! fn pipelined_prepare(
//!     client: &mut Client,
//! ) -> impl Future<Output = Result<(Statement, Statement), Error>>
//! {
//!     future::try_join(
//!         client.prepare("SELECT * FROM foo"),
//!         client.prepare("INSERT INTO bar (id, name) VALUES ($1, $2)")
//!     )
//! }
//! ```
//!
//! # Runtime
//!
//! The client works with arbitrary `AsyncRead + AsyncWrite` streams. Convenience APIs are provided to handle the
//! connection process, but these are gated by the `runtime` Cargo feature, which is enabled by default. If disabled,
//! all dependence on the tokio runtime is removed.
//!
//! # SSL/TLS support
//!
//! TLS support is implemented via external libraries. `Client::connect` and `Config::connect` take a TLS implementation
//! as an argument. The `NoTls` type in this crate can be used when TLS is not required. Otherwise, the
//! `postgres-openssl` and `postgres-native-tls` crates provide implementations backed by the `openssl` and `native-tls`
//! crates, respectively.
#![doc(html_root_url = "https://docs.rs/tokio-postgres/0.4.0-rc.3")]
#![warn(rust_2018_idioms, clippy::all, missing_docs)]

pub use crate::client::Client;
pub use crate::config::Config;
pub use crate::connection::Connection;
use crate::error::DbError;
pub use crate::error::Error;
pub use crate::portal::Portal;
pub use crate::row::{Row, SimpleQueryRow};
#[cfg(feature = "runtime")]
pub use crate::socket::Socket;
#[cfg(feature = "runtime")]
use crate::tls::MakeTlsConnect;
pub use crate::tls::NoTls;
pub use crate::transaction::Transaction;
pub use statement::{Column, Statement};

mod bind;
#[cfg(feature = "runtime")]
mod cancel_query;
mod cancel_query_raw;
mod client;
mod codec;
pub mod config;
#[cfg(feature = "runtime")]
mod connect;
mod connect_raw;
#[cfg(feature = "runtime")]
mod connect_socket;
mod connect_tls;
mod connection;
mod copy_in;
mod copy_out;
pub mod error;
mod maybe_tls_stream;
mod portal;
mod prepare;
mod query;
pub mod row;
mod simple_query;
#[cfg(feature = "runtime")]
mod socket;
mod statement;
pub mod tls;
mod transaction;
pub mod types;

/// A convenience function which parses a connection string and connects to the database.
///
/// See the documentation for [`Config`] for details on the connection string format.
///
/// Requires the `runtime` Cargo feature (enabled by default).
///
/// [`Config`]: config/struct.Config.html
#[cfg(feature = "runtime")]
pub async fn connect<T>(
    config: &str,
    tls: T,
) -> Result<(Client, Connection<Socket, T::Stream>), Error>
where
    T: MakeTlsConnect<Socket>,
{
    let config = config.parse::<Config>()?;
    config.connect(tls).await
}

/// An asynchronous notification.
#[derive(Clone, Debug)]
pub struct Notification {
    process_id: i32,
    channel: String,
    payload: String,
}

impl Notification {
    /// The process ID of the notifying backend process.
    pub fn process_id(&self) -> i32 {
        self.process_id
    }

    /// The name of the channel that the notify has been raised on.
    pub fn channel(&self) -> &str {
        &self.channel
    }

    /// The "payload" string passed from the notifying process.
    pub fn payload(&self) -> &str {
        &self.payload
    }
}

/// An asynchronous message from the server.
#[allow(clippy::large_enum_variant)]
pub enum AsyncMessage {
    /// A notice.
    ///
    /// Notices use the same format as errors, but aren't "errors" per-se.
    Notice(DbError),
    /// A notification.
    ///
    /// Connections can subscribe to notifications with the `LISTEN` command.
    Notification(Notification),
    #[doc(hidden)]
    __NonExhaustive,
}

/// Message returned by the `SimpleQuery` stream.
pub enum SimpleQueryMessage {
    /// A row of data.
    Row(SimpleQueryRow),
    /// A statement in the query has completed.
    ///
    /// The number of rows modified or selected is returned.
    CommandComplete(u64),
    #[doc(hidden)]
    __NonExhaustive,
}
<|endoftext|>


<commit_before>fn each(v: &mut [u32], op: &fn(v: &mut u32)) {
	let mut n = 0;
	while n < v.len() {
		op(&mut v[n]);
		n += 1;
	}
}

struct Mem {
	data:	[u8, ..4096]
}

impl Mem {
	fn read(&self, addr: u32) -> u8 {
		self.data[addr]
	}

	fn write(&mut self, addr: u32, val: u8) {
		self.data[addr] = val;
	}
}

struct Beta {
	pc:			u32,
	register:	[u32, ..31],
	memory:		Mem
}

impl Beta {
	fn reset(&mut self) {
		self.pc = 0;
		do each(self.register) |r| { *r = 0; }

		//println(fmt!("reset. pc at %d", self.pc as int));
	}

	fn tick(&mut self) {
		self.pc += 4;
		//println(fmt!("tick. pc at %d", self.pc as int));
	}
}

fn main() {
	let mut b = ~Beta {
		pc: 10u32,
		register: [3u32, ..31],
		memory: Mem {
			data: [0u8, ..4*1024]
		}
	};

	b.reset();
	b.tick();
	println("success");
}
<commit_msg>Memory can be read byte-wise or word-wise.<commit_after>fn each(v: &mut [u32], op: &fn(v: &mut u32)) {
	let mut n = 0;
	while n < v.len() {
		op(&mut v[n]);
		n += 1;
	}
}

struct Mem {
	data:	[u8, ..4096]
}

impl Mem {
	fn read(&self, addr: u32) -> u8 {
		self.data[addr]
	}

	fn read_word(&self, addr: u32) -> u32 {
		let b1 = self.read(addr) as u32;
		let b2 = self.read(addr + 1) as u32;
		let b3 = self.read(addr + 2) as u32;
		let b4 = self.read(addr + 3) as u32;

		(b1 << 24) | (b2 << 16) | (b3 << 8) | b4
	}

	fn write(&mut self, addr: u32, val: u8) {
		self.data[addr] = val;
	}
}

struct Beta {
	pc:			u32,
	register:	[u32, ..31],
	mem:		Mem
}

impl Beta {
	fn reset(&mut self) {
		self.pc = 0;
		do each(self.register) |r| { *r = 0; }

		//println(fmt!("reset. pc at %d", self.pc as int));
	}

	fn tick(&mut self) {
		let instruction: u32 = self.mem.read_word(self.pc);

		self.pc += 4;
		//println(fmt!("tick. pc at %d", self.pc as int));
	}
}

fn main() {
	let mut b = ~Beta {
		pc: 10u32,
		register: [3u32, ..31],
		mem: Mem {
			data: [0u8, ..4*1024]
		}
	};

	b.reset();
	b.tick();
	println("success");
}
<|endoftext|>