<commit_before>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

extern crate ordered_float;
use self::ordered_float::OrderedFloat;

/// Core types defining a Mentat knowledge base.

/// Represents one entid in the entid space.
///
/// Per https://www.sqlite.org/datatype3.html (see also http://stackoverflow.com/a/8499544), SQLite
/// stores signed integers up to 64 bits in size.  Since u32 is not appropriate for our use case, we
/// use i64 rather than manually truncating u64 to u63 and casting to i64 throughout the codebase.
pub type Entid = i64;

/// The attribute of each Mentat assertion has a :db/valueType constraining the value to a
/// particular set.  Mentat recognizes the following :db/valueType values.
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub enum ValueType {
    Ref,
    Boolean,
    Instant,
    Long,
    Double,
    String,
    Keyword,
}

/// Represents a Mentat value in a particular value set.
// TODO: expand to include :db.type/{instant,url,uuid}.
// TODO: BigInt?
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub enum TypedValue {
    Ref(Entid),
    Boolean(bool),
    Long(i64),
    Double(OrderedFloat<f64>),
    // TODO: &str throughout?
    String(String),
    Keyword(String),
}

impl TypedValue {
    pub fn value_type(&self) -> ValueType {
        match self {
            &TypedValue::Ref(_) => ValueType::Ref,
            &TypedValue::Boolean(_) => ValueType::Boolean,
            &TypedValue::Long(_) => ValueType::Long,
            &TypedValue::Double(_) => ValueType::Double,
            &TypedValue::String(_) => ValueType::String,
            &TypedValue::Keyword(_) => ValueType::Keyword,
        }
    }
}

/// A Mentat schema attribute has a value type and several other flags determining how assertions
/// with the attribute are interpreted.
///
/// TODO: consider packing this into a bitfield or similar.
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct Attribute {
    /// The associated value type, i.e., `:db/valueType`?
    pub value_type: ValueType,

    /// `true` if this attribute is multi-valued, i.e., it is `:db/cardinality
    /// :db.cardinality/many`.  `false` if this attribute is single-valued (the default), i.e., it
    /// is `:db/cardinality :db.cardinality/one`.
    pub multival: bool,

    /// `true` if this attribute is unique-value, i.e., it is `:db/unique :db.unique/value`.
    ///
    /// *Unique-value* means that there is at most one assertion with the attribute and a
    /// particular value in the datom store.
    pub unique_value: bool,

    /// `true` if this attribute is unique-identity, i.e., it is `:db/unique :db.unique/identity`.
    ///
    /// Unique-identity attributes always have value type `Ref`.
    ///
    /// *Unique-identity* means that the attribute is *unique-value* and that they can be used in
    /// lookup-refs and will automatically upsert where appropriate.
    pub unique_identity: bool,

    /// `true` if this attribute is automatically indexed, i.e., it is `:db/indexing true`.
    pub index: bool,

    /// `true` if this attribute is automatically fulltext indexed, i.e., it is `:db/fulltext true`.
    ///
    /// Fulltext attributes always have string values.
    pub fulltext: bool,

    /// `true` if this attribute is a component, i.e., it is `:db/isComponent true`.
    ///
    /// Component attributes always have value type `Ref`.
    ///
    /// They are used to compose entities from component sub-entities: they are fetched recursively
    /// by pull expressions, and they are automatically recursively deleted where appropriate.
    pub component: bool,
}

impl Default for Attribute {
    fn default() -> Attribute {
        Attribute {
            // There's no particular reason to favour one value type, so Ref it is.
            value_type: ValueType::Ref,
            fulltext: false,
            index: false,
            multival: false,
            unique_value: false,
            unique_identity: false,
            component: false,
        }
    }
}

<commit_msg>ValueType is Copy. r=jsantell<commit_after>// Copyright 2016 Mozilla
//
// Licensed under the Apache License, Version 2.0 (the "License"); you may not use
// this file except in compliance with the License. You may obtain a copy of the
// License at http://www.apache.org/licenses/LICENSE-2.0
// Unless required by applicable law or agreed to in writing, software distributed
// under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
// CONDITIONS OF ANY KIND, either express or implied. See the License for the
// specific language governing permissions and limitations under the License.

extern crate ordered_float;
use self::ordered_float::OrderedFloat;

/// Core types defining a Mentat knowledge base.

/// Represents one entid in the entid space.
///
/// Per https://www.sqlite.org/datatype3.html (see also http://stackoverflow.com/a/8499544), SQLite
/// stores signed integers up to 64 bits in size.  Since u32 is not appropriate for our use case, we
/// use i64 rather than manually truncating u64 to u63 and casting to i64 throughout the codebase.
pub type Entid = i64;

/// The attribute of each Mentat assertion has a :db/valueType constraining the value to a
/// particular set.  Mentat recognizes the following :db/valueType values.
#[derive(Clone,Copy,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub enum ValueType {
    Ref,
    Boolean,
    Instant,
    Long,
    Double,
    String,
    Keyword,
}

/// Represents a Mentat value in a particular value set.
// TODO: expand to include :db.type/{instant,url,uuid}.
// TODO: BigInt?
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub enum TypedValue {
    Ref(Entid),
    Boolean(bool),
    Long(i64),
    Double(OrderedFloat<f64>),
    // TODO: &str throughout?
    String(String),
    Keyword(String),
}

impl TypedValue {
    pub fn value_type(&self) -> ValueType {
        match self {
            &TypedValue::Ref(_) => ValueType::Ref,
            &TypedValue::Boolean(_) => ValueType::Boolean,
            &TypedValue::Long(_) => ValueType::Long,
            &TypedValue::Double(_) => ValueType::Double,
            &TypedValue::String(_) => ValueType::String,
            &TypedValue::Keyword(_) => ValueType::Keyword,
        }
    }
}

/// A Mentat schema attribute has a value type and several other flags determining how assertions
/// with the attribute are interpreted.
///
/// TODO: consider packing this into a bitfield or similar.
#[derive(Clone,Debug,Eq,Hash,Ord,PartialOrd,PartialEq)]
pub struct Attribute {
    /// The associated value type, i.e., `:db/valueType`?
    pub value_type: ValueType,

    /// `true` if this attribute is multi-valued, i.e., it is `:db/cardinality
    /// :db.cardinality/many`.  `false` if this attribute is single-valued (the default), i.e., it
    /// is `:db/cardinality :db.cardinality/one`.
    pub multival: bool,

    /// `true` if this attribute is unique-value, i.e., it is `:db/unique :db.unique/value`.
    ///
    /// *Unique-value* means that there is at most one assertion with the attribute and a
    /// particular value in the datom store.
    pub unique_value: bool,

    /// `true` if this attribute is unique-identity, i.e., it is `:db/unique :db.unique/identity`.
    ///
    /// Unique-identity attributes always have value type `Ref`.
    ///
    /// *Unique-identity* means that the attribute is *unique-value* and that they can be used in
    /// lookup-refs and will automatically upsert where appropriate.
    pub unique_identity: bool,

    /// `true` if this attribute is automatically indexed, i.e., it is `:db/indexing true`.
    pub index: bool,

    /// `true` if this attribute is automatically fulltext indexed, i.e., it is `:db/fulltext true`.
    ///
    /// Fulltext attributes always have string values.
    pub fulltext: bool,

    /// `true` if this attribute is a component, i.e., it is `:db/isComponent true`.
    ///
    /// Component attributes always have value type `Ref`.
    ///
    /// They are used to compose entities from component sub-entities: they are fetched recursively
    /// by pull expressions, and they are automatically recursively deleted where appropriate.
    pub component: bool,
}

impl Default for Attribute {
    fn default() -> Attribute {
        Attribute {
            // There's no particular reason to favour one value type, so Ref it is.
            value_type: ValueType::Ref,
            fulltext: false,
            index: false,
            multival: false,
            unique_value: false,
            unique_identity: false,
            component: false,
        }
    }
}

<|endoftext|>


<commit_before>extern crate websocket;
extern crate futures;
extern crate futures_cpupool;
extern crate tokio_core;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

use websocket::message::OwnedMessage;
use websocket::server::InvalidConnection;
use websocket::async::Server;

use tokio_core::reactor::{Handle, Core};

use futures::{Future, Sink, Stream};
use futures::future::{self, Loop};
use futures_cpupool::CpuPool;

use std::sync::{RwLock, Arc, Mutex};
use std::thread;
use std::rc::Rc;
use std::fmt::Debug;
use std::time::Duration;
use std::ops::Deref;

fn main() {
    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let remote = core.remote();
    let server = Server::bind("localhost:8081", &handle).unwrap();
    let pool = Rc::new(CpuPool::new_num_cpus());
    let connections = Arc::new(RwLock::new(Vec::new()));
    let state = Arc::new(RwLock::new(State::new()));
    let (read_channel_out, read_channel_in) = futures::sync::mpsc::unbounded();
    let handle_inner = handle.clone();
    let connections_inner = connections.clone();
    let connection_handler = server.incoming()
        // we don't wanna save the stream if it drops
        .map_err(|InvalidConnection { error, .. }| error)
        .for_each(move |(upgrade, addr)| {
            let connections = connections_inner.clone();
            println!("Got a connection from: {}", addr);
            if !upgrade.protocols().iter().any(|s| s == "rust-websocket") {
                spawn_future(upgrade.reject(), "Upgrade Rejection", &handle_inner);
                return Ok(());
            }
            let read_channel_out = read_channel_out.clone();
            upgrade
                .use_protocol("rust-websocket")
                .accept()
                .and_then(move |(framed, _)| {
                    let (sink, stream) = framed.split();
                    read_channel_out.send(stream).wait().unwrap();
                    connections.write().unwrap().push(Arc::new(RwLock::new(sink)));
                    Ok(())
                })
                .wait()
                .unwrap();
            Ok(())
        })
        .map_err(|_| ());

    let state_read = state.clone();
    let remote_write = remote.clone();
    let read_handler = pool.spawn_fn(|| {
        read_channel_in.for_each(move |stream| {
            let state_read = state_read.clone();
            remote_write.spawn(|_| {
                stream.for_each(move |msg| {
                                    handle_incoming(&mut state_read.write().unwrap(), &msg);
                                    Ok(())
                                })
                    .map_err(|_| ())
            });
            Ok(())
        })
    });

    let connections_inner = connections.clone();
    let (write_channel_out, write_channel_in) = futures::sync::mpsc::unbounded();

    type MessageCodec = websocket::async::MessageCodec<OwnedMessage>;
    type Framed = websocket::client::async::Framed<tokio_core::net::TcpStream, MessageCodec>;
    type SplitSink = futures::stream::SplitSink<Framed>;
    let write_handler = pool.spawn_fn(move || {
        write_channel_in.for_each(move |(sink, state): (Arc<RwLock<SplitSink>>,
                                                        Arc<RwLock<State>>)| {
                let msg = serde_json::to_string(state.read().unwrap().deref()).unwrap();
                println!("Sending message: {}", msg);
                sink.write()
                    .unwrap()
                    .start_send(OwnedMessage::Text(msg))
                    .unwrap();
                sink.write()
                    .unwrap()
                    .poll_complete()
                    .unwrap();
                Ok(())
            })
            .map_err(|_| ())
    });

    let game_loop = pool.spawn_fn(move || {
        future::loop_fn(write_channel_out, move |write_channel_out| {
            thread::sleep(Duration::from_millis(100));
            if !connections.read().unwrap().is_empty() {
                write_channel_out.clone()
                    .send((connections.write().unwrap()[0].clone(), state.clone()))
                    .wait()
                    .unwrap();
            }
            match 1 {
                1 => Ok(Loop::Continue(write_channel_out)),
                2 => Ok(Loop::Break(())),
                _ => Err(()),
            }
        })
    });

    let handlers =
        game_loop.select2(connection_handler.select2(read_handler.select(write_handler)));
    core.run(handlers).map_err(|_| println!("err")).unwrap();
}

fn spawn_future<F, I, E>(f: F, desc: &'static str, handle: &Handle)
    where F: Future<Item = I, Error = E> + 'static,
          E: Debug
{
    handle.spawn(f.map_err(move |e| println!("Error in {}: '{:?}'", desc, e))
                     .map(move |_| println!("{}: Finished.", desc)));
}

fn handle_incoming(state: &mut State, msg: &OwnedMessage) {
    match msg {
        &OwnedMessage::Text(ref txt) => {
            println!("Received message: {}", txt);
            //state.msg = txt.clone();
        }
        _ => {}
    }
}

#[derive(Serialize, Deserialize)]
struct State {
    positions: Vec<Pos>,
}

impl State {
    fn new() -> Self {
        Self { positions: Vec::new() }
    }
}

#[derive(Serialize, Deserialize)]
struct Pos {
    x: i32,
    y: i32,
}

impl Pos {
    fn new(x: i32, y: i32) -> Self {
        Self { x, y }
    }

    fn add_x(&mut self, x: i32) -> &mut Self {
        self.x += x;
        self
    }

    fn add_y(&mut self, y: i32) -> &mut Self {
        self.y += y;
        self
    }

    fn add(&mut self, x: i32, y: i32) -> &mut Self {
        self.x += x;
        self.y += y;
        self
    }
}
<commit_msg>Gardening<commit_after>extern crate websocket;
extern crate futures;
extern crate futures_cpupool;
extern crate tokio_core;
extern crate serde;
extern crate serde_json;
#[macro_use]
extern crate serde_derive;

use websocket::message::OwnedMessage;
use websocket::server::InvalidConnection;
use websocket::async::Server;

use tokio_core::reactor::{Handle, Core};

use futures::{Future, Sink, Stream};
use futures::future::{self, Loop};
use futures_cpupool::CpuPool;

use std::sync::{RwLock, Arc, Mutex};
use std::thread;
use std::rc::Rc;
use std::fmt::Debug;
use std::time::Duration;
use std::ops::Deref;

fn main() {
    let mut core = Core::new().unwrap();
    let handle = core.handle();
    let remote = core.remote();
    let server = Server::bind("localhost:8081", &handle).unwrap();
    let pool = Rc::new(CpuPool::new_num_cpus());
    let connections = Arc::new(RwLock::new(Vec::new()));
    let state = Arc::new(RwLock::new(State::new()));
    let (read_channel_out, read_channel_in) = futures::sync::mpsc::unbounded();
    let handle_inner = handle.clone();
    let connections_inner = connections.clone();
    let connection_handler = server.incoming()
        // we don't wanna save the stream if it drops
        .map_err(|InvalidConnection { error, .. }| error)
        .for_each(move |(upgrade, addr)| {
            let connections = connections_inner.clone();
            println!("Got a connection from: {}", addr);
            if !upgrade.protocols().iter().any(|s| s == "rust-websocket") {
                spawn_future(upgrade.reject(), "Upgrade Rejection", &handle_inner);
                return Ok(());
            }
            let read_channel_out = read_channel_out.clone();
            upgrade
                .use_protocol("rust-websocket")
                .accept()
                .and_then(move |(framed, _)| {
                    let (sink, stream) = framed.split();
                    read_channel_out.send(stream).wait().unwrap();
                    connections.write().unwrap().push(Arc::new(RwLock::new(sink)));
                    Ok(())
                })
                .wait()
                .unwrap();
            Ok(())
        })
        .map_err(|_| ());

    let state_read = state.clone();
    let remote_write = remote.clone();
    let read_handler = pool.spawn_fn(|| {
        read_channel_in.for_each(move |stream| {
            let state_read = state_read.clone();
            remote_write.spawn(|_| {
                stream.for_each(move |msg| {
                                    handle_incoming(&mut state_read.write().unwrap(), &msg);
                                    Ok(())
                                })
                    .map_err(|_| ())
            });
            Ok(())
        })
    });

    let connections_inner = connections.clone();
    let (write_channel_out, write_channel_in) = futures::sync::mpsc::unbounded();

    type MessageCodec = websocket::async::MessageCodec<OwnedMessage>;
    type Framed = websocket::client::async::Framed<tokio_core::net::TcpStream, MessageCodec>;
    type SplitSink = futures::stream::SplitSink<Framed>;
    let write_handler = pool.spawn_fn(move || {
        write_channel_in.for_each(move |(sink, state): (Arc<RwLock<SplitSink>>,
                                                        Arc<RwLock<State>>)| {
                let msg = serde_json::to_string(state.read().unwrap().deref()).unwrap();
                println!("Sending message: {}", msg);
                sink.write()
                    .unwrap()
                    .start_send(OwnedMessage::Text(msg))
                    .unwrap();
                sink.write()
                    .unwrap()
                    .poll_complete()
                    .unwrap();
                Ok(())
            })
            .map_err(|_| ())
    });

    let game_loop = pool.spawn_fn(move || {
        future::loop_fn(write_channel_out, move |write_channel_out| {
            thread::sleep(Duration::from_millis(100));
            if !connections.read().unwrap().is_empty() {
                write_channel_out
                    .clone()
                    .send((connections.write().unwrap()[0].clone(), state.clone()))
                    .wait()
                    .unwrap();
            }
            match 1 {
                1 => Ok(Loop::Continue(write_channel_out)),
                2 => Ok(Loop::Break(())),
                _ => Err(()),
            }
        })
    });

    let handlers = game_loop
        .select2(connection_handler
        .select2(read_handler
        .select(write_handler)));
    core
        .run(handlers)
        .map_err(|_| println!("err"))
        .unwrap();
}

fn spawn_future<F, I, E>(f: F, desc: &'static str, handle: &Handle)
    where F: Future<Item = I, Error = E> + 'static,
          E: Debug
{
    handle.spawn(f.map_err(move |e| println!("Error in {}: '{:?}'", desc, e))
                     .map(move |_| println!("{}: Finished.", desc)));
}

fn handle_incoming(state: &mut State, msg: &OwnedMessage) {
    match msg {
        &OwnedMessage::Text(ref txt) => {
            println!("Received message: {}", txt);
            //state.msg = txt.clone();
        }
        _ => {}
    }
}

#[derive(Serialize, Deserialize)]
struct State {
    positions: Vec<Pos>,
}

impl State {
    fn new() -> Self {
        Self { positions: Vec::new() }
    }
}

#[derive(Serialize, Deserialize)]
struct Pos {
    x: i32,
    y: i32,
}

impl Pos {
    fn new(x: i32, y: i32) -> Self {
        Self { x, y }
    }

    fn add_x(&mut self, x: i32) -> &mut Self {
        self.x += x;
        self
    }

    fn add_y(&mut self, y: i32) -> &mut Self {
        self.y += y;
        self
    }

    fn add(&mut self, x: i32, y: i32) -> &mut Self {
        self.x += x;
        self.y += y;
        self
    }
}
<|endoftext|>


<commit_before>use super::{Document,Root,RootChild,Element};

struct Parser;

impl Parser {
    fn new() -> Parser {
        Parser
    }

    fn parse_preamble<'a>(&self, xml: &'a str) -> &'a str {
        // Parse the preamble
        let idx = xml.find_str("?>").expect("No preamble end");
        let end_of_preamble = idx + "?>".len();
        xml.slice_from(end_of_preamble)
    }

    fn parse_element<'a>(&self, doc: Document, xml: &'a str) -> (Element, &'a str) {
        let (_, after_start_brace) = xml.expect_literal("<").expect("no start brace");

        let (name, after_name) = after_start_brace.slice_name().expect("failed to parse a name!");

        // skip_space
        let (_, after_end_brace) = after_name.expect_literal(" />").expect("no end brace");

        let e = doc.new_element(name.to_string());

        (e, after_end_brace)
    }

    fn parse(&self, xml: &str) -> Document {
        let doc = Document::new();

        let after_preamble = self.parse_preamble(xml);

        let (element, _tail) = self.parse_element(doc.clone(), after_preamble);
        doc.root().append_child(element);

        doc
    }
}

trait XmlStr<'a> {
    fn slice_at(&self, position: uint) -> (&'a str, &'a str);
    fn expect_literal(&self, expected: &str) -> Option<(&'a str, &'a str)>;
    fn slice_name(&self) -> Option<(&'a str, &'a str)>;
}

impl<'a> XmlStr<'a> for &'a str {
    fn slice_at(&self, position: uint) -> (&'a str, &'a str) {
        (self.slice_to(position), self.slice_from(position))
    }

    fn expect_literal(&self, expected: &str) -> Option<(&'a str, &'a str)> {
        if self.starts_with(expected) {
            Some(self.slice_at(expected.len()))
        } else {
            None
        }
    }

    fn slice_name(&self) -> Option<(&'a str, &'a str)> {
        let mut positions = self.char_indices();

        let first_char = match positions.next() {
            Some((_, c)) if c.is_name_start_char() => c,
            Some((_, c)) => return None,
            None => return None,
        };

        // Skip past all the name chars
        let mut positions = positions.skip_while(|&(_, c)| c.is_name_char());

        match positions.next() {
            Some((offset, _)) => Some(self.slice_at(offset)),
            None => Some((self.clone(), "")),
        }
    }
}

trait XmlChar {
    fn is_name_start_char(&self) -> bool;
    fn is_name_char(&self) -> bool;
}

impl XmlChar for char {
    fn is_name_start_char(&self) -> bool {
        match *self {
            ':'                        |
            'A'..'Z'                   |
            '_'                        |
            'a'..'z'                   |
            '\U000000C0'..'\U000000D6' |
            '\U000000D8'..'\U000000F6' |
            '\U000000F8'..'\U000002FF' |
            '\U00000370'..'\U0000037D' |
            '\U0000037F'..'\U00001FFF' |
            '\U0000200C'..'\U0000200D' |
            '\U00002070'..'\U0000218F' |
            '\U00002C00'..'\U00002FEF' |
            '\U00003001'..'\U0000D7FF' |
            '\U0000F900'..'\U0000FDCF' |
            '\U0000FDF0'..'\U0000FFFD' |
            '\U00010000'..'\U000EFFFF' => true,
            _ => false,
        }
    }

    fn is_name_char(&self) -> bool {
        if self.is_name_start_char() { return true; }
        match *self {
            '-'                |
            '.'                |
            '0'..'9'           |
            '\u00B7'           |
            '\u0300'..'\u036F' |
            '\u203F'..'\u2040' => true,
            _ => false
        }
    }
}

trait Hax {
    fn first_child(&self) -> Option<RootChild>;
}

impl Hax for Root {
    fn first_child(&self) -> Option<RootChild> {
        self.children().remove(0)
    }
}

#[test]
fn parses_a_document_with_a_single_element() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello />");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.name().as_slice(), "hello");
}
<commit_msg>Parse spaces better<commit_after>use super::{Document,Root,RootChild,Element};

struct Parser;

impl Parser {
    fn new() -> Parser {
        Parser
    }

    fn parse_preamble<'a>(&self, xml: &'a str) -> &'a str {
        // Parse the preamble
        let idx = xml.find_str("?>").expect("No preamble end");
        let end_of_preamble = idx + "?>".len();
        xml.slice_from(end_of_preamble)
    }

    fn parse_element<'a>(&self, doc: Document, xml: &'a str) -> (Element, &'a str) {
        let (_, after_start_brace) = xml.slice_literal("<").expect("no start brace");

        let (name, after_name) = after_start_brace.slice_name().expect("failed to parse a name!");

        let (_, after_space) = after_name.slice_space().expect("no space after name");

        let (_, after_end_brace) = after_space.slice_literal("/>").expect("no end brace");

        let e = doc.new_element(name.to_string());

        (e, after_end_brace)
    }

    fn parse(&self, xml: &str) -> Document {
        let doc = Document::new();

        let after_preamble = self.parse_preamble(xml);

        let (element, _tail) = self.parse_element(doc.clone(), after_preamble);
        doc.root().append_child(element);

        doc
    }
}

trait XmlStr<'a> {
    fn slice_at(&self, position: uint) -> (&'a str, &'a str);
    fn slice_literal(&self, expected: &str) -> Option<(&'a str, &'a str)>;
    fn slice_start_rest(&self, is_first: |char| -> bool, is_rest: |char| -> bool) -> Option<(&'a str, &'a str)>;
    fn slice_name(&self) -> Option<(&'a str, &'a str)>;
    fn slice_space(&self) -> Option<(&'a str, &'a str)>;
}

impl<'a> XmlStr<'a> for &'a str {
    fn slice_at(&self, position: uint) -> (&'a str, &'a str) {
        (self.slice_to(position), self.slice_from(position))
    }

    fn slice_literal(&self, expected: &str) -> Option<(&'a str, &'a str)> {
        if self.starts_with(expected) {
            Some(self.slice_at(expected.len()))
        } else {
            None
        }
    }

    fn slice_start_rest(&self,
                        is_first: |char| -> bool,
                        is_rest: |char| -> bool)
                        -> Option<(&'a str, &'a str)>
    {
        let mut positions = self.char_indices();

        match positions.next() {
            Some((_, c)) if is_first(c) => (),
            Some((_, _)) => return None,
            None => return None,
        };

        let mut positions = positions.skip_while(|&(_, c)| is_rest(c));
        match positions.next() {
            Some((offset, _)) => Some(self.slice_at(offset)),
            None => Some((self.clone(), "")),
        }
    }

    fn slice_name(&self) -> Option<(&'a str, &'a str)> {
        self.slice_start_rest(|c| c.is_name_start_char(), |c| c.is_name_char())
    }

    fn slice_space(&self) -> Option<(&'a str, &'a str)> {
        self.slice_start_rest(|c| c.is_space_char(), |c| c.is_space_char())
    }
}

trait XmlChar {
    fn is_name_start_char(&self) -> bool;
    fn is_name_char(&self) -> bool;
    fn is_space_char(&self) -> bool;
}

impl XmlChar for char {
    fn is_name_start_char(&self) -> bool {
        match *self {
            ':'                        |
            'A'..'Z'                   |
            '_'                        |
            'a'..'z'                   |
            '\U000000C0'..'\U000000D6' |
            '\U000000D8'..'\U000000F6' |
            '\U000000F8'..'\U000002FF' |
            '\U00000370'..'\U0000037D' |
            '\U0000037F'..'\U00001FFF' |
            '\U0000200C'..'\U0000200D' |
            '\U00002070'..'\U0000218F' |
            '\U00002C00'..'\U00002FEF' |
            '\U00003001'..'\U0000D7FF' |
            '\U0000F900'..'\U0000FDCF' |
            '\U0000FDF0'..'\U0000FFFD' |
            '\U00010000'..'\U000EFFFF' => true,
            _ => false,
        }
    }

    fn is_name_char(&self) -> bool {
        if self.is_name_start_char() { return true; }
        match *self {
            '-'                |
            '.'                |
            '0'..'9'           |
            '\u00B7'           |
            '\u0300'..'\u036F' |
            '\u203F'..'\u2040' => true,
            _ => false
        }
    }

    fn is_space_char(&self) -> bool {
        match *self {
            '\x20' |
            '\x09' |
            '\x0D' |
            '\x0A' => true,
            _ => false,
        }
    }
}

trait Hax {
    fn first_child(&self) -> Option<RootChild>;
}

impl Hax for Root {
    fn first_child(&self) -> Option<RootChild> {
        self.children().remove(0)
    }
}

#[test]
fn parses_a_document_with_a_single_element() {
    let parser = Parser::new();
    let doc = parser.parse("<?xml version='1.0' ?><hello />");
    let top = doc.root().first_child().unwrap().element().unwrap();

    assert_eq!(top.name().as_slice(), "hello");
}
<|endoftext|>


<commit_before>use itertools::Itertools;
use syntax::{
    ast::{self, AstNode, AstToken},
    match_ast, NodeOrToken, SyntaxElement, TextRange, TextSize, T,
};

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

// Assist: remove_dbg
//
// Removes `dbg!()` macro call.
//
// ```
// fn main() {
//     $0dbg!(92);
// }
// ```
// ->
// ```
// fn main() {
//     92;
// }
// ```
pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let macro_call = ctx.find_node_at_offset::<ast::MacroCall>()?;
    let tt = macro_call.token_tree()?;
    let r_delim = NodeOrToken::Token(tt.right_delimiter_token()?);
    if macro_call.path()?.segment()?.name_ref()?.text() != "dbg"
        || macro_call.excl_token().is_none()
    {
        return None;
    }

    let mac_input = tt.syntax().children_with_tokens().skip(1).take_while(|it| *it != r_delim);
    let input_expressions = mac_input.into_iter().group_by(|tok| tok.kind() == T![,]);
    let input_expressions = input_expressions
        .into_iter()
        .filter_map(|(is_sep, group)| (!is_sep).then(|| group))
        .map(|mut tokens| ast::Expr::parse(&tokens.join("")))
        .collect::<Result<Vec<ast::Expr>, _>>()
        .ok()?;

    let parent = macro_call.syntax().parent()?;
    let parent_is_let_stmt = ast::LetStmt::can_cast(parent.kind());
    let (range, text) = match &*input_expressions {
        // dbg!()
        [] => {
            match_ast! {
                match parent {
                    ast::BlockExpr(__) => {
                        let range = macro_call.syntax().text_range();
                        let range = match whitespace_start(macro_call.syntax().prev_sibling_or_token()) {
                            Some(start) => range.cover_offset(start),
                            None => range,
                        };
                        (range, String::new())
                    },
                    ast::ExprStmt(it) => {
                        let range = it.syntax().text_range();
                        let range = match whitespace_start(it.syntax().prev_sibling_or_token()) {
                            Some(start) => range.cover_offset(start),
                            None => range,
                        };
                        (range, String::new())
                    },
                    _ => (macro_call.syntax().text_range(), "()".to_owned())
                }
            }
        }
        // dbg!(expr0)
        [expr] => {
            let wrap = match ast::Expr::cast(parent) {
                Some(parent) => match (expr, parent) {
                    (ast::Expr::CastExpr(_), ast::Expr::CastExpr(_)) => false,
                    (
                        ast::Expr::BoxExpr(_) | ast::Expr::PrefixExpr(_) | ast::Expr::RefExpr(_),
                        ast::Expr::AwaitExpr(_)
                        | ast::Expr::BinExpr(_)
                        | ast::Expr::CallExpr(_)
                        | ast::Expr::CastExpr(_)
                        | ast::Expr::FieldExpr(_)
                        | ast::Expr::IndexExpr(_)
                        | ast::Expr::MethodCallExpr(_)
                        | ast::Expr::RangeExpr(_)
                        | ast::Expr::TryExpr(_),
                    ) => true,
                    (
                        ast::Expr::BinExpr(_) | ast::Expr::CastExpr(_) | ast::Expr::RangeExpr(_),
                        ast::Expr::AwaitExpr(_)
                        | ast::Expr::BinExpr(_)
                        | ast::Expr::CallExpr(_)
                        | ast::Expr::CastExpr(_)
                        | ast::Expr::FieldExpr(_)
                        | ast::Expr::IndexExpr(_)
                        | ast::Expr::MethodCallExpr(_)
                        | ast::Expr::PrefixExpr(_)
                        | ast::Expr::RangeExpr(_)
                        | ast::Expr::RefExpr(_)
                        | ast::Expr::TryExpr(_),
                    ) => true,
                    _ => false,
                },
                None => false,
            };
            (
                macro_call.syntax().text_range(),
                if wrap { format!("({})", expr) } else { expr.to_string() },
            )
        }
        // dbg!(expr0, expr1, ...)
        exprs => (macro_call.syntax().text_range(), format!("({})", exprs.iter().format(","))),
    };

    let range = if macro_call.semicolon_token().is_some() && parent_is_let_stmt {
        TextRange::new(range.start(), range.end() - TextSize::of(";"))
    } else {
        range
    };

    acc.add(AssistId("remove_dbg", AssistKind::Refactor), "Remove dbg!()", range, |builder| {
        builder.replace(range, text);
    })
}

fn whitespace_start(it: Option<SyntaxElement>) -> Option<TextSize> {
    Some(it?.into_token().and_then(ast::Whitespace::cast)?.syntax().text_range().start())
}

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

    use super::*;

    fn check(ra_fixture_before: &str, ra_fixture_after: &str) {
        check_assist(
            remove_dbg,
            &format!("fn main() {{\n{}\n}}", ra_fixture_before),
            &format!("fn main() {{\n{}\n}}", ra_fixture_after),
        );
    }

    #[test]
    fn test_remove_dbg() {
        check("$0dbg!(1 + 1)", "1 + 1");
        check("dbg!$0((1 + 1))", "(1 + 1)");
        check("dbg!(1 $0+ 1)", "1 + 1");
        check("let _ = $0dbg!(1 + 1)", "let _ = 1 + 1");
        check(
            "if let Some(_) = dbg!(n.$0checked_sub(4)) {}",
            "if let Some(_) = n.checked_sub(4) {}",
        );
        check("$0dbg!(Foo::foo_test()).bar()", "Foo::foo_test().bar()");
    }

    #[test]
    fn test_remove_dbg_with_brackets_and_braces() {
        check("dbg![$01 + 1]", "1 + 1");
        check("dbg!{$01 + 1}", "1 + 1");
    }

    #[test]
    fn test_remove_dbg_not_applicable() {
        check_assist_not_applicable(remove_dbg, "fn main() {$0vec![1, 2, 3]}");
        check_assist_not_applicable(remove_dbg, "fn main() {$0dbg(5, 6, 7)}");
        check_assist_not_applicable(remove_dbg, "fn main() {$0dbg!(5, 6, 7}");
    }

    #[test]
    fn test_remove_dbg_keep_semicolon() {
        // https://github.com/rust-analyzer/rust-analyzer/issues/5129#issuecomment-651399779
        // not quite though
        // adding a comment at the end of the line makes
        // the ast::MacroCall to include the semicolon at the end
        check(
            r#"let res = $0dbg!(1 * 20); // needless comment"#,
            r#"let res = 1 * 20; // needless comment"#,
        );
    }

    #[test]
    fn remove_dbg_from_non_leaf_simple_expression() {
        check_assist(
            remove_dbg,
            r"
fn main() {
    let mut a = 1;
    while dbg!$0(a) < 10000 {
        a += 1;
    }
}
",
            r"
fn main() {
    let mut a = 1;
    while a < 10000 {
        a += 1;
    }
}
",
        );
    }

    #[test]
    fn test_remove_dbg_keep_expression() {
        check(r#"let res = $0dbg!(a + b).foo();"#, r#"let res = (a + b).foo();"#);
        check(r#"let res = $0dbg!(2 + 2) * 5"#, r#"let res = (2 + 2) * 5"#);
        check(r#"let res = $0dbg![2 + 2] * 5"#, r#"let res = (2 + 2) * 5"#);
    }

    #[test]
    fn test_remove_dbg_method_chaining() {
        check(r#"let res = $0dbg!(foo().bar()).baz();"#, r#"let res = foo().bar().baz();"#);
        check(r#"let res = $0dbg!(foo.bar()).baz();"#, r#"let res = foo.bar().baz();"#);
    }

    #[test]
    fn test_remove_dbg_field_chaining() {
        check(r#"let res = $0dbg!(foo.bar).baz;"#, r#"let res = foo.bar.baz;"#);
    }

    #[test]
    fn test_remove_dbg_from_inside_fn() {
        check_assist(
            remove_dbg,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(dbg$0!(5 + 10));
    println!("{}", x);
}"#,
            r#"
fn square(x: u32) -> u32 {
    x * x
}

fn main() {
    let x = square(5 + 10);
    println!("{}", x);
}"#,
        );
    }

    #[test]
    fn test_remove_dbg_try_expr() {
        check(r#"let res = $0dbg!(result?).foo();"#, r#"let res = result?.foo();"#);
    }

    #[test]
    fn test_remove_dbg_await_expr() {
        check(r#"let res = $0dbg!(fut.await).foo();"#, r#"let res = fut.await.foo();"#);
    }

    #[test]
    fn test_remove_dbg_as_cast() {
        check(r#"let res = $0dbg!(3 as usize).foo();"#, r#"let res = (3 as usize).foo();"#);
    }

    #[test]
    fn test_remove_dbg_index_expr() {
        check(r#"let res = $0dbg!(array[3]).foo();"#, r#"let res = array[3].foo();"#);
        check(r#"let res = $0dbg!(tuple.3).foo();"#, r#"let res = tuple.3.foo();"#);
    }

    #[test]
    fn test_remove_dbg_range_expr() {
        check(r#"let res = $0dbg!(foo..bar).foo();"#, r#"let res = (foo..bar).foo();"#);
        check(r#"let res = $0dbg!(foo..=bar).foo();"#, r#"let res = (foo..=bar).foo();"#);
    }

    #[test]
    fn test_remove_dbg_followed_by_block() {
        check_assist(
            remove_dbg,
            r#"fn foo() {
    if $0dbg!(x || y) {}
}"#,
            r#"fn foo() {
    if x || y {}
}"#,
        );
        check_assist(
            remove_dbg,
            r#"fn foo() {
    while let foo = $0dbg!(&x) {}
}"#,
            r#"fn foo() {
    while let foo = &x {}
}"#,
        );
        check_assist(
            remove_dbg,
            r#"fn foo() {
    if let foo = $0dbg!(&x) {}
}"#,
            r#"fn foo() {
    if let foo = &x {}
}"#,
        );
        check_assist(
            remove_dbg,
            r#"fn foo() {
    match $0dbg!(&x) {}
}"#,
            r#"fn foo() {
    match &x {}
}"#,
        );
    }

    #[test]
    fn test_remove_empty_dbg() {
        check_assist(remove_dbg, r#"fn foo() { $0dbg!(); }"#, r#"fn foo() { }"#);
        check_assist(
            remove_dbg,
            r#"
fn foo() {
    $0dbg!();
}
"#,
            r#"
fn foo() {
}
"#,
        );
        check_assist(
            remove_dbg,
            r#"
fn foo() {
    let test = $0dbg!();
}"#,
            r#"
fn foo() {
    let test = ();
}"#,
        );
        check_assist(
            remove_dbg,
            r#"
fn foo() {
    let t = {
        println!("Hello, world");
        $0dbg!()
    };
}"#,
            r#"
fn foo() {
    let t = {
        println!("Hello, world");
    };
}"#,
        );
    }
}
<commit_msg>Cleanup tests<commit_after>use itertools::Itertools;
use syntax::{
    ast::{self, AstNode, AstToken},
    match_ast, NodeOrToken, SyntaxElement, TextSize, T,
};

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

// Assist: remove_dbg
//
// Removes `dbg!()` macro call.
//
// ```
// fn main() {
//     $0dbg!(92);
// }
// ```
// ->
// ```
// fn main() {
//     92;
// }
// ```
pub(crate) fn remove_dbg(acc: &mut Assists, ctx: &AssistContext) -> Option<()> {
    let macro_call = ctx.find_node_at_offset::<ast::MacroCall>()?;
    let tt = macro_call.token_tree()?;
    let r_delim = NodeOrToken::Token(tt.right_delimiter_token()?);
    if macro_call.path()?.segment()?.name_ref()?.text() != "dbg"
        || macro_call.excl_token().is_none()
    {
        return None;
    }

    let mac_input = tt.syntax().children_with_tokens().skip(1).take_while(|it| *it != r_delim);
    let input_expressions = mac_input.into_iter().group_by(|tok| tok.kind() == T![,]);
    let input_expressions = input_expressions
        .into_iter()
        .filter_map(|(is_sep, group)| (!is_sep).then(|| group))
        .map(|mut tokens| ast::Expr::parse(&tokens.join("")))
        .collect::<Result<Vec<ast::Expr>, _>>()
        .ok()?;

    let parent = macro_call.syntax().parent()?;
    let (range, text) = match &*input_expressions {
        // dbg!()
        [] => {
            match_ast! {
                match parent {
                    ast::BlockExpr(__) => {
                        let range = macro_call.syntax().text_range();
                        let range = match whitespace_start(macro_call.syntax().prev_sibling_or_token()) {
                            Some(start) => range.cover_offset(start),
                            None => range,
                        };
                        (range, String::new())
                    },
                    ast::ExprStmt(it) => {
                        let range = it.syntax().text_range();
                        let range = match whitespace_start(it.syntax().prev_sibling_or_token()) {
                            Some(start) => range.cover_offset(start),
                            None => range,
                        };
                        (range, String::new())
                    },
                    _ => (macro_call.syntax().text_range(), "()".to_owned())
                }
            }
        }
        // dbg!(expr0)
        [expr] => {
            let wrap = match ast::Expr::cast(parent) {
                Some(parent) => match (expr, parent) {
                    (ast::Expr::CastExpr(_), ast::Expr::CastExpr(_)) => false,
                    (
                        ast::Expr::BoxExpr(_) | ast::Expr::PrefixExpr(_) | ast::Expr::RefExpr(_),
                        ast::Expr::AwaitExpr(_)
                        | ast::Expr::CallExpr(_)
                        | ast::Expr::CastExpr(_)
                        | ast::Expr::FieldExpr(_)
                        | ast::Expr::IndexExpr(_)
                        | ast::Expr::MethodCallExpr(_)
                        | ast::Expr::RangeExpr(_)
                        | ast::Expr::TryExpr(_),
                    ) => true,
                    (
                        ast::Expr::BinExpr(_) | ast::Expr::CastExpr(_) | ast::Expr::RangeExpr(_),
                        ast::Expr::AwaitExpr(_)
                        | ast::Expr::BinExpr(_)
                        | ast::Expr::CallExpr(_)
                        | ast::Expr::CastExpr(_)
                        | ast::Expr::FieldExpr(_)
                        | ast::Expr::IndexExpr(_)
                        | ast::Expr::MethodCallExpr(_)
                        | ast::Expr::PrefixExpr(_)
                        | ast::Expr::RangeExpr(_)
                        | ast::Expr::RefExpr(_)
                        | ast::Expr::TryExpr(_),
                    ) => true,
                    _ => false,
                },
                None => false,
            };
            (
                macro_call.syntax().text_range(),
                if wrap { format!("({})", expr) } else { expr.to_string() },
            )
        }
        // dbg!(expr0, expr1, ...)
        exprs => (macro_call.syntax().text_range(), format!("({})", exprs.iter().format(", "))),
    };

    acc.add(AssistId("remove_dbg", AssistKind::Refactor), "Remove dbg!()", range, |builder| {
        builder.replace(range, text);
    })
}

fn whitespace_start(it: Option<SyntaxElement>) -> Option<TextSize> {
    Some(it?.into_token().and_then(ast::Whitespace::cast)?.syntax().text_range().start())
}

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

    use super::*;

    fn check(ra_fixture_before: &str, ra_fixture_after: &str) {
        check_assist(
            remove_dbg,
            &format!("fn main() {{\n{}\n}}", ra_fixture_before),
            &format!("fn main() {{\n{}\n}}", ra_fixture_after),
        );
    }

    #[test]
    fn test_remove_dbg() {
        check("$0dbg!(1 + 1)", "1 + 1");
        check("dbg!$0(1 + 1)", "1 + 1");
        check("dbg!(1 $0+ 1)", "1 + 1");
        check("dbg![$01 + 1]", "1 + 1");
        check("dbg!{$01 + 1}", "1 + 1");
    }

    #[test]
    fn test_remove_dbg_not_applicable() {
        check_assist_not_applicable(remove_dbg, "fn main() {$0vec![1, 2, 3]}");
        check_assist_not_applicable(remove_dbg, "fn main() {$0dbg(5, 6, 7)}");
        check_assist_not_applicable(remove_dbg, "fn main() {$0dbg!(5, 6, 7}");
    }

    #[test]
    fn test_remove_dbg_keep_semicolon_in_let() {
        // https://github.com/rust-analyzer/rust-analyzer/issues/5129#issuecomment-651399779
        check(
            r#"let res = $0dbg!(1 * 20); // needless comment"#,
            r#"let res = 1 * 20; // needless comment"#,
        );
        check(r#"let res = $0dbg!(); // needless comment"#, r#"let res = (); // needless comment"#);
        check(
            r#"let res = $0dbg!(1, 2); // needless comment"#,
            r#"let res = (1, 2); // needless comment"#,
        );
    }

    #[test]
    fn test_remove_dbg_cast_cast() {
        check(r#"let res = $0dbg!(x as u32) as u32;"#, r#"let res = x as u32 as u32;"#);
    }

    #[test]
    fn test_remove_dbg_prefix() {
        check(r#"let res = $0dbg!(&result).foo();"#, r#"let res = (&result).foo();"#);
        check(r#"let res = &$0dbg!(&result);"#, r#"let res = &&result;"#);
        check(r#"let res = $0dbg!(!result) && true;"#, r#"let res = !result && true;"#);
    }

    #[test]
    fn test_remove_dbg_post_expr() {
        check(r#"let res = $0dbg!(fut.await).foo();"#, r#"let res = fut.await.foo();"#);
        check(r#"let res = $0dbg!(result?).foo();"#, r#"let res = result?.foo();"#);
        check(r#"let res = $0dbg!(foo as u32).foo();"#, r#"let res = (foo as u32).foo();"#);
        check(r#"let res = $0dbg!(array[3]).foo();"#, r#"let res = array[3].foo();"#);
        check(r#"let res = $0dbg!(tuple.3).foo();"#, r#"let res = tuple.3.foo();"#);
    }

    #[test]
    fn test_remove_dbg_range_expr() {
        check(r#"let res = $0dbg!(foo..bar).foo();"#, r#"let res = (foo..bar).foo();"#);
        check(r#"let res = $0dbg!(foo..=bar).foo();"#, r#"let res = (foo..=bar).foo();"#);
    }

    #[test]
    fn test_remove_empty_dbg() {
        check_assist(remove_dbg, r#"fn foo() { $0dbg!(); }"#, r#"fn foo() { }"#);
        check_assist(
            remove_dbg,
            r#"
fn foo() {
    $0dbg!();
}
"#,
            r#"
fn foo() {
}
"#,
        );
        check_assist(
            remove_dbg,
            r#"
fn foo() {
    let test = $0dbg!();
}"#,
            r#"
fn foo() {
    let test = ();
}"#,
        );
        check_assist(
            remove_dbg,
            r#"
fn foo() {
    let t = {
        println!("Hello, world");
        $0dbg!()
    };
}"#,
            r#"
fn foo() {
    let t = {
        println!("Hello, world");
    };
}"#,
        );
    }

    #[test]
    fn test_remove_multi_dbg() {
        check(r#"$0dbg!(0, 1)"#, r#"(0, 1)"#);
        check(r#"$0dbg!(0, (1, 2))"#, r#"(0, (1, 2))"#);
    }
}
<|endoftext|>


<commit_before>use std::collections::HashMap;
use std::fs;
use std::io::Write;
use std::path::Path;

use super::{capitalize_first, FileWriter, IoResult};
use botocore::Service;
use util::case_insensitive_btreemap_get;
use inflector::Inflector;

const BOTOCORE_TESTS_DIR: &'static str = concat!(env!("CARGO_MANIFEST_DIR"),
                                                 "/botocore/tests/unit/response_parsing/xml/responses/");
const OUR_TESTS_DIR: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/unit/responses/");

pub fn generate_tests(writer: &mut FileWriter, service: &Service) -> IoResult {
    writeln!(writer,
             "
            #[cfg(test)]
            mod protocol_tests {{
                {tests_body}
            }}
            ",
             tests_body = generate_tests_body(service).unwrap_or("".to_string()))
}

fn generate_tests_body(service: &Service) -> Option<String> {
    let responses: HashMap<String, Response> = find_responses();

    let our_responses: Vec<Response> = responses.values()
        .into_iter()
        .filter(|r| r.service.to_lowercase() == service.service_type_name().to_lowercase())
        .map(|r| r.to_owned())
        .collect();

    let test_bodies: Vec<String> = our_responses.into_iter()
        .flat_map(|response| generate_response_parse_test(service, response))
        .collect();

    if !test_bodies.is_empty() {
        let tests_str = test_bodies.join("\n\n");

        Some(format!("
                use mock::*;
                use super::*;
                use super::super::Region as rusoto_region;

                {test_bodies}",
                     test_bodies = tests_str))
    } else {
        None
    }
}

fn generate_response_parse_test(service: &Service, response: Response) -> Option<String> {
    let maybe_operation = case_insensitive_btreemap_get(&service.operations, &response.action);

    if maybe_operation.is_none() {
        return None;
    }

    let operation = maybe_operation.unwrap();
    let request_params;
    let request_constructor;
    if operation.input.is_some() {
        request_constructor = format!("let request = {request_type}::default();",
                                      request_type = operation.input_shape());
        request_params = "&request".to_string();
    } else {
        request_constructor = "".to_string();
        request_params = "".to_string();
    }

    Some(format!("
        #[test]
        fn test_parse_{service_name}_{action}() {{
            let mock_response =  MockResponseReader::read_response(r#\"{response_dir_name}\"#, \"{response_file_name}\");
            let mock = MockRequestDispatcher::with_status(200)
                .with_body(&mock_response);
            let client = {client_type}::new(mock, MockCredentialsProvider, rusoto_region::UsEast1);
            {request_constructor}
            let result = client.{action}({request_params});
            assert!(result.is_ok(), \"parse error: {{:?}}\", result);
        }}
    ",
                 service_name = response.service.to_snake_case(),
                 action = response.action.to_snake_case(),
                 response_dir_name = response.dir_name,
                 response_file_name = response.file_name,
                 client_type = service.client_type_name(),
                 request_constructor = request_constructor,
                 request_params = request_params))
}

#[derive(Debug, Clone)]
pub struct Response {
    pub service: String,
    pub action: String,
    pub dir_name: String,
    pub file_name: String,
    pub extension: String,
}

impl Response {
    pub fn from_response_file_name(directory: &Path, f: &str) -> Option<Response> {
        let maybe_file_name_and_extension: Vec<&str> = f.split('.').collect();

        let mut service_name = None;
        let mut action = None;
        let extension = maybe_file_name_and_extension.get(1);

        if let Some(file_name) = maybe_file_name_and_extension.get(0) {
            let file_name_parts: Vec<&str> = file_name.split('-').collect();

            service_name = file_name_parts.get(0).map(|s| capitalize_first(*s));

            action = Some(file_name_parts.into_iter().skip(1).map(capitalize_first).collect());
        }

        service_name.and_then(|s| {
            action.and_then(|a| {
                extension.and_then(|e| {
                    Some(Response {
                        service: s,
                        action: a,
                        dir_name: directory.to_str().unwrap().to_owned(),
                        file_name: f.to_owned(),
                        extension: e.to_string(),
                    })
                })
            })
        })
    }
}

pub fn find_responses_in_dir(dir_path: &Path) -> Vec<Response> {
    let dir = fs::read_dir(dir_path).expect("read_dir");

    dir.map(|d| d.expect("direntry").file_name().into_string().expect("osstr"))
        .flat_map(|f| Response::from_response_file_name(dir_path, &f))
        .filter(|r| r.extension == "xml")
        .collect()
}

pub fn find_responses() -> HashMap<String, Response> {
    let mut responses = HashMap::new();

    for r in find_responses_in_dir(Path::new(BOTOCORE_TESTS_DIR)) {
        responses.insert(r.file_name.clone(), r);
    }

    for r in find_responses_in_dir(Path::new(OUR_TESTS_DIR)) {
        responses.insert(r.file_name.clone(), r);
    }

    responses
}
<commit_msg>Bikeshed some spacing in codegen.<commit_after>use std::collections::HashMap;
use std::fs;
use std::io::Write;
use std::path::Path;

use super::{capitalize_first, FileWriter, IoResult};
use botocore::Service;
use util::case_insensitive_btreemap_get;
use inflector::Inflector;

const BOTOCORE_TESTS_DIR: &'static str = concat!(env!("CARGO_MANIFEST_DIR"),
                                                 "/botocore/tests/unit/response_parsing/xml/responses/");
const OUR_TESTS_DIR: &'static str = concat!(env!("CARGO_MANIFEST_DIR"), "/tests/unit/responses/");

pub fn generate_tests(writer: &mut FileWriter, service: &Service) -> IoResult {
    writeln!(writer,
             "
#[cfg(test)]
mod protocol_tests {{
    {tests_body}
}}
            ",
             tests_body = generate_tests_body(service).unwrap_or("".to_string()))
}

fn generate_tests_body(service: &Service) -> Option<String> {
    let responses: HashMap<String, Response> = find_responses();

    let our_responses: Vec<Response> = responses.values()
        .into_iter()
        .filter(|r| r.service.to_lowercase() == service.service_type_name().to_lowercase())
        .map(|r| r.to_owned())
        .collect();

    let test_bodies: Vec<String> = our_responses.into_iter()
        .flat_map(|response| generate_response_parse_test(service, response))
        .collect();

    if !test_bodies.is_empty() {
        let tests_str = test_bodies.join("\n\n");

        Some(format!("
                use mock::*;
                use super::*;
                use super::super::Region as rusoto_region;

                {test_bodies}",
                     test_bodies = tests_str))
    } else {
        None
    }
}

fn generate_response_parse_test(service: &Service, response: Response) -> Option<String> {
    let maybe_operation = case_insensitive_btreemap_get(&service.operations, &response.action);

    if maybe_operation.is_none() {
        return None;
    }

    let operation = maybe_operation.unwrap();
    let request_params;
    let request_constructor;
    if operation.input.is_some() {
        request_constructor = format!("let request = {request_type}::default();",
                                      request_type = operation.input_shape());
        request_params = "&request".to_string();
    } else {
        request_constructor = "".to_string();
        request_params = "".to_string();
    }

    Some(format!("
        #[test]
        fn test_parse_{service_name}_{action}() {{
            let mock_response =  MockResponseReader::read_response(r#\"{response_dir_name}\"#, \"{response_file_name}\");
            let mock = MockRequestDispatcher::with_status(200)
                .with_body(&mock_response);
            let client = {client_type}::new(mock, MockCredentialsProvider, rusoto_region::UsEast1);
            {request_constructor}
            let result = client.{action}({request_params});
            assert!(result.is_ok(), \"parse error: {{:?}}\", result);
        }}",
        service_name = response.service.to_snake_case(),
        action = response.action.to_snake_case(),
        response_dir_name = response.dir_name,
        response_file_name = response.file_name,
        client_type = service.client_type_name(),
        request_constructor = request_constructor,
        request_params = request_params))
}

#[derive(Debug, Clone)]
pub struct Response {
    pub service: String,
    pub action: String,
    pub dir_name: String,
    pub file_name: String,
    pub extension: String,
}

impl Response {
    pub fn from_response_file_name(directory: &Path, f: &str) -> Option<Response> {
        let maybe_file_name_and_extension: Vec<&str> = f.split('.').collect();

        let mut service_name = None;
        let mut action = None;
        let extension = maybe_file_name_and_extension.get(1);

        if let Some(file_name) = maybe_file_name_and_extension.get(0) {
            let file_name_parts: Vec<&str> = file_name.split('-').collect();

            service_name = file_name_parts.get(0).map(|s| capitalize_first(*s));

            action = Some(file_name_parts.into_iter().skip(1).map(capitalize_first).collect());
        }

        service_name.and_then(|s| {
            action.and_then(|a| {
                extension.and_then(|e| {
                    Some(Response {
                        service: s,
                        action: a,
                        dir_name: directory.to_str().unwrap().to_owned(),
                        file_name: f.to_owned(),
                        extension: e.to_string(),
                    })
                })
            })
        })
    }
}

pub fn find_responses_in_dir(dir_path: &Path) -> Vec<Response> {
    let dir = fs::read_dir(dir_path).expect("read_dir");

    dir.map(|d| d.expect("direntry").file_name().into_string().expect("osstr"))
        .flat_map(|f| Response::from_response_file_name(dir_path, &f))
        .filter(|r| r.extension == "xml")
        .collect()
}

pub fn find_responses() -> HashMap<String, Response> {
    let mut responses = HashMap::new();

    for r in find_responses_in_dir(Path::new(BOTOCORE_TESTS_DIR)) {
        responses.insert(r.file_name.clone(), r);
    }

    for r in find_responses_in_dir(Path::new(OUR_TESTS_DIR)) {
        responses.insert(r.file_name.clone(), r);
    }

    responses
}
<|endoftext|>


<commit_before>//! Implement linear solver using LU decomposition
//! for tridiagonal matrix

use super::*;
use crate::{error::*, layout::MatrixLayout};
use cauchy::*;
use num_traits::Zero;
use std::ops::{Index, IndexMut};

/// Represents a tridiagonal matrix as 3 one-dimensional vectors.
///
/// ```text
/// [d0, u1,  0,   ...,       0,
///  l1, d1, u2,            ...,
///   0, l2, d2,
///  ...           ...,  u{n-1},
///   0,  ...,  l{n-1},  d{n-1},]
/// ```
#[derive(Clone, PartialEq)]
pub struct Tridiagonal<A: Scalar> {
    /// layout of raw matrix
    pub l: MatrixLayout,
    /// (n-1) sub-diagonal elements of matrix.
    pub dl: Vec<A>,
    /// (n) diagonal elements of matrix.
    pub d: Vec<A>,
    /// (n-1) super-diagonal elements of matrix.
    pub du: Vec<A>,
}

impl<A: Scalar> Tridiagonal<A> {
    fn opnorm_one(&self) -> A::Real {
        let mut col_sum: Vec<A::Real> = self.d.iter().map(|val| val.abs()).collect();
        for i in 0..col_sum.len() {
            if i < self.dl.len() {
                col_sum[i] += self.dl[i].abs();
            }
            if i > 0 {
                col_sum[i] += self.du[i - 1].abs();
            }
        }
        let mut max = A::Real::zero();
        for &val in &col_sum {
            if max < val {
                max = val;
            }
        }
        max
    }
}

/// Represents the LU factorization of a tridiagonal matrix `A` as `A = P*L*U`.
#[derive(Clone, PartialEq)]
pub struct LUFactorizedTridiagonal<A: Scalar> {
    /// A tridiagonal matrix which consists of
    /// - l : layout of raw matrix
    /// - dl: (n-1) multipliers that define the matrix L.
    /// - d : (n) diagonal elements of the upper triangular matrix U.
    /// - du: (n-1) elements of the first super-diagonal of U.
    pub a: Tridiagonal<A>,
    /// (n-2) elements of the second super-diagonal of U.
    pub du2: Vec<A>,
    /// The pivot indices that define the permutation matrix `P`.
    pub ipiv: Pivot,

    a_opnorm_one: A::Real,
}

impl<A: Scalar> Index<(i32, i32)> for Tridiagonal<A> {
    type Output = A;
    #[inline]
    fn index(&self, (row, col): (i32, i32)) -> &A {
        let (n, _) = self.l.size();
        assert!(
            std::cmp::max(row, col) < n,
            "ndarray: index {:?} is out of bounds for array of shape {}",
            [row, col],
            n
        );
        match row - col {
            0 => &self.d[row as usize],
            1 => &self.dl[col as usize],
            -1 => &self.du[row as usize],
            _ => panic!(
                "ndarray-linalg::tridiagonal: index {:?} is not tridiagonal element",
                [row, col]
            ),
        }
    }
}

impl<A: Scalar> Index<[i32; 2]> for Tridiagonal<A> {
    type Output = A;
    #[inline]
    fn index(&self, [row, col]: [i32; 2]) -> &A {
        &self[(row, col)]
    }
}

impl<A: Scalar> IndexMut<(i32, i32)> for Tridiagonal<A> {
    #[inline]
    fn index_mut(&mut self, (row, col): (i32, i32)) -> &mut A {
        let (n, _) = self.l.size();
        assert!(
            std::cmp::max(row, col) < n,
            "ndarray: index {:?} is out of bounds for array of shape {}",
            [row, col],
            n
        );
        match row - col {
            0 => &mut self.d[row as usize],
            1 => &mut self.dl[col as usize],
            -1 => &mut self.du[row as usize],
            _ => panic!(
                "ndarray-linalg::tridiagonal: index {:?} is not tridiagonal element",
                [row, col]
            ),
        }
    }
}

impl<A: Scalar> IndexMut<[i32; 2]> for Tridiagonal<A> {
    #[inline]
    fn index_mut(&mut self, [row, col]: [i32; 2]) -> &mut A {
        &mut self[(row, col)]
    }
}

/// Wraps `*gttrf`, `*gtcon` and `*gttrs`
pub trait Tridiagonal_: Scalar + Sized {
    /// Computes the LU factorization of a tridiagonal `m x n` matrix `a` using
    /// partial pivoting with row interchanges.
    unsafe fn lu_tridiagonal(a: Tridiagonal<Self>) -> Result<LUFactorizedTridiagonal<Self>>;

    unsafe fn rcond_tridiagonal(lu: &LUFactorizedTridiagonal<Self>) -> Result<Self::Real>;

    unsafe fn solve_tridiagonal(
        lu: &LUFactorizedTridiagonal<Self>,
        bl: MatrixLayout,
        t: Transpose,
        b: &mut [Self],
    ) -> Result<()>;
}

macro_rules! impl_tridiagonal {
    (@real, $scalar:ty, $gttrf:path, $gtcon:path, $gttrs:path) => {
        impl_tridiagonal!(@body, $scalar, $gttrf, $gtcon, $gttrs, iwork);
    };
    (@complex, $scalar:ty, $gttrf:path, $gtcon:path, $gttrs:path) => {
        impl_tridiagonal!(@body, $scalar, $gttrf, $gtcon, $gttrs, );
    };
    (@body, $scalar:ty, $gttrf:path, $gtcon:path, $gttrs:path, $($iwork:ident)*) => {
        impl Tridiagonal_ for $scalar {
            unsafe fn lu_tridiagonal(
                mut a: Tridiagonal<Self>,
            ) -> Result<LUFactorizedTridiagonal<Self>> {
                let (n, _) = a.l.size();
                let mut du2 = vec![Zero::zero(); (n - 2) as usize];
                let mut ipiv = vec![0; n as usize];
                // We have to calc one-norm before LU factorization
                let a_opnorm_one = a.opnorm_one();
                let mut info = 0;
                $gttrf(
                    n, &mut a.dl, &mut a.d, &mut a.du, &mut du2, &mut ipiv, &mut info,
                );
                info.as_lapack_result()?;
                Ok(LUFactorizedTridiagonal {
                    a,
                    du2,
                    ipiv,
                    a_opnorm_one,
                })
            }

            unsafe fn rcond_tridiagonal(lu: &LUFactorizedTridiagonal<Self>) -> Result<Self::Real> {
                let (n, _) = lu.a.l.size();
                let ipiv = &lu.ipiv;
                let mut work = vec![Self::zero(); 2 * n as usize];
                $(
                let mut $iwork = vec![0; n as usize];
                )*
                let mut rcond = Self::Real::zero();
                let mut info = 0;
                $gtcon(
                    NormType::One as u8,
                    n,
                    &lu.a.dl,
                    &lu.a.d,
                    &lu.a.du,
                    &lu.du2,
                    ipiv,
                    lu.a_opnorm_one,
                    &mut rcond,
                    &mut work,
                    $(&mut $iwork,)*
                    &mut info,
                );
                info.as_lapack_result()?;
                Ok(rcond)
            }

            unsafe fn solve_tridiagonal(
                lu: &LUFactorizedTridiagonal<Self>,
                bl: MatrixLayout,
                t: Transpose,
                b: &mut [Self],
            ) -> Result<()> {
                let (n, _) = lu.a.l.size();
                let (_, nrhs) = bl.size();
                let ipiv = &lu.ipiv;
                let ldb = bl.lda();
                let mut info = 0;
                $gttrs(
                    t as u8, n, nrhs, &lu.a.dl, &lu.a.d, &lu.a.du, &lu.du2, ipiv, b, ldb, &mut info,
                );
                info.as_lapack_result()?;
                Ok(())
            }
        }
    };
} // impl_tridiagonal!

impl_tridiagonal!(@real, f64, lapack::dgttrf, lapack::dgtcon, lapack::dgttrs);
impl_tridiagonal!(@real, f32, lapack::sgttrf, lapack::sgtcon, lapack::sgttrs);
impl_tridiagonal!(@complex, c64, lapack::zgttrf, lapack::zgtcon, lapack::zgttrs);
impl_tridiagonal!(@complex, c32, lapack::cgttrf, lapack::cgtcon, lapack::cgttrs);
<commit_msg>Transpose if C-contiguous<commit_after>//! Implement linear solver using LU decomposition
//! for tridiagonal matrix

use super::*;
use crate::{error::*, layout::*};
use cauchy::*;
use num_traits::Zero;
use std::ops::{Index, IndexMut};

/// Represents a tridiagonal matrix as 3 one-dimensional vectors.
///
/// ```text
/// [d0, u1,  0,   ...,       0,
///  l1, d1, u2,            ...,
///   0, l2, d2,
///  ...           ...,  u{n-1},
///   0,  ...,  l{n-1},  d{n-1},]
/// ```
#[derive(Clone, PartialEq)]
pub struct Tridiagonal<A: Scalar> {
    /// layout of raw matrix
    pub l: MatrixLayout,
    /// (n-1) sub-diagonal elements of matrix.
    pub dl: Vec<A>,
    /// (n) diagonal elements of matrix.
    pub d: Vec<A>,
    /// (n-1) super-diagonal elements of matrix.
    pub du: Vec<A>,
}

impl<A: Scalar> Tridiagonal<A> {
    fn opnorm_one(&self) -> A::Real {
        let mut col_sum: Vec<A::Real> = self.d.iter().map(|val| val.abs()).collect();
        for i in 0..col_sum.len() {
            if i < self.dl.len() {
                col_sum[i] += self.dl[i].abs();
            }
            if i > 0 {
                col_sum[i] += self.du[i - 1].abs();
            }
        }
        let mut max = A::Real::zero();
        for &val in &col_sum {
            if max < val {
                max = val;
            }
        }
        max
    }
}

/// Represents the LU factorization of a tridiagonal matrix `A` as `A = P*L*U`.
#[derive(Clone, PartialEq)]
pub struct LUFactorizedTridiagonal<A: Scalar> {
    /// A tridiagonal matrix which consists of
    /// - l : layout of raw matrix
    /// - dl: (n-1) multipliers that define the matrix L.
    /// - d : (n) diagonal elements of the upper triangular matrix U.
    /// - du: (n-1) elements of the first super-diagonal of U.
    pub a: Tridiagonal<A>,
    /// (n-2) elements of the second super-diagonal of U.
    pub du2: Vec<A>,
    /// The pivot indices that define the permutation matrix `P`.
    pub ipiv: Pivot,

    a_opnorm_one: A::Real,
}

impl<A: Scalar> Index<(i32, i32)> for Tridiagonal<A> {
    type Output = A;
    #[inline]
    fn index(&self, (row, col): (i32, i32)) -> &A {
        let (n, _) = self.l.size();
        assert!(
            std::cmp::max(row, col) < n,
            "ndarray: index {:?} is out of bounds for array of shape {}",
            [row, col],
            n
        );
        match row - col {
            0 => &self.d[row as usize],
            1 => &self.dl[col as usize],
            -1 => &self.du[row as usize],
            _ => panic!(
                "ndarray-linalg::tridiagonal: index {:?} is not tridiagonal element",
                [row, col]
            ),
        }
    }
}

impl<A: Scalar> Index<[i32; 2]> for Tridiagonal<A> {
    type Output = A;
    #[inline]
    fn index(&self, [row, col]: [i32; 2]) -> &A {
        &self[(row, col)]
    }
}

impl<A: Scalar> IndexMut<(i32, i32)> for Tridiagonal<A> {
    #[inline]
    fn index_mut(&mut self, (row, col): (i32, i32)) -> &mut A {
        let (n, _) = self.l.size();
        assert!(
            std::cmp::max(row, col) < n,
            "ndarray: index {:?} is out of bounds for array of shape {}",
            [row, col],
            n
        );
        match row - col {
            0 => &mut self.d[row as usize],
            1 => &mut self.dl[col as usize],
            -1 => &mut self.du[row as usize],
            _ => panic!(
                "ndarray-linalg::tridiagonal: index {:?} is not tridiagonal element",
                [row, col]
            ),
        }
    }
}

impl<A: Scalar> IndexMut<[i32; 2]> for Tridiagonal<A> {
    #[inline]
    fn index_mut(&mut self, [row, col]: [i32; 2]) -> &mut A {
        &mut self[(row, col)]
    }
}

/// Wraps `*gttrf`, `*gtcon` and `*gttrs`
pub trait Tridiagonal_: Scalar + Sized {
    /// Computes the LU factorization of a tridiagonal `m x n` matrix `a` using
    /// partial pivoting with row interchanges.
    unsafe fn lu_tridiagonal(a: Tridiagonal<Self>) -> Result<LUFactorizedTridiagonal<Self>>;

    unsafe fn rcond_tridiagonal(lu: &LUFactorizedTridiagonal<Self>) -> Result<Self::Real>;

    unsafe fn solve_tridiagonal(
        lu: &LUFactorizedTridiagonal<Self>,
        bl: MatrixLayout,
        t: Transpose,
        b: &mut [Self],
    ) -> Result<()>;
}

macro_rules! impl_tridiagonal {
    (@real, $scalar:ty, $gttrf:path, $gtcon:path, $gttrs:path) => {
        impl_tridiagonal!(@body, $scalar, $gttrf, $gtcon, $gttrs, iwork);
    };
    (@complex, $scalar:ty, $gttrf:path, $gtcon:path, $gttrs:path) => {
        impl_tridiagonal!(@body, $scalar, $gttrf, $gtcon, $gttrs, );
    };
    (@body, $scalar:ty, $gttrf:path, $gtcon:path, $gttrs:path, $($iwork:ident)*) => {
        impl Tridiagonal_ for $scalar {
            unsafe fn lu_tridiagonal(
                mut a: Tridiagonal<Self>,
            ) -> Result<LUFactorizedTridiagonal<Self>> {
                let (n, _) = a.l.size();
                let mut du2 = vec![Zero::zero(); (n - 2) as usize];
                let mut ipiv = vec![0; n as usize];
                // We have to calc one-norm before LU factorization
                let a_opnorm_one = a.opnorm_one();
                let mut info = 0;
                $gttrf(
                    n, &mut a.dl, &mut a.d, &mut a.du, &mut du2, &mut ipiv, &mut info,
                );
                info.as_lapack_result()?;
                Ok(LUFactorizedTridiagonal {
                    a,
                    du2,
                    ipiv,
                    a_opnorm_one,
                })
            }

            unsafe fn rcond_tridiagonal(lu: &LUFactorizedTridiagonal<Self>) -> Result<Self::Real> {
                let (n, _) = lu.a.l.size();
                let ipiv = &lu.ipiv;
                let mut work = vec![Self::zero(); 2 * n as usize];
                $(
                let mut $iwork = vec![0; n as usize];
                )*
                let mut rcond = Self::Real::zero();
                let mut info = 0;
                $gtcon(
                    NormType::One as u8,
                    n,
                    &lu.a.dl,
                    &lu.a.d,
                    &lu.a.du,
                    &lu.du2,
                    ipiv,
                    lu.a_opnorm_one,
                    &mut rcond,
                    &mut work,
                    $(&mut $iwork,)*
                    &mut info,
                );
                info.as_lapack_result()?;
                Ok(rcond)
            }

            unsafe fn solve_tridiagonal(
                lu: &LUFactorizedTridiagonal<Self>,
                b_layout: MatrixLayout,
                t: Transpose,
                b: &mut [Self],
            ) -> Result<()> {
                let (n, _) = lu.a.l.size();
                let ipiv = &lu.ipiv;
                // Transpose if b is C-continuous
                let mut b_t = None;
                let b_layout = match b_layout {
                    MatrixLayout::C { .. } => {
                        b_t = Some(vec![Self::zero(); b.len()]);
                        transpose(b_layout, b, b_t.as_mut().unwrap())
                    }
                    MatrixLayout::F { .. } => b_layout,
                };
                let (ldb, nrhs) = b_layout.size();
                let mut info = 0;
                $gttrs(
                    t as u8,
                    n,
                    nrhs,
                    &lu.a.dl,
                    &lu.a.d,
                    &lu.a.du,
                    &lu.du2,
                    ipiv,
                    b_t.as_mut().map(|v| v.as_mut_slice()).unwrap_or(b),
                    ldb,
                    &mut info,
                );
                info.as_lapack_result()?;
                if let Some(b_t) = b_t {
                    transpose(b_layout, &b_t, b);
                }
                Ok(())
            }
        }
    };
} // impl_tridiagonal!

impl_tridiagonal!(@real, f64, lapack::dgttrf, lapack::dgtcon, lapack::dgttrs);
impl_tridiagonal!(@real, f32, lapack::sgttrf, lapack::sgtcon, lapack::sgttrs);
impl_tridiagonal!(@complex, c64, lapack::zgttrf, lapack::zgtcon, lapack::zgttrs);
impl_tridiagonal!(@complex, c32, lapack::cgttrf, lapack::cgtcon, lapack::cgttrs);
<|endoftext|>


<commit_before>use std::io;
use std::io::BufRead;

fn stock_maximize(stock_values: &Vec<i64>) -> i64 {
    let mut money = 0i64;
    let mut current_max = *stock_values.last().unwrap();
    for i in (0..stock_values.len()).rev() {
        if stock_values[i] <= current_max {
            money += current_max - stock_values[i];
        } else {
            current_max = stock_values[i];
        }
    }
    money
}

#[allow(dead_code)]
fn main() {
    let stdin = io::stdin();
    let mut lines = stdin.lock().lines();
    let first_line = lines.next().unwrap().unwrap();
    let t = first_line.trim().parse::<usize>().unwrap();
    let mut lines_enum = lines.take(t*2);
    let mut results = Vec::<i64>::with_capacity(t);
    while let Some(line_count) = lines_enum.next() {
        let count = line_count.unwrap().trim().parse::<usize>().unwrap();
        let line_values = lines_enum.next().unwrap().unwrap();
        let values: Vec<i64> = line_values.trim().split(' ')
            .map(|value| value.parse::<i64>().unwrap())
            .take(count)
            .collect();
        results.push(stock_maximize(&values));
    }

    for result in results.iter() {
        println!("{}", result);
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn sample1() {
        assert_eq!(0, super::stock_maximize(&vec![5, 3, 2]));
    }

    #[test]
    fn sample2() {
        assert_eq!(197, super::stock_maximize(&vec![1, 2, 100]));
    }

    #[test]
    fn sample3() {
        assert_eq!(3, super::stock_maximize(&vec![1, 3, 1, 2]));
    }

    //&(1..250).collect()
    #[test]
    fn big() {
        super::stock_maximize(&(1..40000).collect());
    }
}<commit_msg>use iterator for stock maximize<commit_after>use std::io;
use std::io::BufRead;

fn stock_maximize(stock_values: &Vec<i64>) -> i64 {
    let mut money = 0i64;
    let mut current_max = *stock_values.last().unwrap();
    for stock_values in stock_values.iter().rev() {
        if *stock_values <= current_max {
            money += current_max - stock_values;
        } else {
            current_max = *stock_values;
        }
    }
    money
}

#[allow(dead_code)]
fn main() {
    let stdin = io::stdin();
    let mut lines = stdin.lock().lines();
    let first_line = lines.next().unwrap().unwrap();
    let t = first_line.trim().parse::<usize>().unwrap();
    let mut lines_enum = lines.take(t*2);
    let mut results = Vec::<i64>::with_capacity(t);
    while let Some(line_count) = lines_enum.next() {
        let count = line_count.unwrap().trim().parse::<usize>().unwrap();
        let line_values = lines_enum.next().unwrap().unwrap();
        let values: Vec<i64> = line_values.trim().split(' ')
            .map(|value| value.parse::<i64>().unwrap())
            .take(count)
            .collect();
        results.push(stock_maximize(&values));
    }

    for result in results.iter() {
        println!("{}", result);
    }
}

#[cfg(test)]
mod tests {
    #[test]
    fn sample1() {
        assert_eq!(0, super::stock_maximize(&vec![5, 3, 2]));
    }

    #[test]
    fn sample2() {
        assert_eq!(197, super::stock_maximize(&vec![1, 2, 100]));
    }

    #[test]
    fn sample3() {
        assert_eq!(3, super::stock_maximize(&vec![1, 3, 1, 2]));
    }

    //&(1..250).collect()
    #[test]
    fn big() {
        super::stock_maximize(&(1..40000).collect());
    }
}<|endoftext|>


<commit_before>use std::time::Duration;

use serde::{Deserialize, Serialize};

use crate::components::*;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ServerMessage {
    /// Server time since session start.
    pub session_time: Duration,
    /// List of new entities.
    pub new_entities: Vec<Vec<Component>>,
    /// List of updated components.
    pub changed_components: Vec<(GameEntityId, Component)>,
}

impl ServerMessage {
    pub fn new(session_time: Duration) -> ServerMessage {
        ServerMessage {
            session_time: session_time.clone(),
            new_entities: Vec::new(),
            changed_components: Vec::new(),
        }
    }
}
<commit_msg>Move session_time into ServerMessage<commit_after>use std::time::Duration;

use serde::{Deserialize, Serialize};

use crate::components::*;

#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
pub struct ServerMessage {
    /// Server time since session start.
    pub session_time: Duration,
    /// List of new entities.
    pub new_entities: Vec<Vec<Component>>,
    /// List of updated components.
    pub changed_components: Vec<(GameEntityId, Component)>,
}

impl ServerMessage {
    pub fn new(session_time: Duration) -> ServerMessage {
        ServerMessage {
            session_time,
            new_entities: Vec::new(),
            changed_components: Vec::new(),
        }
    }
}
<|endoftext|>


<commit_before>fn main() {
    // a = (m^2 - n^2) ·d
    // b = 2·m·n·d
    // c = (m^2 + n^2) ·d
    // m > n
    for m in 2..Math.sqrt(500) {
        for k in m + 1..500 / m {
            // gcd(m, n) == 1 => gcd(m, m + n) == 1 => gcd(m, k) == 1
            if (500 / m) % k == 0 && 1 == gcd(m, k) {
                println!("a: {}, b: {}, c: {}", a, b ,c);
            }
        }
    }
}
<commit_msg>add m limit<commit_after>fn main() {
    // let a = (m^2 - n^2) ·d
    // let b = 2·m·n·d
    // let c = (m^2 + n^2) ·d
    // m > n && gcd(m, n) == 1

    /* (1)
     * 2 x d x m x (m + n) = s
     *     => m x (m + n) = s / (2 x d)
     *     => m^2 < s / (2 x d)
     *     => m^2 < s / 2
     *     => m <= round((s / 2)^0.5)
     * (2)
     * m > n > 0
     *     => m >= 2
     * (3)
     * s / 2 = m x d x (m + n)
     *     => (s / 2) % m == 0
     */
    for m in 2..round(Math.sqrt(500)) {
        if s / 2 % m == 0 {
            /*
             * (1)
             * k = m + n
             *     => k % 2 == 1
             */
            for k in m + 1..500 / m {
                // gcd(m, n) == 1 => gcd(m, m + n) == 1 => gcd(m, k) == 1
                if (500 / m) % k == 0 && 1 == gcd(m, k) {
                    println!("a: {}, b: {}, c: {}", a, b ,c);
                }
            }
        }
    }
}
<|endoftext|>