<commit_before>/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

use std::collections::HashMap;
use std::time::Duration;

use aws_config::meta::region::RegionProviderChain;
use aws_http::AwsErrorRetryPolicy;
use aws_sdk_dynamodb::client::fluent_builders::Query;
use aws_sdk_dynamodb::error::DescribeTableError;
use aws_sdk_dynamodb::input::DescribeTableInput;
use aws_sdk_dynamodb::middleware::DefaultMiddleware;
use aws_sdk_dynamodb::model::{
    AttributeDefinition, AttributeValue, KeySchemaElement, KeyType, ProvisionedThroughput,
    ScalarAttributeType, TableStatus,
};
use aws_sdk_dynamodb::operation::DescribeTable;
use aws_sdk_dynamodb::output::DescribeTableOutput;
use aws_sdk_dynamodb::{Client, Config, Error, Region, PKG_VERSION};
use aws_smithy_client::erase::DynConnector;
use aws_smithy_http::operation::Operation;
use aws_smithy_http::result::{SdkError, SdkSuccess};
use aws_smithy_http::retry::ClassifyResponse;
use aws_smithy_types::retry::RetryKind;
use serde_json::Value;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Opt {
    /// The AWS Region.
    #[structopt(short, long)]
    region: Option<String>,

    /// The name of the table.
    #[structopt(short, long)]
    table: String,

    /// Whether to display additional information.
    #[structopt(short, long)]
    verbose: bool,
}

/// A partial reimplementation of
/// <https://docs.amazonaws.cn/en_us/amazondynamodb/latest/developerguide/GettingStarted.Ruby.html>
/// in Rust
///
/// - Create table
/// - Wait for table to be ready
/// - Add a couple of rows
/// - Query for those rows
#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt::init();

    let Opt {
        region,
        table,
        verbose,
    } = Opt::from_args();

    let region_provider = RegionProviderChain::first_try(region.map(Region::new))
        .or_default_provider()
        .or_else(Region::new("us-west-2"));
    let shared_config = aws_config::from_env().region(region_provider).load().await;

    println!();

    if verbose {
        println!("DynamoDB client version: {}", PKG_VERSION);
        println!(
            "Region:                  {}",
            shared_config.region().unwrap()
        );
        println!("Table:                   {}", &table);
        println!();
    }

    let client = Client::new(&shared_config);

    let raw_client = aws_smithy_client::Client::<DynConnector, DefaultMiddleware>::dyn_https();

    let table_exists = does_table_exist(&client, &table).await?;

    if !table_exists {
        println!("Creating table.");

        create_table(&client, &table.to_string())
            .send()
            .await
            .expect("failed to create table");
    }

    raw_client
        .call(wait_for_ready_table(&table.to_string(), client.conf()).await)
        .await
        .expect("table should become ready");

    // data.json contains 2 movies from 2013
    let data = match serde_json::from_str(include_str!("data.json")).expect("should be valid JSON")
    {
        Value::Array(inner) => inner,
        data => panic!("data must be an array, got: {:?}", data),
    };

    println!("Adding items to table.");

    for value in data {
        add_item(&client, &table, value).await?;
    }

    println!("Making sure table has items.");

    let films_2222 = movies_in_year(&client, &table.to_string(), 2222)
        .send()
        .await
        .expect("query should succeed");

    // this isn't back to the future, there are no movies from 2022
    assert_eq!(films_2222.count(), 0);

    let films_2013 = movies_in_year(&client, &table.to_string(), 2013)
        .send()
        .await
        .expect("query should succeed");

    assert_eq!(films_2013.count(), 2);

    let titles: Vec<AttributeValue> = films_2013
        .items()
        .unwrap()
        .iter_mut()
        .map(|row| row.remove("title").expect("row should have title"))
        .collect();

    assert_eq!(
        titles,
        vec![
            AttributeValue::S("Rush".to_string()),
            AttributeValue::S("Turn It Down, Or Else!".to_string())
        ]
    );

    println!("Deleting table.");

    delete_table(&client, &table).await
}

// Does table exist?
// snippet-start:[dynamodb.rust.movies-does_table_exist]
async fn does_table_exist(client: &Client, table: &str) -> Result<bool, Error> {
    let table_exists = client
        .list_tables()
        .send()
        .await
        .expect("should succeed")
        .table_names()
        .as_ref()
        .unwrap()
        .contains(&table.into());

    Ok(table_exists)
}
// snippet-end:[dynamodb.rust.movies-does_table_exist]

// snippet-start:[dynamodb.rust.movies-create_table]
fn create_table(
    client: &Client,
    table_name: &str,
) -> aws_sdk_dynamodb::client::fluent_builders::CreateTable {
    client
        .create_table()
        .table_name(table_name)
        .key_schema(
            KeySchemaElement::builder()
                .attribute_name("year")
                .key_type(KeyType::Hash)
                .build(),
        )
        .key_schema(
            KeySchemaElement::builder()
                .attribute_name("title")
                .key_type(KeyType::Range)
                .build(),
        )
        .attribute_definitions(
            AttributeDefinition::builder()
                .attribute_name("year")
                .attribute_type(ScalarAttributeType::N)
                .build(),
        )
        .attribute_definitions(
            AttributeDefinition::builder()
                .attribute_name("title")
                .attribute_type(ScalarAttributeType::S)
                .build(),
        )
        .provisioned_throughput(
            ProvisionedThroughput::builder()
                .read_capacity_units(10)
                .write_capacity_units(10)
                .build(),
        )
}
// snippet-end:[dynamodb.rust.movies-create_table]

fn parse_item(value: Value) -> HashMap<String, AttributeValue> {
    match value_to_item(value) {
        AttributeValue::M(map) => map,
        other => panic!("can only insert top level values, got {:?}", other),
    }
}

fn value_to_item(value: Value) -> AttributeValue {
    match value {
        Value::Null => AttributeValue::Null(true),
        Value::Bool(b) => AttributeValue::Bool(b),
        Value::Number(n) => AttributeValue::N(n.to_string()),
        Value::String(s) => AttributeValue::S(s),
        Value::Array(a) => AttributeValue::L(a.into_iter().map(value_to_item).collect()),
        Value::Object(o) => {
            AttributeValue::M(o.into_iter().map(|(k, v)| (k, value_to_item(v))).collect())
        }
    }
}

// Add an item to the table.
// snippet-start:[dynamodb.rust.movies-add_item]
async fn add_item(client: &Client, table: &str, value: serde_json::Value) -> Result<(), Error> {
    client
        .put_item()
        .table_name(table)
        .set_item(Some(parse_item(value)))
        .send()
        .await?;

    Ok(())
}
// snippet-end:[dynamodb.rust.movies-add_item]

// snippet-start:[dynamodb.rust.movies-movies_in_year]
fn movies_in_year(client: &Client, table_name: &str, year: u16) -> Query {
    client
        .query()
        .table_name(table_name)
        .key_condition_expression("#yr = :yyyy")
        .expression_attribute_names("#yr", "year")
        .expression_attribute_values(":yyyy", AttributeValue::N(year.to_string()))
}
// snippet-end:[dynamodb.rust.movies-movies_in_year]

// Deletes a table.
// snippet-start:[dynamodb.rust.movies-delete_table]
async fn delete_table(client: &Client, table: &str) -> Result<(), Error> {
    client.delete_table().table_name(table).send().await?;

    Ok(())
}
// snippet-end:[dynamodb.rust.movies-delete_table]

/// Hand-written waiter to retry every second until the table is out of `Creating` state
#[derive(Clone)]
struct WaitForReadyTable<R> {
    inner: R,
}

impl<R> ClassifyResponse<SdkSuccess<DescribeTableOutput>, SdkError<DescribeTableError>>
    for WaitForReadyTable<R>
where
    R: ClassifyResponse<SdkSuccess<DescribeTableOutput>, SdkError<DescribeTableError>>,
{
    fn classify(
        &self,
        response: Result<&SdkSuccess<DescribeTableOutput>, &SdkError<DescribeTableError>>,
    ) -> RetryKind {
        match self.inner.classify(response) {
            RetryKind::NotRetryable => (),
            other => return other,
        };
        match response {
            Ok(SdkSuccess { parsed, .. }) => {
                if parsed
                    .table
                    .as_ref()
                    .unwrap()
                    .table_status
                    .as_ref()
                    .unwrap()
                    == &TableStatus::Creating
                {
                    RetryKind::Explicit(Duration::from_secs(1))
                } else {
                    RetryKind::NotRetryable
                }
            }
            _ => RetryKind::NotRetryable,
        }
    }
}

/// Construct a `DescribeTable` request with a policy to retry every second until the table
/// is ready
async fn wait_for_ready_table(
    table_name: &str,
    conf: &Config,
) -> Operation<DescribeTable, WaitForReadyTable<AwsErrorRetryPolicy>> {
    let operation = DescribeTableInput::builder()
        .table_name(table_name)
        .build()
        .expect("valid input")
        .make_operation(conf)
        .await
        .expect("valid operation");
    let waiting_policy = WaitForReadyTable {
        inner: operation.retry_policy().clone(),
    };
    operation.with_retry_policy(waiting_policy)
}
<commit_msg>Update movies.rs<commit_after>/*
 * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved.
 * SPDX-License-Identifier: Apache-2.0.
 */

use std::collections::HashMap;
use std::time::Duration;

use aws_config::meta::region::RegionProviderChain;
use aws_http::AwsErrorRetryPolicy;
use aws_sdk_dynamodb::client::fluent_builders::Query;
use aws_sdk_dynamodb::error::DescribeTableError;
use aws_sdk_dynamodb::input::DescribeTableInput;
use aws_sdk_dynamodb::middleware::DefaultMiddleware;
use aws_sdk_dynamodb::model::{
    AttributeDefinition, AttributeValue, KeySchemaElement, KeyType, ProvisionedThroughput,
    ScalarAttributeType, TableStatus,
};
use aws_sdk_dynamodb::operation::DescribeTable;
use aws_sdk_dynamodb::output::DescribeTableOutput;
use aws_sdk_dynamodb::{Client, Config, Error, Region, PKG_VERSION};
use aws_smithy_client::erase::DynConnector;
use aws_smithy_http::operation::Operation;
use aws_smithy_http::result::{SdkError, SdkSuccess};
use aws_smithy_http::retry::ClassifyResponse;
use aws_smithy_types::retry::RetryKind;
use serde_json::Value;
use structopt::StructOpt;

#[derive(Debug, StructOpt)]
struct Opt {
    /// The AWS Region.
    #[structopt(short, long)]
    region: Option<String>,

    /// The name of the table.
    #[structopt(short, long)]
    table: String,

    /// Whether to display additional information.
    #[structopt(short, long)]
    verbose: bool,
}

/// A partial reimplementation of
/// <https://docs.amazonaws.cn/en_us/amazondynamodb/latest/developerguide/GettingStarted.Ruby.html>
/// in Rust
///
/// - Create table
/// - Wait for table to be ready
/// - Add a couple of rows
/// - Query for those rows
#[tokio::main]
async fn main() -> Result<(), Error> {
    tracing_subscriber::fmt::init();

    let Opt {
        region,
        table,
        verbose,
    } = Opt::from_args();

    let region_provider = RegionProviderChain::first_try(region.map(Region::new))
        .or_default_provider()
        .or_else(Region::new("us-west-2"));
    let shared_config = aws_config::from_env().region(region_provider).load().await;

    println!();

    if verbose {
        println!("DynamoDB client version: {}", PKG_VERSION);
        println!(
            "Region:                  {}",
            shared_config.region().unwrap()
        );
        println!("Table:                   {}", &table);
        println!();
    }

    let client = Client::new(&shared_config);

    let raw_client = aws_smithy_client::Client::<DynConnector, DefaultMiddleware>::dyn_https();

    let table_exists = does_table_exist(&client, &table).await?;

    if !table_exists {
        println!("Creating table.");

        create_table(&client, &table.to_string())
            .send()
            .await
            .expect("failed to create table");
    }

    raw_client
        .call(wait_for_ready_table(&table.to_string(), client.conf()).await)
        .await
        .expect("table should become ready");

    // data.json contains 2 movies from 2013
    let data = match serde_json::from_str(include_str!("data.json")).expect("should be valid JSON")
    {
        Value::Array(inner) => inner,
        data => panic!("data must be an array, got: {:?}", data),
    };

    println!("Adding items to table.");

    for value in data {
        add_item(&client, &table, value).await?;
    }

    println!("Making sure table has items.");

    let films_2222 = movies_in_year(&client, &table.to_string(), 2222)
        .send()
        .await
        .expect("query should succeed");

    // this isn't back to the future, there are no movies from 2022
    assert_eq!(films_2222.count(), 0);

    let films_2013 = movies_in_year(&client, &table.to_string(), 2013)
        .send()
        .await
        .expect("query should succeed");

    assert_eq!(films_2013.count(), 2);

    let titles: Vec<AttributeValue> = films_2013
        .items
        .unwrap()
        .iter_mut()
        .map(|row| row.remove("title").expect("row should have title"))
        .collect();

    assert_eq!(
        titles,
        vec![
            AttributeValue::S("Rush".to_string()),
            AttributeValue::S("Turn It Down, Or Else!".to_string())
        ]
    );

    println!("Deleting table.");

    delete_table(&client, &table).await
}

// Does table exist?
// snippet-start:[dynamodb.rust.movies-does_table_exist]
async fn does_table_exist(client: &Client, table: &str) -> Result<bool, Error> {
    let table_exists = client
        .list_tables()
        .send()
        .await
        .expect("should succeed")
        .table_names()
        .as_ref()
        .unwrap()
        .contains(&table.into());

    Ok(table_exists)
}
// snippet-end:[dynamodb.rust.movies-does_table_exist]

// snippet-start:[dynamodb.rust.movies-create_table]
fn create_table(
    client: &Client,
    table_name: &str,
) -> aws_sdk_dynamodb::client::fluent_builders::CreateTable {
    client
        .create_table()
        .table_name(table_name)
        .key_schema(
            KeySchemaElement::builder()
                .attribute_name("year")
                .key_type(KeyType::Hash)
                .build(),
        )
        .key_schema(
            KeySchemaElement::builder()
                .attribute_name("title")
                .key_type(KeyType::Range)
                .build(),
        )
        .attribute_definitions(
            AttributeDefinition::builder()
                .attribute_name("year")
                .attribute_type(ScalarAttributeType::N)
                .build(),
        )
        .attribute_definitions(
            AttributeDefinition::builder()
                .attribute_name("title")
                .attribute_type(ScalarAttributeType::S)
                .build(),
        )
        .provisioned_throughput(
            ProvisionedThroughput::builder()
                .read_capacity_units(10)
                .write_capacity_units(10)
                .build(),
        )
}
// snippet-end:[dynamodb.rust.movies-create_table]

fn parse_item(value: Value) -> HashMap<String, AttributeValue> {
    match value_to_item(value) {
        AttributeValue::M(map) => map,
        other => panic!("can only insert top level values, got {:?}", other),
    }
}

fn value_to_item(value: Value) -> AttributeValue {
    match value {
        Value::Null => AttributeValue::Null(true),
        Value::Bool(b) => AttributeValue::Bool(b),
        Value::Number(n) => AttributeValue::N(n.to_string()),
        Value::String(s) => AttributeValue::S(s),
        Value::Array(a) => AttributeValue::L(a.into_iter().map(value_to_item).collect()),
        Value::Object(o) => {
            AttributeValue::M(o.into_iter().map(|(k, v)| (k, value_to_item(v))).collect())
        }
    }
}

// Add an item to the table.
// snippet-start:[dynamodb.rust.movies-add_item]
async fn add_item(client: &Client, table: &str, value: serde_json::Value) -> Result<(), Error> {
    client
        .put_item()
        .table_name(table)
        .set_item(Some(parse_item(value)))
        .send()
        .await?;

    Ok(())
}
// snippet-end:[dynamodb.rust.movies-add_item]

// snippet-start:[dynamodb.rust.movies-movies_in_year]
fn movies_in_year(client: &Client, table_name: &str, year: u16) -> Query {
    client
        .query()
        .table_name(table_name)
        .key_condition_expression("#yr = :yyyy")
        .expression_attribute_names("#yr", "year")
        .expression_attribute_values(":yyyy", AttributeValue::N(year.to_string()))
}
// snippet-end:[dynamodb.rust.movies-movies_in_year]

// Deletes a table.
// snippet-start:[dynamodb.rust.movies-delete_table]
async fn delete_table(client: &Client, table: &str) -> Result<(), Error> {
    client.delete_table().table_name(table).send().await?;

    Ok(())
}
// snippet-end:[dynamodb.rust.movies-delete_table]

/// Hand-written waiter to retry every second until the table is out of `Creating` state
#[derive(Clone)]
struct WaitForReadyTable<R> {
    inner: R,
}

impl<R> ClassifyResponse<SdkSuccess<DescribeTableOutput>, SdkError<DescribeTableError>>
    for WaitForReadyTable<R>
where
    R: ClassifyResponse<SdkSuccess<DescribeTableOutput>, SdkError<DescribeTableError>>,
{
    fn classify(
        &self,
        response: Result<&SdkSuccess<DescribeTableOutput>, &SdkError<DescribeTableError>>,
    ) -> RetryKind {
        match self.inner.classify(response) {
            RetryKind::NotRetryable => (),
            other => return other,
        };
        match response {
            Ok(SdkSuccess { parsed, .. }) => {
                if parsed
                    .table
                    .as_ref()
                    .unwrap()
                    .table_status
                    .as_ref()
                    .unwrap()
                    == &TableStatus::Creating
                {
                    RetryKind::Explicit(Duration::from_secs(1))
                } else {
                    RetryKind::NotRetryable
                }
            }
            _ => RetryKind::NotRetryable,
        }
    }
}

/// Construct a `DescribeTable` request with a policy to retry every second until the table
/// is ready
async fn wait_for_ready_table(
    table_name: &str,
    conf: &Config,
) -> Operation<DescribeTable, WaitForReadyTable<AwsErrorRetryPolicy>> {
    let operation = DescribeTableInput::builder()
        .table_name(table_name)
        .build()
        .expect("valid input")
        .make_operation(conf)
        .await
        .expect("valid operation");
    let waiting_policy = WaitForReadyTable {
        inner: operation.retry_policy().clone(),
    };
    operation.with_retry_policy(waiting_policy)
}
<|endoftext|>


<commit_before>use openssl::ssl::{SslMethod, SslConnectorBuilder};
use std::io::{Read, Write};
use std::net::{TcpStream, TcpListener};
use std::thread;

use super::*;

#[test]
fn connect_google() {
    let builder = TlsConnector::builder().unwrap().build().unwrap();
    let s = TcpStream::connect("google.com:443").unwrap();
    let mut socket = builder.connect("google.com", s).unwrap();

    socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
    let mut result = vec![];
    socket.read_to_end(&mut result).unwrap();

    println!("{}", String::from_utf8_lossy(&result));
    assert!(result.starts_with(b"HTTP/1.0"));
    assert!(result.ends_with(b"\r\n") || result.ends_with(b""));
}

#[test]
fn connect_bad_hostname() {
    let builder = TlsConnector::builder().unwrap().build().unwrap();
    let s = TcpStream::connect("wrong.host.badssl.com:443").unwrap();
    assert!(builder.connect("wrong.host.badssl.com", s).is_err());
}

#[test]
fn server() {
    let buf = include_bytes!("../test/identity.p12");
    let pkcs12 = Pkcs12::from_der(buf, "mypass").unwrap();
    let builder = TlsAcceptor::builder(pkcs12).unwrap().build().unwrap();

    let listener = TcpListener::bind("0.0.0.0:15410").unwrap();
    let port = listener.local_addr().unwrap().port();

    thread::spawn(move || {
        let socket = listener.accept().unwrap().0;
        let mut socket = builder.accept(socket).unwrap();

        let mut buf = [0; 5];
        socket.read_exact(&mut buf).unwrap();
        assert_eq!(&buf, b"hello");

        socket.write_all(b"world").unwrap();
    });

    let socket = TcpStream::connect(("localhost", port)).unwrap();
    let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
    builder.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
    let connector = builder.build();
    let mut socket = connector.connect("foobar.com", socket).unwrap();
    assert_eq!(socket.ssl().version(), "TLSv1.2");
    socket.write_all(b"hello").unwrap();
    let mut buf = vec![];
    socket.read_to_end(&mut buf).unwrap();
    assert_eq!(buf, b"world");
}
<commit_msg>Unlock port<commit_after>use openssl::ssl::{SslMethod, SslConnectorBuilder};
use std::io::{Read, Write};
use std::net::{TcpStream, TcpListener};
use std::thread;

use super::*;

#[test]
fn connect_google() {
    let builder = TlsConnector::builder().unwrap().build().unwrap();
    let s = TcpStream::connect("google.com:443").unwrap();
    let mut socket = builder.connect("google.com", s).unwrap();

    socket.write_all(b"GET / HTTP/1.0\r\n\r\n").unwrap();
    let mut result = vec![];
    socket.read_to_end(&mut result).unwrap();

    println!("{}", String::from_utf8_lossy(&result));
    assert!(result.starts_with(b"HTTP/1.0"));
    assert!(result.ends_with(b"\r\n") || result.ends_with(b""));
}

#[test]
fn connect_bad_hostname() {
    let builder = TlsConnector::builder().unwrap().build().unwrap();
    let s = TcpStream::connect("wrong.host.badssl.com:443").unwrap();
    assert!(builder.connect("wrong.host.badssl.com", s).is_err());
}

#[test]
fn server() {
    let buf = include_bytes!("../test/identity.p12");
    let pkcs12 = Pkcs12::from_der(buf, "mypass").unwrap();
    let builder = TlsAcceptor::builder(pkcs12).unwrap().build().unwrap();

    let listener = TcpListener::bind("0.0.0.0:0").unwrap();
    let port = listener.local_addr().unwrap().port();

    thread::spawn(move || {
        let socket = listener.accept().unwrap().0;
        let mut socket = builder.accept(socket).unwrap();

        let mut buf = [0; 5];
        socket.read_exact(&mut buf).unwrap();
        assert_eq!(&buf, b"hello");

        socket.write_all(b"world").unwrap();
    });

    let socket = TcpStream::connect(("localhost", port)).unwrap();
    let mut builder = SslConnectorBuilder::new(SslMethod::tls()).unwrap();
    builder.builder_mut().set_ca_file("test/root-ca.pem").unwrap();
    let connector = builder.build();
    let mut socket = connector.connect("foobar.com", socket).unwrap();
    assert_eq!(socket.ssl().version(), "TLSv1.2");
    socket.write_all(b"hello").unwrap();
    let mut buf = vec![];
    socket.read_to_end(&mut buf).unwrap();
    assert_eq!(buf, b"world");
}
<|endoftext|>


<commit_before>use std::collections::Bitv;
use geolocation::GeoLocation;
use boundingbox::BoundingBox;

//static BASE32_CODES: [char, ..32] = [
static BASE32_CODES: [char; 32] = [
    '0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', 'b', 'c', 'd', 'e', 'f', 'g',
    'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r',
    's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
];

//static BASE32_INDICES: [int, ..75]=[
static BASE32_INDICES: [int; 75]=[
	 0,  1,  2,  3,  4,  5,  6,  7, // 30-37, '0'..'7'
	 8,  9, -1, -1, -1, -1, -1, -1, // 38-2F, '8','9'
	-1, -1, 10, 11, 12, 13, 14, 15, // 40-47, 'B'..'G'
	16, -1, 17, 18, -1, 19, 20, -1, // 48-4F, 'H','J','K','M','N'
	21, 22, 23, 24, 25, 26, 27, 28, // 50-57, 'P'..'W'
	29, 30, 31, -1, -1, -1, -1, -1, // 58-5F, 'X'..'Z'
	-1, -1, 10, 11, 12, 13, 14, 15, // 60-67, 'b'..'g'
	16, -1, 17, 18, -1, 19, 20, -1, // 68-6F, 'h','j','k','m','n'
	21, 22, 23, 24, 25, 26, 27, 28, // 70-77, 'p'..'w'
	29, 30, 31,                     // 78-7A, 'x'..'z'
];

/// Binary hash code for a given `GeoLocation` with specific precision
#[derive(Default, Copy, PartialEq)]
pub struct BinaryHash {
    bits : u64,
    precision : uint,
}

///
impl BinaryHash {
    /// Create an empty `BinaryHash`
    pub fn new() -> BinaryHash {
        BinaryHash{
            bits: 0u64,
            precision: 0u,
        }
    }

    /// Create a `BinaryHash` from a `Bitv`
    ///
    /// # Example
    ///
    /// ```
    /// use std::collections::Bitv;
    /// let a=0b11100110;
    /// let bv = Bitv::from_bytes(&[a]);
    /// assert_eq!(geohashrust::BinaryHash::from_bitv(&bv).to_string(), "11100110");
    /// ```
    pub fn from_bitv(bv: &Bitv) -> BinaryHash {
        let mut output=BinaryHash::new();
        for b in bv.iter() {
            output.push(b)
        }
        output
    }

    /// Create a `BinaryHash` from a String
    ///
    /// # Example
    ///
    /// ```
    /// let bh=geohashrust::BinaryHash::from_string("11100110");
    /// assert_eq!(bh.to_string(), "11100110");
    /// ```
    pub fn from_string(s: &str) -> BinaryHash {
        let mut output=BinaryHash::new();
        for c in s.chars() {
            match c {
                '0' => output.push(false),
                '1' => output.push(true),
                _ => panic!("Invalid binary code"),
            }
        }
        output
    }

    /// Encode a `GeoLocation` into binary hash
    ///
    /// # Example
    ///
    /// ```
    /// let l=geohashrust::GeoLocation{
    ///         latitude:31.23,
    ///         longitude:121.473,
    /// };
    /// let bh=geohashrust::BinaryHash::encode(l, 8);
    /// assert_eq!(bh.to_string(), "11100110");
    /// ```
    pub fn encode(l: GeoLocation, precision: uint) -> BinaryHash {
        let mut bbox = BoundingBox::from_coordinates(-90.0, 90.0, -180.0, 180.0);
        let mut islon = true;

        let mut output=BinaryHash::new();

        while output.len() < precision {
            if islon {
                let mid = (bbox.max_lon + bbox.min_lon) / 2.0;
                if l.longitude > mid {
                    output.push(true);
                    bbox.min_lon=mid;
                } else {
                    output.push(false);
                    bbox.max_lon=mid;
                }
            } else {
                let mid = (bbox.max_lat + bbox.min_lat) / 2.0;
                if l.latitude > mid  {
                    output.push(true);
                    bbox.min_lat = mid;
                } else {
                    output.push(false);
                    bbox.max_lat = mid;
                }
            }
            islon = !islon;
        }
        output
    }

    /// Decode binary hash into a `BoundingBox`
    ///
    /// # Example
    ///
    /// ```
    /// let bh=geohashrust::BinaryHash::from_string("11100");
    /// let bbox=bh.decode();
    /// assert!(bbox.contains(geohashrust::GeoLocation::from_coordinates(21.0, 113.0)));
    /// ```
    pub fn decode(&self) -> BoundingBox {
        let mut output = BoundingBox::from_coordinates(-90.0, 90.0, -180.0, 180.0);
        let mut islon = true;

        for n in range(0u, self.precision) {
            if islon {
                let mid = (output.max_lon + output.min_lon) / 2.0;
                if self.test(n) {
                    output.min_lon = mid;
                } else {
                    output.max_lon = mid;
                }
            } else {
                let mid = (output.max_lat + output.min_lat) / 2.0;
                if self.test(n) {
                    output.min_lat = mid;
                } else {
                    output.max_lat = mid;
                }
            }
            islon = !islon;
        }
        output
    }

    /// Decode binary hash into a `BoundingBox`
    ///
    /// # Example
    ///
    /// ```
    /// let bbox=geohashrust::BinaryHash::decode_string("11100");
    /// assert!(bbox.contains(geohashrust::GeoLocation::from_coordinates(21.0, 113.0)));
    /// ```
    pub fn decode_string(s: &str) -> BoundingBox {
        BinaryHash::from_string(s).decode()
    }

    /// Convert `BinaryHash` to a `Bitv`
    ///
    /// # Example
    ///
    /// ```
    /// use std::collections::Bitv;
    /// let a=0b11100110;
    /// let bv = Bitv::from_bytes(&[a]);
    /// let bh=geohashrust::BinaryHash::from_string("11100110");
    /// assert_eq!(bh.to_bitv(), bv);
    /// ```
    pub fn to_bitv(&self) -> Bitv {
        let mut output=Bitv::with_capacity(self.precision);
        for n in range(0u, self.precision) {
            output.push(self.test(n))
        }
        output
    }

    /// Convert `BinaryHash` to a `String`
    ///
    /// # Example
    ///
    /// ```
    /// let bh=geohashrust::BinaryHash::from_string("11100110");
    /// assert_eq!(bh.to_string(), "11100110");
    /// ```
    pub fn to_string(&self) -> String {
        let mut output=String::with_capacity(self.precision);
        for n in range(0u, self.precision) {
            output.push(if self.test(n) {'1'} else {'0'})
        }
        output
    }

    /// Return the count of effective bits in the binary hash
    ///
    /// # Example
    ///
    /// ```
    /// let mut bh=geohashrust::BinaryHash::new();
    /// assert_eq!(bh.len(), 0u);
    /// bh.push(true);
    /// bh.push(true);
    /// assert_eq!(bh.len(), 2u);
    /// bh.push(false);
    /// bh.push(true);
    /// assert_eq!(bh.len(), 4u);
    /// ```
    pub fn len(&self) -> uint {
        self.precision
    }

    /// Test if the binary hash is empty
    ///
    /// # Example
    ///
    /// ```
    /// let mut bh=geohashrust::BinaryHash::new();
    /// assert!(bh.empty());
    /// bh.push(true);
    /// bh.push(true);
    /// bh.push(false);
    /// bh.push(true);
    /// assert!(!bh.empty());
    /// ```
    pub fn empty(&self) -> bool {
        self.precision == 0u
    }

    /// Test specific bit of the binary hash
    ///
    /// # Example
    ///
    /// ```
    /// let mut bh=geohashrust::BinaryHash::new();
    /// bh.push(true);
    /// bh.push(true);
    /// bh.push(false);
    /// bh.push(true);
    /// assert!(bh.test(0));
    /// assert!(bh.test(1));
    /// assert!(!bh.test(2));
    /// assert!(bh.test(3));
    /// ```
    pub fn test(&self, n: uint) -> bool {
        (self.bits & (1u64 << (self.precision-n-1u))) != 0
    }

    /// Push a bit into binary hash
    ///
    /// # Example
    ///
    /// ```
    /// let mut bh=geohashrust::BinaryHash::new();
    /// bh.push(true);
    /// bh.push(true);
    /// bh.push(false);
    /// bh.push(true);
    /// assert_eq!(bh.to_string(), "1101");
    /// ```
    pub fn push(&mut self, b: bool) {
        self.bits <<= 1u;
        self.bits |= if b {1u64} else {0u64};
        self.precision += 1u;
    }
}

/// Encode a `GeoLocation` into GeoHash with given precision
///
/// # Example
///
/// ```
/// let l=geohashrust::GeoLocation{
///         latitude:31.16373922,
///         longitude:121.62585927,
/// };
/// assert_eq!(geohashrust::encode(l, 7u), "wtw3r9j");
/// ```
pub fn encode(l: GeoLocation, precision: uint) -> String {
	let mut bbox = BoundingBox::from_coordinates(-90.0, 90.0, -180.0, 180.0);
    let mut islon = true;
    let mut num_bits = 0u;
    let mut hash_index = 0u;

    // Pre-Allocate the hash string
    let mut output=String::with_capacity(precision);

    while output.len() < precision {
        if islon {
            let mid = (bbox.max_lon + bbox.min_lon) / 2.0;
            if l.longitude > mid {
                hash_index = (hash_index << 1) + 1;
                bbox.min_lon=mid;
            } else {
                hash_index = (hash_index << 1) + 0;
                bbox.max_lon=mid;
            }
        } else {
            let mid = (bbox.max_lat + bbox.min_lat) / 2.0;
            if l.latitude > mid  {
                hash_index = (hash_index << 1) + 1;
                bbox.min_lat = mid;
            } else {
                hash_index = (hash_index << 1) + 0;
                bbox.max_lat = mid;
            }
        }
        islon = !islon;

        num_bits+=1;
        if num_bits%5==0 {
            output.push(BASE32_CODES[hash_index]);
            hash_index = 0;
        }
    }
    output
}

/// Decode a GeoHash into a `BoundingBox`
///
/// # Example
///
/// ```
/// let bbox=geohashrust::decode("wtw3r9jjz");
/// assert!(bbox.contains(geohashrust::GeoLocation::from_coordinates(31.163728, 121.625841)));
/// ```
pub fn decode(hash: &str) -> BoundingBox {
    let mut output = BoundingBox::from_coordinates(-90.0, 90.0, -180.0, 180.0);
    let mut islon = true;

    for c in hash.chars() {
        assert!(c>='0' && c<='z');
        let char_index = BASE32_INDICES[(c as uint)-48];

        for bits in range(0u, 5).rev() {
            let bit = ((char_index >> bits) & 1)==1;
            if islon {
                let mid = (output.max_lon + output.min_lon) / 2.0;
                if bit {
                    output.min_lon = mid;
                } else {
                    output.max_lon = mid;
                }
            } else {
                let mid = (output.max_lat + output.min_lat) / 2.0;
                if bit {
                    output.min_lat = mid;
                } else {
                    output.max_lat = mid;
                }
            }
            islon = !islon;
        }
    }
    println!("min_lat:{}, max_lat:{}, min_long:{}, max_lon:{}", output.min_lat, output.max_lat, output.min_lon, output.max_lon);
    output
}

/// Get the neighbor of GeoHash on specific direction
///
/// # Example
///
/// ```
/// assert_eq!(geohashrust::neighbor("wtw3s", (-1, -1)), "wtw37");
/// assert_eq!(geohashrust::neighbor("wtw3sjj", (1, -1)), "wtw3sjk");
/// ```
pub fn neighbor(hash: &str, direction: (int, int)) -> String {
	let b = decode(hash);
	let cp = b.center();
	encode(match direction {
		(dlat, dlon) => GeoLocation::from_coordinates(
			cp.latitude + b.latitude_range() * (dlat as f64),
			cp.longitude + b.longitude_range() * (dlon as f64),
		)
	}, hash.len())
}

/// Get a vector of neighbors for the GeoHash on all 8 directions, with itself as the first
///
/// # Example
///
/// ```
/// let ns=geohashrust::neighbors("wtw3s");
/// assert_eq!(ns[0], "wtw3s");
/// assert_eq!(ns[1], "wtw37");
/// assert_eq!(ns[2], "wtw3k");
/// assert_eq!(ns[3], "wtw3m");
/// assert_eq!(ns[4], "wtw3e");
/// assert_eq!(ns[5], "wtw3t");
/// assert_eq!(ns[6], "wtw3g");
/// assert_eq!(ns[7], "wtw3u");
/// assert_eq!(ns[8], "wtw3v");
/// ```
pub fn neighbors(hash: &str) -> Box<Vec<String>> {
	box vec![
		hash.to_string(),
		neighbor(hash, (-1, -1)),
		neighbor(hash, (-1,  0)),
		neighbor(hash, (-1,  1)),
		neighbor(hash, ( 0, -1)),
		neighbor(hash, ( 0,  1)),
		neighbor(hash, ( 1, -1)),
		neighbor(hash, ( 1,  0)),
		neighbor(hash, ( 1,  1)),
	]
}

<commit_msg>Cleanup<commit_after>use std::collections::Bitv;
use geolocation::GeoLocation;
use boundingbox::BoundingBox;

static BASE32_CODES: [char; 32] = [
    '0', '1', '2', '3', '4', '5', '6', '7',
    '8', '9', 'b', 'c', 'd', 'e', 'f', 'g',
    'h', 'j', 'k', 'm', 'n', 'p', 'q', 'r',
    's', 't', 'u', 'v', 'w', 'x', 'y', 'z',
];

static BASE32_INDICES: [int; 75]=[
	 0,  1,  2,  3,  4,  5,  6,  7, // 30-37, '0'..'7'
	 8,  9, -1, -1, -1, -1, -1, -1, // 38-2F, '8','9'
	-1, -1, 10, 11, 12, 13, 14, 15, // 40-47, 'B'..'G'
	16, -1, 17, 18, -1, 19, 20, -1, // 48-4F, 'H','J','K','M','N'
	21, 22, 23, 24, 25, 26, 27, 28, // 50-57, 'P'..'W'
	29, 30, 31, -1, -1, -1, -1, -1, // 58-5F, 'X'..'Z'
	-1, -1, 10, 11, 12, 13, 14, 15, // 60-67, 'b'..'g'
	16, -1, 17, 18, -1, 19, 20, -1, // 68-6F, 'h','j','k','m','n'
	21, 22, 23, 24, 25, 26, 27, 28, // 70-77, 'p'..'w'
	29, 30, 31,                     // 78-7A, 'x'..'z'
];

/// Binary hash code for a given `GeoLocation` with specific precision
#[derive(Default, Copy, PartialEq)]
pub struct BinaryHash {
    bits : u64,
    precision : uint,
}

///
impl BinaryHash {
    /// Create an empty `BinaryHash`
    pub fn new() -> BinaryHash {
        BinaryHash{
            bits: 0u64,
            precision: 0u,
        }
    }

    /// Create a `BinaryHash` from a `Bitv`
    ///
    /// # Example
    ///
    /// ```
    /// use std::collections::Bitv;
    /// let a=0b11100110;
    /// let bv = Bitv::from_bytes(&[a]);
    /// assert_eq!(geohashrust::BinaryHash::from_bitv(&bv).to_string(), "11100110");
    /// ```
    pub fn from_bitv(bv: &Bitv) -> BinaryHash {
        let mut output=BinaryHash::new();
        for b in bv.iter() {
            output.push(b)
        }
        output
    }

    /// Create a `BinaryHash` from a String
    ///
    /// # Example
    ///
    /// ```
    /// let bh=geohashrust::BinaryHash::from_string("11100110");
    /// assert_eq!(bh.to_string(), "11100110");
    /// ```
    pub fn from_string(s: &str) -> BinaryHash {
        let mut output=BinaryHash::new();
        for c in s.chars() {
            match c {
                '0' => output.push(false),
                '1' => output.push(true),
                _ => panic!("Invalid binary code"),
            }
        }
        output
    }

    /// Encode a `GeoLocation` into binary hash
    ///
    /// # Example
    ///
    /// ```
    /// let l=geohashrust::GeoLocation{
    ///         latitude:31.23,
    ///         longitude:121.473,
    /// };
    /// let bh=geohashrust::BinaryHash::encode(l, 8);
    /// assert_eq!(bh.to_string(), "11100110");
    /// ```
    pub fn encode(l: GeoLocation, precision: uint) -> BinaryHash {
        let mut bbox = BoundingBox::from_coordinates(-90.0, 90.0, -180.0, 180.0);
        let mut islon = true;

        let mut output=BinaryHash::new();

        while output.len() < precision {
            if islon {
                let mid = (bbox.max_lon + bbox.min_lon) / 2.0;
                if l.longitude > mid {
                    output.push(true);
                    bbox.min_lon=mid;
                } else {
                    output.push(false);
                    bbox.max_lon=mid;
                }
            } else {
                let mid = (bbox.max_lat + bbox.min_lat) / 2.0;
                if l.latitude > mid  {
                    output.push(true);
                    bbox.min_lat = mid;
                } else {
                    output.push(false);
                    bbox.max_lat = mid;
                }
            }
            islon = !islon;
        }
        output
    }

    /// Decode binary hash into a `BoundingBox`
    ///
    /// # Example
    ///
    /// ```
    /// let bh=geohashrust::BinaryHash::from_string("11100");
    /// let bbox=bh.decode();
    /// assert!(bbox.contains(geohashrust::GeoLocation::from_coordinates(21.0, 113.0)));
    /// ```
    pub fn decode(&self) -> BoundingBox {
        let mut output = BoundingBox::from_coordinates(-90.0, 90.0, -180.0, 180.0);
        let mut islon = true;

        for n in range(0u, self.precision) {
            if islon {
                let mid = (output.max_lon + output.min_lon) / 2.0;
                if self.test(n) {
                    output.min_lon = mid;
                } else {
                    output.max_lon = mid;
                }
            } else {
                let mid = (output.max_lat + output.min_lat) / 2.0;
                if self.test(n) {
                    output.min_lat = mid;
                } else {
                    output.max_lat = mid;
                }
            }
            islon = !islon;
        }
        output
    }

    /// Decode binary hash into a `BoundingBox`
    ///
    /// # Example
    ///
    /// ```
    /// let bbox=geohashrust::BinaryHash::decode_string("11100");
    /// assert!(bbox.contains(geohashrust::GeoLocation::from_coordinates(21.0, 113.0)));
    /// ```
    pub fn decode_string(s: &str) -> BoundingBox {
        BinaryHash::from_string(s).decode()
    }

    /// Convert `BinaryHash` to a `Bitv`
    ///
    /// # Example
    ///
    /// ```
    /// use std::collections::Bitv;
    /// let a=0b11100110;
    /// let bv = Bitv::from_bytes(&[a]);
    /// let bh=geohashrust::BinaryHash::from_string("11100110");
    /// assert_eq!(bh.to_bitv(), bv);
    /// ```
    pub fn to_bitv(&self) -> Bitv {
        let mut output=Bitv::with_capacity(self.precision);
        for n in range(0u, self.precision) {
            output.push(self.test(n))
        }
        output
    }

    /// Convert `BinaryHash` to a `String`
    ///
    /// # Example
    ///
    /// ```
    /// let bh=geohashrust::BinaryHash::from_string("11100110");
    /// assert_eq!(bh.to_string(), "11100110");
    /// ```
    pub fn to_string(&self) -> String {
        let mut output=String::with_capacity(self.precision);
        for n in range(0u, self.precision) {
            output.push(if self.test(n) {'1'} else {'0'})
        }
        output
    }

    /// Return the count of effective bits in the binary hash
    ///
    /// # Example
    ///
    /// ```
    /// let mut bh=geohashrust::BinaryHash::new();
    /// assert_eq!(bh.len(), 0u);
    /// bh.push(true);
    /// bh.push(true);
    /// assert_eq!(bh.len(), 2u);
    /// bh.push(false);
    /// bh.push(true);
    /// assert_eq!(bh.len(), 4u);
    /// ```
    pub fn len(&self) -> uint {
        self.precision
    }

    /// Test if the binary hash is empty
    ///
    /// # Example
    ///
    /// ```
    /// let mut bh=geohashrust::BinaryHash::new();
    /// assert!(bh.empty());
    /// bh.push(true);
    /// bh.push(true);
    /// bh.push(false);
    /// bh.push(true);
    /// assert!(!bh.empty());
    /// ```
    pub fn empty(&self) -> bool {
        self.precision == 0u
    }

    /// Test specific bit of the binary hash
    ///
    /// # Example
    ///
    /// ```
    /// let mut bh=geohashrust::BinaryHash::new();
    /// bh.push(true);
    /// bh.push(true);
    /// bh.push(false);
    /// bh.push(true);
    /// assert!(bh.test(0));
    /// assert!(bh.test(1));
    /// assert!(!bh.test(2));
    /// assert!(bh.test(3));
    /// ```
    pub fn test(&self, n: uint) -> bool {
        (self.bits & (1u64 << (self.precision-n-1u))) != 0
    }

    /// Push a bit into binary hash
    ///
    /// # Example
    ///
    /// ```
    /// let mut bh=geohashrust::BinaryHash::new();
    /// bh.push(true);
    /// bh.push(true);
    /// bh.push(false);
    /// bh.push(true);
    /// assert_eq!(bh.to_string(), "1101");
    /// ```
    pub fn push(&mut self, b: bool) {
        self.bits <<= 1u;
        self.bits |= if b {1u64} else {0u64};
        self.precision += 1u;
    }
}

/// Encode a `GeoLocation` into GeoHash with given precision
///
/// # Example
///
/// ```
/// let l=geohashrust::GeoLocation{
///         latitude:31.16373922,
///         longitude:121.62585927,
/// };
/// assert_eq!(geohashrust::encode(l, 7u), "wtw3r9j");
/// ```
pub fn encode(l: GeoLocation, precision: uint) -> String {
	let mut bbox = BoundingBox::from_coordinates(-90.0, 90.0, -180.0, 180.0);
    let mut islon = true;
    let mut num_bits = 0u;
    let mut hash_index = 0u;

    // Pre-Allocate the hash string
    let mut output=String::with_capacity(precision);

    while output.len() < precision {
        if islon {
            let mid = (bbox.max_lon + bbox.min_lon) / 2.0;
            if l.longitude > mid {
                hash_index = (hash_index << 1) + 1;
                bbox.min_lon=mid;
            } else {
                hash_index = (hash_index << 1) + 0;
                bbox.max_lon=mid;
            }
        } else {
            let mid = (bbox.max_lat + bbox.min_lat) / 2.0;
            if l.latitude > mid  {
                hash_index = (hash_index << 1) + 1;
                bbox.min_lat = mid;
            } else {
                hash_index = (hash_index << 1) + 0;
                bbox.max_lat = mid;
            }
        }
        islon = !islon;

        num_bits+=1;
        if num_bits%5==0 {
            output.push(BASE32_CODES[hash_index]);
            hash_index = 0;
        }
    }
    output
}

/// Decode a GeoHash into a `BoundingBox`
///
/// # Example
///
/// ```
/// let bbox=geohashrust::decode("wtw3r9jjz");
/// assert!(bbox.contains(geohashrust::GeoLocation::from_coordinates(31.163728, 121.625841)));
/// ```
pub fn decode(hash: &str) -> BoundingBox {
    let mut output = BoundingBox::from_coordinates(-90.0, 90.0, -180.0, 180.0);
    let mut islon = true;

    for c in hash.chars() {
        assert!(c>='0' && c<='z');
        let char_index = BASE32_INDICES[(c as uint)-48];

        for bits in range(0u, 5).rev() {
            let bit = ((char_index >> bits) & 1)==1;
            if islon {
                let mid = (output.max_lon + output.min_lon) / 2.0;
                if bit {
                    output.min_lon = mid;
                } else {
                    output.max_lon = mid;
                }
            } else {
                let mid = (output.max_lat + output.min_lat) / 2.0;
                if bit {
                    output.min_lat = mid;
                } else {
                    output.max_lat = mid;
                }
            }
            islon = !islon;
        }
    }
    println!("min_lat:{}, max_lat:{}, min_long:{}, max_lon:{}", output.min_lat, output.max_lat, output.min_lon, output.max_lon);
    output
}

/// Get the neighbor of GeoHash on specific direction
///
/// # Example
///
/// ```
/// assert_eq!(geohashrust::neighbor("wtw3s", (-1, -1)), "wtw37");
/// assert_eq!(geohashrust::neighbor("wtw3sjj", (1, -1)), "wtw3sjk");
/// ```
pub fn neighbor(hash: &str, direction: (int, int)) -> String {
	let b = decode(hash);
	let cp = b.center();
	encode(match direction {
		(dlat, dlon) => GeoLocation::from_coordinates(
			cp.latitude + b.latitude_range() * (dlat as f64),
			cp.longitude + b.longitude_range() * (dlon as f64),
		)
	}, hash.len())
}

/// Get a vector of neighbors for the GeoHash on all 8 directions, with itself as the first
///
/// # Example
///
/// ```
/// let ns=geohashrust::neighbors("wtw3s");
/// assert_eq!(ns[0], "wtw3s");
/// assert_eq!(ns[1], "wtw37");
/// assert_eq!(ns[2], "wtw3k");
/// assert_eq!(ns[3], "wtw3m");
/// assert_eq!(ns[4], "wtw3e");
/// assert_eq!(ns[5], "wtw3t");
/// assert_eq!(ns[6], "wtw3g");
/// assert_eq!(ns[7], "wtw3u");
/// assert_eq!(ns[8], "wtw3v");
/// ```
pub fn neighbors(hash: &str) -> Box<Vec<String>> {
	box vec![
		hash.to_string(),
		neighbor(hash, (-1, -1)),
		neighbor(hash, (-1,  0)),
		neighbor(hash, (-1,  1)),
		neighbor(hash, ( 0, -1)),
		neighbor(hash, ( 0,  1)),
		neighbor(hash, ( 1, -1)),
		neighbor(hash, ( 1,  0)),
		neighbor(hash, ( 1,  1)),
	]
}

<|endoftext|>


<commit_before>//! Utility functions

use hl::*;

pub fn create_compute_context() -> Result<(Device, Context, CommandQueue), &'static str>
{
    let platforms = get_platforms();
    if platforms.len() == 0 {
        return Err("No platform found");
    }

    let mut devices = platforms[0].get_devices();
    if let Some(device) = devices.remove(0) {
        let context = device.create_context();
        let queue = context.create_command_queue(&device);

        Ok((device, context, queue))
    } else {
        return Err("No devices found");
    }
}

#[deriving(Copy)]
pub enum PreferedType {
    Any,

    CPUPrefered,
    GPUPrefered,

    CPUOnly,
    GPUOnly,
}

pub fn create_compute_context_prefer(cltype: PreferedType) -> Result<(Device, Context, CommandQueue), &'static str>
{
    let platforms = get_platforms();
    for platform in platforms.iter() {
        let types = match cltype {
            PreferedType::Any => vec![DeviceType::CPU, DeviceType::GPU],
            PreferedType::CPUPrefered | PreferedType::CPUOnly => vec![DeviceType::CPU],
            PreferedType::GPUPrefered | PreferedType::GPUOnly => vec![DeviceType::GPU]
        };

        let mut devices = platform.get_devices_by_types(types.as_slice());
        if let Some(device) = devices.remove(0) {
            let context = device.create_context();
            let queue = context.create_command_queue(&device);
            return Ok((device, context, queue));
        }
    }

    match cltype {
        PreferedType::Any |
        PreferedType::CPUPrefered |
        PreferedType::GPUPrefered => create_compute_context(),
        _ => Err("Could not find valid implementation")
    }
}
<commit_msg>Fixed remove change<commit_after>//! Utility functions

use hl::*;

pub fn create_compute_context() -> Result<(Device, Context, CommandQueue), &'static str>
{
    let platforms = get_platforms();
    if platforms.len() == 0 {
        return Err("No platform found");
    }

    let mut devices = platforms[0].get_devices();
    if devices.len() == 0 {
        Err("No device found")
    } else {
        let device = devices.remove(0);
        let context = device.create_context();
        let queue = context.create_command_queue(&device);
        Ok((device, context, queue))
    }
}

#[deriving(Copy)]
pub enum PreferedType {
    Any,

    CPUPrefered,
    GPUPrefered,

    CPUOnly,
    GPUOnly,
}

pub fn create_compute_context_prefer(cltype: PreferedType) -> Result<(Device, Context, CommandQueue), &'static str>
{
    let platforms = get_platforms();
    for platform in platforms.iter() {
        let types = match cltype {
            PreferedType::Any => vec![DeviceType::CPU, DeviceType::GPU],
            PreferedType::CPUPrefered | PreferedType::CPUOnly => vec![DeviceType::CPU],
            PreferedType::GPUPrefered | PreferedType::GPUOnly => vec![DeviceType::GPU]
        };

        let mut devices = platform.get_devices_by_types(types.as_slice());
        if devices.len() > 0 {
            let device = devices.remove(0);
            let context = device.create_context();
            let queue = context.create_command_queue(&device);
            return Ok((device, context, queue))
        }
    }

    match cltype {
        PreferedType::Any |
        PreferedType::CPUPrefered |
        PreferedType::GPUPrefered => create_compute_context(),
        _ => Err("Could not find valid implementation")
    }
}
<|endoftext|>


<commit_before>use std::marker::PhantomData;

use super::Query;
use crate::backend::{Backend, DieselReserveSpecialization};
use crate::connection::Connection;
use crate::query_builder::{AstPass, QueryFragment, QueryId};
use crate::query_dsl::RunQueryDsl;
use crate::result::QueryResult;
use crate::serialize::ToSql;
use crate::sql_types::{HasSqlType, Untyped};

#[derive(Debug, Clone)]
#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
/// The return value of `sql_query`.
///
/// Unlike most queries in Diesel, `SqlQuery` loads its data by column name,
/// rather than by index. This means that you cannot deserialize this query into
/// a tuple, and any structs used must implement `QueryableByName`.
///
/// See [`sql_query`](crate::sql_query()) for examples.
pub struct SqlQuery<Inner = self::private::Empty> {
    inner: Inner,
    query: String,
}

impl<Inner> SqlQuery<Inner> {
    pub(crate) fn new(inner: Inner, query: String) -> Self {
        SqlQuery { inner, query }
    }

    /// Bind a value for use with this SQL query. The given query should have
    /// placeholders that vary based on the database type,
    /// like [SQLite Parameter](https://sqlite.org/lang_expr.html#varparam) syntax,
    /// [PostgreSQL PREPARE syntax](https://www.postgresql.org/docs/current/sql-prepare.html),
    /// or [MySQL bind syntax](https://dev.mysql.com/doc/refman/8.0/en/mysql-stmt-bind-param.html).
    ///
    /// # Safety
    ///
    /// This function should be used with care, as Diesel cannot validate that
    /// the value is of the right type nor can it validate that you have passed
    /// the correct number of parameters.
    ///
    /// # Example
    ///
    /// ```
    /// # include!("../doctest_setup.rs");
    /// #
    /// # use schema::users;
    /// #
    /// # #[derive(QueryableByName, Debug, PartialEq)]
    /// # #[diesel(table_name = users)]
    /// # struct User {
    /// #     id: i32,
    /// #     name: String,
    /// # }
    /// #
    /// # fn main() {
    /// #     use diesel::sql_query;
    /// #     use diesel::sql_types::{Integer, Text};
    /// #
    /// #     let connection = &mut establish_connection();
    /// #     diesel::insert_into(users::table)
    /// #         .values(users::name.eq("Jim"))
    /// #         .execute(connection).unwrap();
    /// # #[cfg(feature = "postgres")]
    /// # let users = sql_query("SELECT * FROM users WHERE id > $1 AND name != $2");
    /// # #[cfg(not(feature = "postgres"))]
    /// let users = sql_query("SELECT * FROM users WHERE id > ? AND name <> ?")
    /// # ;
    /// # let users = users
    ///     .bind::<Integer, _>(1)
    ///     .bind::<Text, _>("Tess")
    ///     .get_results(connection);
    /// let expected_users = vec![
    ///     User { id: 3, name: "Jim".into() },
    /// ];
    /// assert_eq!(Ok(expected_users), users);
    /// # }
    /// ```
    pub fn bind<ST, Value>(self, value: Value) -> UncheckedBind<Self, Value, ST> {
        UncheckedBind::new(self, value)
    }

    /// Internally boxes future calls on `bind` and `sql` so that they don't
    /// change the type.
    ///
    /// This allows doing things you otherwise couldn't do, e.g. `bind`ing in a
    /// loop.
    pub fn into_boxed<'f, DB: Backend>(self) -> BoxedSqlQuery<'f, DB, Self> {
        BoxedSqlQuery::new(self)
    }

    /// Appends a piece of SQL code at the end.
    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
        self.query += sql.as_ref();
        self
    }
}

impl SqlQuery {
    pub(crate) fn from_sql(query: String) -> SqlQuery {
        Self {
            inner: self::private::Empty,
            query,
        }
    }
}

impl<DB, Inner> QueryFragment<DB> for SqlQuery<Inner>
where
    DB: Backend + DieselReserveSpecialization,
    Inner: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        self.inner.walk_ast(out.reborrow())?;
        out.push_sql(&self.query);
        Ok(())
    }
}

impl<Inner> QueryId for SqlQuery<Inner> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<Inner> Query for SqlQuery<Inner> {
    type SqlType = Untyped;
}

impl<Inner, Conn> RunQueryDsl<Conn> for SqlQuery<Inner> {}

#[derive(Debug, Clone, Copy)]
#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
/// Returned by the [`SqlQuery::bind()`] method when binding a value to a fragment of SQL.
///
pub struct UncheckedBind<Query, Value, ST> {
    query: Query,
    value: Value,
    _marker: PhantomData<ST>,
}

impl<Query, Value, ST> UncheckedBind<Query, Value, ST> {
    pub fn new(query: Query, value: Value) -> Self {
        UncheckedBind {
            query,
            value,
            _marker: PhantomData,
        }
    }

    pub fn bind<ST2, Value2>(self, value: Value2) -> UncheckedBind<Self, Value2, ST2> {
        UncheckedBind::new(self, value)
    }

    pub fn into_boxed<'f, DB: Backend>(self) -> BoxedSqlQuery<'f, DB, Self> {
        BoxedSqlQuery::new(self)
    }

    /// Construct a full SQL query using raw SQL.
    ///
    /// This function exists for cases where a query needs to be written that is not
    /// supported by the query builder. Unlike most queries in Diesel, `sql_query`
    /// will deserialize its data by name, not by index. That means that you cannot
    /// deserialize into a tuple, and structs which you deserialize from this
    /// function will need to have `#[derive(QueryableByName)]`.
    ///
    /// This function is intended for use when you want to write the entire query
    /// using raw SQL. If you only need a small bit of raw SQL in your query, use
    /// [`sql`](dsl::sql()) instead.
    ///
    /// Query parameters can be bound into the raw query using [`SqlQuery::bind()`].
    ///
    /// # Safety
    ///
    /// The implementation of `QueryableByName` will assume that columns with a
    /// given name will have a certain type. The compiler will be unable to verify
    /// that the given type is correct. If your query returns a column of an
    /// unexpected type, the result may have the wrong value, or return an error.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # include!("../doctest_setup.rs");
    /// #
    /// # use schema::users;
    /// #
    /// # #[derive(QueryableByName, Debug, PartialEq)]
    /// # #[diesel(table_name = users)]
    /// # struct User {
    /// #     id: i32,
    /// #     name: String,
    /// # }
    /// #
    /// # fn main() {
    /// #     use diesel::sql_query;
    /// #     use diesel::sql_types::{Integer, Text};
    /// #
    /// #     let connection = &mut establish_connection();
    /// #     diesel::insert_into(users::table)
    /// #         .values(users::name.eq("Jim"))
    /// #         .execute(connection).unwrap();
    /// # #[cfg(feature = "postgres")]
    /// # let users = sql_query("SELECT * FROM users WHERE id > $1 AND name != $2");
    /// # #[cfg(not(feature = "postgres"))]
    /// let users = sql_query("SELECT * FROM users WHERE id > ? AND name <> ?")
    /// # ;
    /// # let users = users
    ///     .bind::<Integer, _>(1)
    ///     .bind::<Text, _>("Tess")
    ///     .get_results(connection);
    /// let expected_users = vec![
    ///     User { id: 3, name: "Jim".into() },
    /// ];
    /// assert_eq!(Ok(expected_users), users);
    /// # }
    /// ```
    /// [`SqlQuery::bind()`]: query_builder::SqlQuery::bind()
    pub fn sql<T: Into<String>>(self, sql: T) -> SqlQuery<Self> {
        SqlQuery::new(self, sql.into())
    }
}

impl<Query, Value, ST> QueryId for UncheckedBind<Query, Value, ST>
where
    Query: QueryId,
    ST: QueryId,
{
    type QueryId = UncheckedBind<Query::QueryId, (), ST::QueryId>;

    const HAS_STATIC_QUERY_ID: bool = Query::HAS_STATIC_QUERY_ID && ST::HAS_STATIC_QUERY_ID;
}

impl<Query, Value, ST, DB> QueryFragment<DB> for UncheckedBind<Query, Value, ST>
where
    DB: Backend + HasSqlType<ST> + DieselReserveSpecialization,
    Query: QueryFragment<DB>,
    Value: ToSql<ST, DB>,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        self.query.walk_ast(out.reborrow())?;
        out.push_bind_param_value_only(&self.value)?;
        Ok(())
    }
}

impl<Q, Value, ST> Query for UncheckedBind<Q, Value, ST> {
    type SqlType = Untyped;
}

impl<Conn, Query, Value, ST> RunQueryDsl<Conn> for UncheckedBind<Query, Value, ST> {}

#[must_use = "Queries are only executed when calling `load`, `get_result`, or similar."]
/// See [`SqlQuery::into_boxed`].
///
/// [`SqlQuery::into_boxed`]: SqlQuery::into_boxed()
#[allow(missing_debug_implementations)]
pub struct BoxedSqlQuery<'f, DB: Backend, Query> {
    query: Query,
    sql: String,
    binds: Vec<Box<dyn QueryFragment<DB> + 'f>>,
}

struct RawBind<ST, U> {
    value: U,
    p: PhantomData<ST>,
}

impl<ST, U, DB> QueryFragment<DB> for RawBind<ST, U>
where
    DB: Backend + HasSqlType<ST>,
    U: ToSql<ST, DB>,
{
    fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        pass.push_bind_param_value_only(&self.value)
    }
}

impl<'f, DB: Backend, Query> BoxedSqlQuery<'f, DB, Query> {
    pub(crate) fn new(query: Query) -> Self {
        BoxedSqlQuery {
            query,
            sql: "".to_string(),
            binds: vec![],
        }
    }

    /// See [`SqlQuery::bind`].
    ///
    /// [`SqlQuery::bind`]: SqlQuery::bind()
    pub fn bind<BindSt, Value>(mut self, b: Value) -> Self
    where
        DB: HasSqlType<BindSt>,
        Value: ToSql<BindSt, DB> + 'f,
        BindSt: 'f,
    {
        self.binds.push(Box::new(RawBind {
            value: b,
            p: PhantomData,
        }) as Box<_>);
        self
    }

    /// See [`SqlQuery::sql`].
    ///
    /// [`SqlQuery::sql`]: SqlQuery::sql()
    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
        self.sql += sql.as_ref();
        self
    }
}

impl<DB, Query> QueryFragment<DB> for BoxedSqlQuery<'_, DB, Query>
where
    DB: Backend + DieselReserveSpecialization,
    Query: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        self.query.walk_ast(out.reborrow())?;
        out.push_sql(&self.sql);

        for b in &self.binds {
            b.walk_ast(out.reborrow())?;
        }
        Ok(())
    }
}

impl<DB: Backend, Query> QueryId for BoxedSqlQuery<'_, DB, Query> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<DB, Q> Query for BoxedSqlQuery<'_, DB, Q>
where
    DB: Backend,
{
    type SqlType = Untyped;
}

impl<Conn: Connection, Query> RunQueryDsl<Conn> for BoxedSqlQuery<'_, Conn::Backend, Query> {}

mod private {
    use crate::backend::{Backend, DieselReserveSpecialization};
    use crate::query_builder::{QueryFragment, QueryId};

    #[derive(Debug, Clone, Copy, QueryId)]
    pub struct Empty;

    impl<DB> QueryFragment<DB> for Empty
    where
        DB: Backend + DieselReserveSpecialization,
    {
        fn walk_ast<'b>(
            &'b self,
            _pass: crate::query_builder::AstPass<'_, 'b, DB>,
        ) -> crate::QueryResult<()> {
            Ok(())
        }
    }
}
<commit_msg>Make `BoxedSqlQuery` Send to mirror the behaviour of our other boxed types<commit_after>use std::marker::PhantomData;

use super::Query;
use crate::backend::{Backend, DieselReserveSpecialization};
use crate::connection::Connection;
use crate::query_builder::{AstPass, QueryFragment, QueryId};
use crate::query_dsl::RunQueryDsl;
use crate::result::QueryResult;
use crate::serialize::ToSql;
use crate::sql_types::{HasSqlType, Untyped};

#[derive(Debug, Clone)]
#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
/// The return value of `sql_query`.
///
/// Unlike most queries in Diesel, `SqlQuery` loads its data by column name,
/// rather than by index. This means that you cannot deserialize this query into
/// a tuple, and any structs used must implement `QueryableByName`.
///
/// See [`sql_query`](crate::sql_query()) for examples.
pub struct SqlQuery<Inner = self::private::Empty> {
    inner: Inner,
    query: String,
}

impl<Inner> SqlQuery<Inner> {
    pub(crate) fn new(inner: Inner, query: String) -> Self {
        SqlQuery { inner, query }
    }

    /// Bind a value for use with this SQL query. The given query should have
    /// placeholders that vary based on the database type,
    /// like [SQLite Parameter](https://sqlite.org/lang_expr.html#varparam) syntax,
    /// [PostgreSQL PREPARE syntax](https://www.postgresql.org/docs/current/sql-prepare.html),
    /// or [MySQL bind syntax](https://dev.mysql.com/doc/refman/8.0/en/mysql-stmt-bind-param.html).
    ///
    /// # Safety
    ///
    /// This function should be used with care, as Diesel cannot validate that
    /// the value is of the right type nor can it validate that you have passed
    /// the correct number of parameters.
    ///
    /// # Example
    ///
    /// ```
    /// # include!("../doctest_setup.rs");
    /// #
    /// # use schema::users;
    /// #
    /// # #[derive(QueryableByName, Debug, PartialEq)]
    /// # #[diesel(table_name = users)]
    /// # struct User {
    /// #     id: i32,
    /// #     name: String,
    /// # }
    /// #
    /// # fn main() {
    /// #     use diesel::sql_query;
    /// #     use diesel::sql_types::{Integer, Text};
    /// #
    /// #     let connection = &mut establish_connection();
    /// #     diesel::insert_into(users::table)
    /// #         .values(users::name.eq("Jim"))
    /// #         .execute(connection).unwrap();
    /// # #[cfg(feature = "postgres")]
    /// # let users = sql_query("SELECT * FROM users WHERE id > $1 AND name != $2");
    /// # #[cfg(not(feature = "postgres"))]
    /// let users = sql_query("SELECT * FROM users WHERE id > ? AND name <> ?")
    /// # ;
    /// # let users = users
    ///     .bind::<Integer, _>(1)
    ///     .bind::<Text, _>("Tess")
    ///     .get_results(connection);
    /// let expected_users = vec![
    ///     User { id: 3, name: "Jim".into() },
    /// ];
    /// assert_eq!(Ok(expected_users), users);
    /// # }
    /// ```
    pub fn bind<ST, Value>(self, value: Value) -> UncheckedBind<Self, Value, ST> {
        UncheckedBind::new(self, value)
    }

    /// Internally boxes future calls on `bind` and `sql` so that they don't
    /// change the type.
    ///
    /// This allows doing things you otherwise couldn't do, e.g. `bind`ing in a
    /// loop.
    pub fn into_boxed<'f, DB: Backend>(self) -> BoxedSqlQuery<'f, DB, Self> {
        BoxedSqlQuery::new(self)
    }

    /// Appends a piece of SQL code at the end.
    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
        self.query += sql.as_ref();
        self
    }
}

impl SqlQuery {
    pub(crate) fn from_sql(query: String) -> SqlQuery {
        Self {
            inner: self::private::Empty,
            query,
        }
    }
}

impl<DB, Inner> QueryFragment<DB> for SqlQuery<Inner>
where
    DB: Backend + DieselReserveSpecialization,
    Inner: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        self.inner.walk_ast(out.reborrow())?;
        out.push_sql(&self.query);
        Ok(())
    }
}

impl<Inner> QueryId for SqlQuery<Inner> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<Inner> Query for SqlQuery<Inner> {
    type SqlType = Untyped;
}

impl<Inner, Conn> RunQueryDsl<Conn> for SqlQuery<Inner> {}

#[derive(Debug, Clone, Copy)]
#[must_use = "Queries are only executed when calling `load`, `get_result` or similar."]
/// Returned by the [`SqlQuery::bind()`] method when binding a value to a fragment of SQL.
///
pub struct UncheckedBind<Query, Value, ST> {
    query: Query,
    value: Value,
    _marker: PhantomData<ST>,
}

impl<Query, Value, ST> UncheckedBind<Query, Value, ST> {
    pub fn new(query: Query, value: Value) -> Self {
        UncheckedBind {
            query,
            value,
            _marker: PhantomData,
        }
    }

    pub fn bind<ST2, Value2>(self, value: Value2) -> UncheckedBind<Self, Value2, ST2> {
        UncheckedBind::new(self, value)
    }

    pub fn into_boxed<'f, DB: Backend>(self) -> BoxedSqlQuery<'f, DB, Self> {
        BoxedSqlQuery::new(self)
    }

    /// Construct a full SQL query using raw SQL.
    ///
    /// This function exists for cases where a query needs to be written that is not
    /// supported by the query builder. Unlike most queries in Diesel, `sql_query`
    /// will deserialize its data by name, not by index. That means that you cannot
    /// deserialize into a tuple, and structs which you deserialize from this
    /// function will need to have `#[derive(QueryableByName)]`.
    ///
    /// This function is intended for use when you want to write the entire query
    /// using raw SQL. If you only need a small bit of raw SQL in your query, use
    /// [`sql`](dsl::sql()) instead.
    ///
    /// Query parameters can be bound into the raw query using [`SqlQuery::bind()`].
    ///
    /// # Safety
    ///
    /// The implementation of `QueryableByName` will assume that columns with a
    /// given name will have a certain type. The compiler will be unable to verify
    /// that the given type is correct. If your query returns a column of an
    /// unexpected type, the result may have the wrong value, or return an error.
    ///
    /// # Examples
    ///
    /// ```rust
    /// # include!("../doctest_setup.rs");
    /// #
    /// # use schema::users;
    /// #
    /// # #[derive(QueryableByName, Debug, PartialEq)]
    /// # #[diesel(table_name = users)]
    /// # struct User {
    /// #     id: i32,
    /// #     name: String,
    /// # }
    /// #
    /// # fn main() {
    /// #     use diesel::sql_query;
    /// #     use diesel::sql_types::{Integer, Text};
    /// #
    /// #     let connection = &mut establish_connection();
    /// #     diesel::insert_into(users::table)
    /// #         .values(users::name.eq("Jim"))
    /// #         .execute(connection).unwrap();
    /// # #[cfg(feature = "postgres")]
    /// # let users = sql_query("SELECT * FROM users WHERE id > $1 AND name != $2");
    /// # #[cfg(not(feature = "postgres"))]
    /// let users = sql_query("SELECT * FROM users WHERE id > ? AND name <> ?")
    /// # ;
    /// # let users = users
    ///     .bind::<Integer, _>(1)
    ///     .bind::<Text, _>("Tess")
    ///     .get_results(connection);
    /// let expected_users = vec![
    ///     User { id: 3, name: "Jim".into() },
    /// ];
    /// assert_eq!(Ok(expected_users), users);
    /// # }
    /// ```
    /// [`SqlQuery::bind()`]: query_builder::SqlQuery::bind()
    pub fn sql<T: Into<String>>(self, sql: T) -> SqlQuery<Self> {
        SqlQuery::new(self, sql.into())
    }
}

impl<Query, Value, ST> QueryId for UncheckedBind<Query, Value, ST>
where
    Query: QueryId,
    ST: QueryId,
{
    type QueryId = UncheckedBind<Query::QueryId, (), ST::QueryId>;

    const HAS_STATIC_QUERY_ID: bool = Query::HAS_STATIC_QUERY_ID && ST::HAS_STATIC_QUERY_ID;
}

impl<Query, Value, ST, DB> QueryFragment<DB> for UncheckedBind<Query, Value, ST>
where
    DB: Backend + HasSqlType<ST> + DieselReserveSpecialization,
    Query: QueryFragment<DB>,
    Value: ToSql<ST, DB>,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        self.query.walk_ast(out.reborrow())?;
        out.push_bind_param_value_only(&self.value)?;
        Ok(())
    }
}

impl<Q, Value, ST> Query for UncheckedBind<Q, Value, ST> {
    type SqlType = Untyped;
}

impl<Conn, Query, Value, ST> RunQueryDsl<Conn> for UncheckedBind<Query, Value, ST> {}

#[must_use = "Queries are only executed when calling `load`, `get_result`, or similar."]
/// See [`SqlQuery::into_boxed`].
///
/// [`SqlQuery::into_boxed`]: SqlQuery::into_boxed()
#[allow(missing_debug_implementations)]
pub struct BoxedSqlQuery<'f, DB: Backend, Query> {
    query: Query,
    sql: String,
    binds: Vec<Box<dyn QueryFragment<DB> + Send + 'f>>,
}

struct RawBind<ST, U> {
    value: U,
    p: PhantomData<ST>,
}

impl<ST, U, DB> QueryFragment<DB> for RawBind<ST, U>
where
    DB: Backend + HasSqlType<ST>,
    U: ToSql<ST, DB>,
{
    fn walk_ast<'b>(&'b self, mut pass: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        pass.push_bind_param_value_only(&self.value)
    }
}

impl<'f, DB: Backend, Query> BoxedSqlQuery<'f, DB, Query> {
    pub(crate) fn new(query: Query) -> Self {
        BoxedSqlQuery {
            query,
            sql: "".to_string(),
            binds: vec![],
        }
    }

    /// See [`SqlQuery::bind`].
    ///
    /// [`SqlQuery::bind`]: SqlQuery::bind()
    pub fn bind<BindSt, Value>(mut self, b: Value) -> Self
    where
        DB: HasSqlType<BindSt>,
        Value: ToSql<BindSt, DB> + Send + 'f,
        BindSt: Send + 'f,
    {
        self.binds.push(Box::new(RawBind {
            value: b,
            p: PhantomData,
        }) as Box<_>);
        self
    }

    /// See [`SqlQuery::sql`].
    ///
    /// [`SqlQuery::sql`]: SqlQuery::sql()
    pub fn sql<T: AsRef<str>>(mut self, sql: T) -> Self {
        self.sql += sql.as_ref();
        self
    }
}

impl<DB, Query> QueryFragment<DB> for BoxedSqlQuery<'_, DB, Query>
where
    DB: Backend + DieselReserveSpecialization,
    Query: QueryFragment<DB>,
{
    fn walk_ast<'b>(&'b self, mut out: AstPass<'_, 'b, DB>) -> QueryResult<()> {
        out.unsafe_to_cache_prepared();
        self.query.walk_ast(out.reborrow())?;
        out.push_sql(&self.sql);

        for b in &self.binds {
            b.walk_ast(out.reborrow())?;
        }
        Ok(())
    }
}

impl<DB: Backend, Query> QueryId for BoxedSqlQuery<'_, DB, Query> {
    type QueryId = ();

    const HAS_STATIC_QUERY_ID: bool = false;
}

impl<DB, Q> Query for BoxedSqlQuery<'_, DB, Q>
where
    DB: Backend,
{
    type SqlType = Untyped;
}

impl<Conn: Connection, Query> RunQueryDsl<Conn> for BoxedSqlQuery<'_, Conn::Backend, Query> {}

mod private {
    use crate::backend::{Backend, DieselReserveSpecialization};
    use crate::query_builder::{QueryFragment, QueryId};

    #[derive(Debug, Clone, Copy, QueryId)]
    pub struct Empty;

    impl<DB> QueryFragment<DB> for Empty
    where
        DB: Backend + DieselReserveSpecialization,
    {
        fn walk_ast<'b>(
            &'b self,
            _pass: crate::query_builder::AstPass<'_, 'b, DB>,
        ) -> crate::QueryResult<()> {
            Ok(())
        }
    }
}

#[cfg(test)]
mod tests {
    fn assert_send<S: Send>(_: S) {}

    #[test]
    fn check_boxed_sql_query_is_send() {
        let query = crate::sql_query("…")
            .into_boxed::<<crate::test_helpers::TestConnection as crate::Connection>::Backend>(
        );

        assert_send(query);
    }
}
<|endoftext|>


<commit_before>use file;
use playpen;
use std::iter::repeat;
use regex::Regex;

pub struct Markdown<'a, 'b> {
    content: String,
    id: &'a str,
    prefix: &'b str,
}

impl<'a, 'b> Markdown<'a, 'b> {
    pub fn process(number: &[uint], id: &'a str, title: &str, prefix: &'b str)
        -> Result<(), String>
    {
        let mut mkd = try!(Markdown::new(number, id, title, prefix));

        try!(mkd.insert_sources());
        try!(mkd.insert_outputs());
        try!(mkd.insert_playpen_links());
        try!(mkd.save());

        Ok(())
    }

    fn new(number: &[uint], id: &'a str, title: &str, prefix: &'b str)
        -> Result<Markdown<'a, 'b>, String>
    {
        let path = Path::new(format!("examples/{}/{}/input.md", prefix, id));
        let body = try!(file::read(&path));
        let version = number.iter().map(|x| {
            format!("{}", x)
        }).collect::<Vec<String>>().connect(".");

        let len = number.len();
        let content = format!("{} {} {}\n\n{}",
                              repeat("#").take(len).collect::<String>(),
                              version,
                              title,
                              body);

        Ok(Markdown {
            content: content,
            id: id,
            prefix: prefix,
        })
    }

    fn insert_sources(&mut self) -> Result<(), String> {
        let id = self.id;
        let prefix = self.prefix;
        let re = Regex::new(r"\{(.*\.rs)\}").unwrap();

        let mut table = Vec::new();
        for line in self.content.as_slice().lines() {
            match re.captures(line) {
                None => {},
                Some(captures) => {
                    let src = captures.at(1).unwrap();
                    let input = format!("{{{}}}", src);
                    let p = format!("examples/{}/{}/{}", prefix, id, src);
                    let output = match file::read(&Path::new(p.as_slice())) {
                        Err(_) => {
                            return Err(format!("{} not found", p));
                        },
                        Ok(string) => {
                            format!("``` rust\n// {}\n{}```",
                                    src, string)
                        }
                    };

                    table.push((input, output))
                }
            }
        }

        for (input, output) in table.into_iter() {
            self.content = self.content.replace(input.as_slice(),
                                                output.as_slice());
        }

        Ok(())
    }

    fn insert_outputs(&mut self) -> Result<(), String> {
        let id = self.id;
        let prefix = self.prefix;
        let r = Regex::new(r"\{(.*)\.out\}").unwrap();

        let dir = Path::new(format!("bin/{}/{}", prefix, id));

        file::mkdir(&dir);

        let mut table = Vec::new();
        for line in self.content.as_slice().lines() {
            match r.captures(line) {
                None => {},
                Some(captures) => {
                    let src = captures.at(1);
                    let input = format!("{{{:?}.out}}", src);
                    let s = try!(file::run(prefix, id, src.unwrap()));
                    let s = format!("```\n$ rustc {0:?}.rs && ./{0:?}\n{1:?}```",
                                    src, s);

                    table.push((input, s));
                },
            }
        }

        for (input, output) in table.into_iter() {
            self.content = self.content.replace(input.as_slice(),
                                                output.as_slice());
        }

        Ok(())
    }

    fn insert_playpen_links(&mut self) -> Result<(), String> {
        let id = self.id;
        let prefix = self.prefix;
        let re = Regex::new(r"\{(.*)\.play\}").unwrap();

        let mut once_ = false;
        let mut table = Vec::new();
        for line in self.content.as_slice().lines() {
            match re.captures(line) {
                None => {},
                Some(captures) => {
                    if once_ {
                        return Err(format!("more than one editor!"))
                    } else {
                        once_ = true;
                    }

                    let srcbase = captures.at(1).unwrap();
                    let input = format!("{{{}.play}}", srcbase);
                    let src = format!("{}.rs", srcbase);
                    let p = format!("examples/{}/{}/{}", prefix, id, src);
                    let output = match file::read(&Path::new(p.as_slice())) {
                        Err(_) => {
                            return Err(format!("{} not found", p));
                        },
                        Ok(source) => {
                            playpen::editor(source.as_slice())
                        }
                    };

                    table.push((input, output))
                }
            }
        }

        for (input, output) in table.into_iter() {
            self.content = self.content.replace(input.as_slice(),
                                                output.as_slice());
        }

        Ok(())
    }

    fn save(&self) -> Result<(), String> {
        let path = Path::new(format!("stage/{}/{}.md", self.prefix, self.id));

        file::write(&path, self.content.as_slice())
    }
}
<commit_msg>Make all lines less than 80 characters<commit_after>use file;
use playpen;
use std::iter::repeat;
use regex::Regex;

pub struct Markdown<'a, 'b> {
    content: String,
    id: &'a str,
    prefix: &'b str,
}

impl<'a, 'b> Markdown<'a, 'b> {
    pub fn process(number: &[uint], id: &'a str, title: &str, prefix: &'b str)
        -> Result<(), String>
    {
        let mut mkd = try!(Markdown::new(number, id, title, prefix));

        try!(mkd.insert_sources());
        try!(mkd.insert_outputs());
        try!(mkd.insert_playpen_links());
        try!(mkd.save());

        Ok(())
    }

    fn new(number: &[uint], id: &'a str, title: &str, prefix: &'b str)
        -> Result<Markdown<'a, 'b>, String>
    {
        let path = Path::new(format!("examples/{}/{}/input.md", prefix, id));
        let body = try!(file::read(&path));
        let version = number.iter().map(|x| {
            format!("{}", x)
        }).collect::<Vec<String>>().connect(".");

        let len = number.len();
        let content = format!("{} {} {}\n\n{}",
                              repeat("#").take(len).collect::<String>(),
                              version,
                              title,
                              body);

        Ok(Markdown {
            content: content,
            id: id,
            prefix: prefix,
        })
    }

    fn insert_sources(&mut self) -> Result<(), String> {
        let id = self.id;
        let prefix = self.prefix;
        let re = Regex::new(r"\{(.*\.rs)\}").unwrap();

        let mut table = Vec::new();
        for line in self.content.as_slice().lines() {
            match re.captures(line) {
                None => {},
                Some(captures) => {
                    let src = captures.at(1).unwrap();
                    let input = format!("{{{}}}", src);
                    let p = format!("examples/{}/{}/{}", prefix, id, src);
                    let output = match file::read(&Path::new(p.as_slice())) {
                        Err(_) => {
                            return Err(format!("{} not found", p));
                        },
                        Ok(string) => {
                            format!("``` rust\n// {}\n{}```",
                                    src, string)
                        }
                    };

                    table.push((input, output))
                }
            }
        }

        for (input, output) in table.into_iter() {
            self.content = self.content.replace(input.as_slice(),
                                                output.as_slice());
        }

        Ok(())
    }

    fn insert_outputs(&mut self) -> Result<(), String> {
        let id = self.id;
        let prefix = self.prefix;
        let r = Regex::new(r"\{(.*)\.out\}").unwrap();

        let dir = Path::new(format!("bin/{}/{}", prefix, id));

        file::mkdir(&dir);

        let mut table = Vec::new();
        for line in self.content.as_slice().lines() {
            match r.captures(line) {
                None => {},
                Some(captures) => {
                    let src = captures.at(1);
                    let input = format!("{{{:?}.out}}", src);
                    let s = try!(file::run(prefix, id, src.unwrap()));
                    let s = format!("``` \n\
                                    $ rustc {0:?}.rs && ./{0:?}\n{1:?}\n\
                                    ```",
                                    src, s);

                    table.push((input, s));
                },
            }
        }

        for (input, output) in table.into_iter() {
            self.content = self.content.replace(input.as_slice(),
                                                output.as_slice());
        }

        Ok(())
    }

    fn insert_playpen_links(&mut self) -> Result<(), String> {
        let id = self.id;
        let prefix = self.prefix;
        let re = Regex::new(r"\{(.*)\.play\}").unwrap();

        let mut once_ = false;
        let mut table = Vec::new();
        for line in self.content.as_slice().lines() {
            match re.captures(line) {
                None => {},
                Some(captures) => {
                    if once_ {
                        return Err(format!("more than one editor!"))
                    } else {
                        once_ = true;
                    }

                    let srcbase = captures.at(1).unwrap();
                    let input = format!("{{{}.play}}", srcbase);
                    let src = format!("{}.rs", srcbase);
                    let p = format!("examples/{}/{}/{}", prefix, id, src);
                    let output = match file::read(&Path::new(p.as_slice())) {
                        Err(_) => {
                            return Err(format!("{} not found", p));
                        },
                        Ok(source) => {
                            playpen::editor(source.as_slice())
                        }
                    };

                    table.push((input, output))
                }
            }
        }

        for (input, output) in table.into_iter() {
            self.content = self.content.replace(input.as_slice(),
                                                output.as_slice());
        }

        Ok(())
    }

    fn save(&self) -> Result<(), String> {
        let path = Path::new(format!("stage/{}/{}.md", self.prefix, self.id));

        file::write(&path, self.content.as_slice())
    }
}
<|endoftext|>


<commit_before>extern crate ructe;
extern crate core;
use self::ructe::templates::ToHtml;
use self::core::fmt::Display;
use std::io::{Write,Error};
use std::mem::transmute;

use std::collections::HashMap as Dict;
fn parse_linkmark(text:&[u8])->(&[u8], Vec<u8>){

    let mut contents:Option<(usize, usize)> = None;
    let mut link :(Option<usize>, Option<usize>) = (None, None);
    for (i,ch) in text.iter().enumerate(){
        if let None = contents{
            if *ch == b']'{
                contents = Some((1,i));
            }
        }
        else{
            if *ch == b'('{
                link.0 = Some(i + 1);
            }
            if let Some( _ ) = link.0{
                if *ch == b')'{
                    link.1 = Some(i);
                    break;
                }
            }
        }
    }
    let r = match (link.0, link.1, contents){
        (Some(l1), Some(l2), Some(c))=>(l1,l2,c.0, c.1),
        _=>{
            return (&text[1..],vec![b'[']);
        }
    };
    let mut link = Vec::<u8>::new();
    let mut contents = Vec::<u8>::new();
    for ch in &text[r.0..r.1]{
        if *ch == b'"'{
            link.extend(b"%22");
        }
        else{
            link.push(*ch);
        }
    }
    for ch in &text[r.2 .. r.3]{
        match *ch{
            b'<'=>{
                contents.extend(b"<");
            },
            b'>'=>{
                contents.extend(b">");
            }
            _=>{
                contents.push(*ch);
            }
        }
    }
    let mut msg = Vec::<u8>::new();
    msg.extend(b"");
    msg.append(&mut contents);
    msg.extend(b"");
    return (&text[(r.1)+1..], msg);
}
fn parse_nomark(text:&[u8])->(&[u8], Vec<u8>){
    let mut res = Vec::<u8>::new();
    let mut t = &text[2..];

    while t.len() >= 2{
        if &t[..2] == b"}}"{
            return (&t[2..], res); //(&t[2..], format!("{}",link, res));
        }
        let s = match &t[0..1]{
            b"<"=>b"<",
            b">"=>b">",
            c@_=>c
        } ;
        res.extend(s);
        t = &t[1..];
    }

    return (&text[1..],vec![b'{']);
}
fn parse_strikethrough<'a>(text:&'a [u8], tag:&'a [u8])->(&'a[u8], Vec<u8>){
    let mut res = Vec::<u8>::new();
    let mut t = &text[2..];

    while t.len() > 0{
        if t.len() >= 2{
            if &t[..2] == tag{
                let mut msg = Vec::<u8>::new();
                msg.extend(b"");
                msg.append(&mut res);
                msg.extend(b"");
                return (&t[2..], msg); //(&t[2..], format!("{}",link, res));
            }
            if &t[..2] == b"__"{
                let mut r = parse_bold(t, &t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"**"{
                let mut r = parse_bold(t, &t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
        }
        if &t[..1] == b"["{
            let mut r = parse_linkmark(t);
            res.append(&mut r.1);
            t = r.0;
            continue;
        }

        res.push(t[0]);
        t = &t[1..];
    }

    return (&text[1..],Vec::from(&tag[..1]));
}
fn parse_bold<'a>(text:&'a [u8], tag:&'a [u8])->(&'a[u8], Vec<u8>){
    let mut res = Vec::<u8>::new();
    let mut t = &text[2..];

    while t.len() > 0{
        if t.len() >= 2{
            if &t[..2] == tag{
                let mut msg = Vec::<u8>::new();
                msg.extend(b"");
                msg.append(&mut res);
                msg.extend(b"");
                return (&t[2..], msg); //(&t[2..], format!("{}",link, res));
            }
            if &t[..2] == b"~~"{
                let mut r = parse_strikethrough(t,&t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"--"{
                let mut r = parse_strikethrough(t, &t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
        }
        if &t[..1] == b"["{
            let mut r = parse_linkmark(t);
            res.append(&mut r.1);
            t = r.0;
            continue;
        }

        res.push(t[0]);
        t = &t[1..];
    }

    return (&text[1..],Vec::from(&tag[..1]));
}
fn parse(text:&str)->Vec<u8>{
    let mut res = Vec::<u8>::new();
    let mut t:&[u8] = text.as_bytes();
    res.extend(b"
");
    while t.len() != 0{
        if t.len() > 2{
            if &t[..2] == b"\n\n"{
                res.extend(b"

");
                t = &t[2..];
                continue;
            }
            if &t[..2] == b"  "{
                res.extend(b"
");
                t = &t[2..];
                continue;
            }
            if &t[..2] == b"~~"{
                let mut r = parse_strikethrough(t, &t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"--"{
                let mut r = parse_strikethrough(t, &t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"{{"{
                let mut r = parse_nomark(t);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"__"{
                let mut r = parse_bold(t,&t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"**"{
                let mut r = parse_bold(t,&t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
        }
        if &t[..1] == b"["{
            let mut r = parse_linkmark(t);
            res.append(&mut r.1);
            t = r.0;
            continue;
        }

        let s = match &t[0..1]{
            b"<"=>b"<",
            b">"=>b">",
            c@_=>c
        } ;
        res.extend(s);
        t = &t[1..];
    }
    res.extend(b"
");
    return res;
    //return String::from_utf8(res).unwrap();
}

pub struct Markdown{
    obj:*const str
}
impl Markdown{
    pub fn to_html(&self, out: &mut Write) -> Result<(),Error>{
        let text:&str =
        unsafe{transmute::<_, &str>(self.obj)};
        out.write_all(&parse(text));
        Ok(())
    }
}
pub fn render(obj:&str)->Markdown{
    Markdown{obj:obj}
}<commit_msg>인용문 코드 추가<commit_after>extern crate ructe;
extern crate core;
use self::ructe::templates::ToHtml;
use self::core::fmt::Display;
use std::io::{Write,Error};
use std::mem::transmute;

use std::collections::HashMap as Dict;
fn parse_linkmark(text:&[u8])->(&[u8], Vec<u8>){

    let mut contents:Option<(usize, usize)> = None;
    let mut link :(Option<usize>, Option<usize>) = (None, None);
    for (i,ch) in text.iter().enumerate(){
        if let None = contents{
            if *ch == b']'{
                contents = Some((1,i));
            }
        }
        else{
            if *ch == b'('{
                link.0 = Some(i + 1);
            }
            if let Some( _ ) = link.0{
                if *ch == b')'{
                    link.1 = Some(i);
                    break;
                }
            }
        }
    }
    let r = match (link.0, link.1, contents){
        (Some(l1), Some(l2), Some(c))=>(l1,l2,c.0, c.1),
        _=>{
            return (&text[1..],vec![b'[']);
        }
    };
    let mut link = Vec::<u8>::new();
    let mut contents = Vec::<u8>::new();
    for ch in &text[r.0..r.1]{
        if *ch == b'"'{
            link.extend(b"%22");
        }
        else{
            link.push(*ch);
        }
    }
    for ch in &text[r.2 .. r.3]{
        match *ch{
            b'<'=>{
                contents.extend(b"<");
            },
            b'>'=>{
                contents.extend(b">");
            }
            _=>{
                contents.push(*ch);
            }
        }
    }
    let mut msg = Vec::<u8>::new();
    msg.extend(b"");
    msg.append(&mut contents);
    msg.extend(b"");
    return (&text[(r.1)+1..], msg);
}
fn parse_nomark(text:&[u8])->(&[u8], Vec<u8>){
    let mut res = Vec::<u8>::new();
    let mut t = &text[2..];

    while t.len() >= 2{
        if &t[..2] == b"}}"{
            return (&t[2..], res); //(&t[2..], format!("{}",link, res));
        }
        let s = match &t[0..1]{
            b"<"=>b"<",
            b">"=>b">",
            c@_=>c
        } ;
        res.extend(s);
        t = &t[1..];
    }

    return (&text[1..],vec![b'{']);
}
fn parse_strikethrough<'a>(text:&'a [u8], tag:&'a [u8])->(&'a[u8], Vec<u8>){
    let mut res = Vec::<u8>::new();
    let mut t = &text[2..];

    while t.len() > 0{
        if t.len() >= 2{
            if &t[..2] == tag{
                let mut msg = Vec::<u8>::new();
                msg.extend(b"");
                msg.append(&mut res);
                msg.extend(b"");
                return (&t[2..], msg); //(&t[2..], format!("{}",link, res));
            }
            if &t[..2] == b"__"{
                let mut r = parse_bold(t, &t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"**"{
                let mut r = parse_bold(t, &t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
        }
        if &t[..1] == b"["{
            let mut r = parse_linkmark(t);
            res.append(&mut r.1);
            t = r.0;
            continue;
        }

        res.push(t[0]);
        t = &t[1..];
    }

    return (&text[1..],Vec::from(&tag[..1]));
}
fn parse_bold<'a>(text:&'a [u8], tag:&'a [u8])->(&'a[u8], Vec<u8>){
    let mut res = Vec::<u8>::new();
    let mut t = &text[2..];

    while t.len() > 0{
        if t.len() >= 2{
            if &t[..2] == tag{
                let mut msg = Vec::<u8>::new();
                msg.extend(b"");
                msg.append(&mut res);
                msg.extend(b"");
                return (&t[2..], msg); //(&t[2..], format!("{}",link, res));
            }
            if &t[..2] == b"~~"{
                let mut r = parse_strikethrough(t,&t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"--"{
                let mut r = parse_strikethrough(t, &t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
        }
        if &t[..1] == b"["{
            let mut r = parse_linkmark(t);
            res.append(&mut r.1);
            t = r.0;
            continue;
        }

        res.push(t[0]);
        t = &t[1..];
    }

    return (&text[1..],Vec::from(&tag[..1]));
}
fn parse_blackqoute(text:&[u8])->(&[u8], Vec<u8>){
    let mut t = text;
    let mut html = Vec::<u8>::new();
    return (t, html);
}
fn parse(text:&str)->Vec<u8>{
    let mut res = Vec::<u8>::new();
    let mut t:&[u8] = text.as_bytes();
    res.extend(b"
");
    while t.len() != 0{
        if t.len() > 2{
            if (t.len() == text.as_bytes().len() && &t[..1] == b">") ||
            &t[..2] == b"\n>"{

            }
            if &t[..2] == b"\n\n"{
                res.extend(b"

");
                t = &t[2..];
                continue;
            }
            if &t[..2] == b"  "{
                res.extend(b"
");
                t = &t[2..];
                continue;
            }
            if &t[..2] == b"~~"{
                let mut r = parse_strikethrough(t, &t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"--"{
                let mut r = parse_strikethrough(t, &t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"{{"{
                let mut r = parse_nomark(t);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"__"{
                let mut r = parse_bold(t,&t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
            if &t[..2] == b"**"{
                let mut r = parse_bold(t,&t[..2]);
                res.append(&mut r.1);
                t = r.0;
                continue;
            }
        }
        if &t[..1] == b"["{
            let mut r = parse_linkmark(t);
            res.append(&mut r.1);
            t = r.0;
            continue;
        }

        let s = match &t[0..1]{
            b"<"=>b"<",
            b">"=>b">",
            c@_=>c
        } ;
        res.extend(s);
        t = &t[1..];
    }
    res.extend(b"
");
    return res;
    //return String::from_utf8(res).unwrap();
}

pub struct Markdown{
    obj:*const str
}
impl Markdown{
    pub fn to_html(&self, out: &mut Write) -> Result<(),Error>{
        let text:&str =
        unsafe{transmute::<_, &str>(self.obj)};
        out.write_all(&parse(text));
        Ok(())
    }
}
pub fn render(obj:&str)->Markdown{
    Markdown{obj:obj}
}<|endoftext|>