<commit_before>//! Define trait for general matrix

use std::cmp::min;
use ndarray::prelude::*;
use ndarray::LinalgScalar;
use lapack::c::Layout;

use error::LapackError;
use qr::ImplQR;
use svd::ImplSVD;
use norm::ImplNorm;
use solve::ImplSolve;

/// Methods for general matrices
pub trait Matrix: Sized {
    type Scalar;
    type Vector;
    type Permutator;
    /// number of (rows, columns)
    fn size(&self) -> (usize, usize);
    /// Layout (C/Fortran) of matrix
    fn layout(&self) -> Layout;
    /// Operator norm for L-1 norm
    fn norm_1(&self) -> Self::Scalar;
    /// Operator norm for L-inf norm
    fn norm_i(&self) -> Self::Scalar;
    /// Frobenius norm
    fn norm_f(&self) -> Self::Scalar;
    /// singular-value decomposition (SVD)
    fn svd(self) -> Result<(Self, Self::Vector, Self), LapackError>;
    /// QR decomposition
    fn qr(self) -> Result<(Self, Self), LapackError>;
    /// LU decomposition
    fn lu(self) -> Result<(Self::Permutator, Self, Self), LapackError>;
    /// permutate matrix
    fn permutate_column(self, p: &Self::Permutator) -> Self;
    /// permutate matrix
    fn permutate_row(self, p: &Self::Permutator) -> Self;
}

impl<A> Matrix for Array<A, (Ix, Ix)>
    where A: ImplQR + ImplSVD + ImplNorm + ImplSolve + LinalgScalar
{
    type Scalar = A;
    type Vector = Array<A, Ix>;
    type Permutator = Vec<i32>;

    fn size(&self) -> (usize, usize) {
        (self.rows(), self.cols())
    }
    fn layout(&self) -> Layout {
        let strides = self.strides();
        if strides[0] < strides[1] {
            Layout::ColumnMajor
        } else {
            Layout::RowMajor
        }
    }
    fn norm_1(&self) -> Self::Scalar {
        let (m, n) = self.size();
        let strides = self.strides();
        if strides[0] > strides[1] {
            ImplNorm::norm_i(n, m, self.clone().into_raw_vec())
        } else {
            ImplNorm::norm_1(m, n, self.clone().into_raw_vec())
        }
    }
    fn norm_i(&self) -> Self::Scalar {
        let (m, n) = self.size();
        let strides = self.strides();
        if strides[0] > strides[1] {
            ImplNorm::norm_1(n, m, self.clone().into_raw_vec())
        } else {
            ImplNorm::norm_i(m, n, self.clone().into_raw_vec())
        }
    }
    fn norm_f(&self) -> Self::Scalar {
        let (m, n) = self.size();
        ImplNorm::norm_f(m, n, self.clone().into_raw_vec())
    }
    fn svd(self) -> Result<(Self, Self::Vector, Self), LapackError> {
        let strides = self.strides();
        let (m, n) = if strides[0] > strides[1] {
            self.size()
        } else {
            let (n, m) = self.size();
            (m, n)
        };
        let (u, s, vt) = try!(ImplSVD::svd(m, n, self.clone().into_raw_vec()));
        let sv = Array::from_vec(s);
        if strides[0] > strides[1] {
            let ua = Array::from_vec(u).into_shape((n, n)).unwrap();
            let va = Array::from_vec(vt).into_shape((m, m)).unwrap();
            Ok((va, sv, ua))
        } else {
            let ua = Array::from_vec(u).into_shape((n, n)).unwrap().reversed_axes();
            let va = Array::from_vec(vt).into_shape((m, m)).unwrap().reversed_axes();
            Ok((ua, sv, va))
        }
    }
    fn qr(self) -> Result<(Self, Self), LapackError> {
        let (n, m) = self.size();
        let strides = self.strides();
        let k = min(n, m);
        let (q, r) = if strides[0] < strides[1] {
            try!(ImplQR::qr(m, n, self.clone().into_raw_vec()))
        } else {
            try!(ImplQR::lq(n, m, self.clone().into_raw_vec()))
        };
        let (qa, ra) = if strides[0] < strides[1] {
            (Array::from_vec(q).into_shape((m, n)).unwrap().reversed_axes(),
             Array::from_vec(r).into_shape((m, n)).unwrap().reversed_axes())
        } else {
            (Array::from_vec(q).into_shape((n, m)).unwrap(),
             Array::from_vec(r).into_shape((n, m)).unwrap())
        };
        let qm = if m > k {
            let (qsl, _) = qa.view().split_at(Axis(1), k);
            qsl.to_owned()
        } else {
            qa
        };
        let mut rm = if n > k {
            let (rsl, _) = ra.view().split_at(Axis(0), k);
            rsl.to_owned()
        } else {
            ra
        };
        for ((i, j), val) in rm.indexed_iter_mut() {
            if i > j {
                *val = A::zero();
            }
        }
        Ok((qm, rm))
    }
    fn lu(self) -> Result<(Self::Permutator, Self, Self), LapackError> {
        let (n, m) = self.size();
        let (p, l) = try!(ImplSolve::lu(self.layout(), n, m, self.clone().into_raw_vec()));
        let mut lm = Array::from_vec(l).into_shape((m, n)).unwrap();
        let mut um = Array::zeros((n, m));
        for ((i, j), val) in um.indexed_iter_mut() {
            if i < j {
                *val = lm[(i, j)];
            } else if i == j {
                *val = A::one();
            }
        }
        for ((i, j), val) in lm.indexed_iter_mut() {
            if i < j {
                *val = A::zero();
            }
        }
        Ok((p, um.reversed_axes(), lm.reversed_axes()))
    }
    fn permutate_column(self, p: &Self::Permutator) -> Self {
        let (n, m) = self.size();
        let pd = ImplSolve::permutate_column(self.layout(), n, m, self.clone().into_raw_vec(), p);
        match self.layout() {
            Layout::ColumnMajor => Array::from_vec(pd).into_shape((m, n)).unwrap().reversed_axes(),
            Layout::RowMajor => Array::from_vec(pd).into_shape((m, n)).unwrap(),
        }
    }
    fn permutate_row(self, p: &Self::Permutator) -> Self {
        let (n, m) = self.size();
        let pd = ImplSolve::permutate_column(self.layout(), m, n, self.clone().into_raw_vec(), p);
        Array::from_vec(pd).into_shape((n, m)).unwrap()
    }
}
<commit_msg>Split Column/Row major codes<commit_after>//! Define trait for general matrix

use std::cmp::min;
use ndarray::prelude::*;
use ndarray::LinalgScalar;
use lapack::c::Layout;

use error::LapackError;
use qr::ImplQR;
use svd::ImplSVD;
use norm::ImplNorm;
use solve::ImplSolve;

/// Methods for general matrices
pub trait Matrix: Sized {
    type Scalar;
    type Vector;
    type Permutator;
    /// number of (rows, columns)
    fn size(&self) -> (usize, usize);
    /// Layout (C/Fortran) of matrix
    fn layout(&self) -> Layout;
    /// Operator norm for L-1 norm
    fn norm_1(&self) -> Self::Scalar;
    /// Operator norm for L-inf norm
    fn norm_i(&self) -> Self::Scalar;
    /// Frobenius norm
    fn norm_f(&self) -> Self::Scalar;
    /// singular-value decomposition (SVD)
    fn svd(self) -> Result<(Self, Self::Vector, Self), LapackError>;
    /// QR decomposition
    fn qr(self) -> Result<(Self, Self), LapackError>;
    /// LU decomposition
    fn lu(self) -> Result<(Self::Permutator, Self, Self), LapackError>;
    /// permutate matrix
    fn permutate_column(self, p: &Self::Permutator) -> Self;
    /// permutate matrix
    fn permutate_row(self, p: &Self::Permutator) -> Self;
}

impl<A> Matrix for Array<A, (Ix, Ix)>
    where A: ImplQR + ImplSVD + ImplNorm + ImplSolve + LinalgScalar
{
    type Scalar = A;
    type Vector = Array<A, Ix>;
    type Permutator = Vec<i32>;

    fn size(&self) -> (usize, usize) {
        (self.rows(), self.cols())
    }
    fn layout(&self) -> Layout {
        let strides = self.strides();
        if strides[0] < strides[1] {
            Layout::ColumnMajor
        } else {
            Layout::RowMajor
        }
    }
    fn norm_1(&self) -> Self::Scalar {
        let (m, n) = self.size();
        let strides = self.strides();
        if strides[0] > strides[1] {
            ImplNorm::norm_i(n, m, self.clone().into_raw_vec())
        } else {
            ImplNorm::norm_1(m, n, self.clone().into_raw_vec())
        }
    }
    fn norm_i(&self) -> Self::Scalar {
        let (m, n) = self.size();
        let strides = self.strides();
        if strides[0] > strides[1] {
            ImplNorm::norm_1(n, m, self.clone().into_raw_vec())
        } else {
            ImplNorm::norm_i(m, n, self.clone().into_raw_vec())
        }
    }
    fn norm_f(&self) -> Self::Scalar {
        let (m, n) = self.size();
        ImplNorm::norm_f(m, n, self.clone().into_raw_vec())
    }
    fn svd(self) -> Result<(Self, Self::Vector, Self), LapackError> {
        let strides = self.strides();
        let (m, n) = if strides[0] > strides[1] {
            self.size()
        } else {
            let (n, m) = self.size();
            (m, n)
        };
        let (u, s, vt) = try!(ImplSVD::svd(m, n, self.clone().into_raw_vec()));
        let sv = Array::from_vec(s);
        if strides[0] > strides[1] {
            let ua = Array::from_vec(u).into_shape((n, n)).unwrap();
            let va = Array::from_vec(vt).into_shape((m, m)).unwrap();
            Ok((va, sv, ua))
        } else {
            let ua = Array::from_vec(u).into_shape((n, n)).unwrap().reversed_axes();
            let va = Array::from_vec(vt).into_shape((m, m)).unwrap().reversed_axes();
            Ok((ua, sv, va))
        }
    }
    fn qr(self) -> Result<(Self, Self), LapackError> {
        let (n, m) = self.size();
        let strides = self.strides();
        let k = min(n, m);
        let (q, r) = if strides[0] < strides[1] {
            try!(ImplQR::qr(m, n, self.clone().into_raw_vec()))
        } else {
            try!(ImplQR::lq(n, m, self.clone().into_raw_vec()))
        };
        let (qa, ra) = if strides[0] < strides[1] {
            (Array::from_vec(q).into_shape((m, n)).unwrap().reversed_axes(),
             Array::from_vec(r).into_shape((m, n)).unwrap().reversed_axes())
        } else {
            (Array::from_vec(q).into_shape((n, m)).unwrap(),
             Array::from_vec(r).into_shape((n, m)).unwrap())
        };
        let qm = if m > k {
            let (qsl, _) = qa.view().split_at(Axis(1), k);
            qsl.to_owned()
        } else {
            qa
        };
        let mut rm = if n > k {
            let (rsl, _) = ra.view().split_at(Axis(0), k);
            rsl.to_owned()
        } else {
            ra
        };
        for ((i, j), val) in rm.indexed_iter_mut() {
            if i > j {
                *val = A::zero();
            }
        }
        Ok((qm, rm))
    }
    fn lu(self) -> Result<(Self::Permutator, Self, Self), LapackError> {
        let (n, m) = self.size();
        let (p, l) = try!(ImplSolve::lu(self.layout(), n, m, self.clone().into_raw_vec()));
        let mut lm = Array::from_vec(l).into_shape((m, n)).unwrap();
        let mut um = Array::zeros((n, m));
        match self.layout() {
            Layout::ColumnMajor => {
                for ((i, j), val) in um.indexed_iter_mut() {
                    if i < j {
                        *val = lm[(i, j)];
                    } else if i == j {
                        *val = A::one();
                    }
                }
                for ((i, j), val) in lm.indexed_iter_mut() {
                    if i < j {
                        *val = A::zero();
                    }
                }
                Ok((p, um.reversed_axes(), lm.reversed_axes()))
            }
            Layout::RowMajor => {
                for ((i, j), val) in um.indexed_iter_mut() {
                    if i > j {
                        *val = lm[(i, j)];
                    } else if i == j {
                        *val = A::one();
                    }
                }
                for ((i, j), val) in lm.indexed_iter_mut() {
                    if i > j {
                        *val = A::zero();
                    }
                }
                Ok((p, lm, um))
            }
        }
    }
    fn permutate_column(self, p: &Self::Permutator) -> Self {
        let (n, m) = self.size();
        let pd = ImplSolve::permutate_column(self.layout(), n, m, self.clone().into_raw_vec(), p);
        match self.layout() {
            Layout::ColumnMajor => Array::from_vec(pd).into_shape((m, n)).unwrap().reversed_axes(),
            Layout::RowMajor => Array::from_vec(pd).into_shape((m, n)).unwrap(),
        }
    }
    fn permutate_row(self, p: &Self::Permutator) -> Self {
        let (n, m) = self.size();
        let pd = ImplSolve::permutate_column(self.layout(), m, n, self.clone().into_raw_vec(), p);
        Array::from_vec(pd).into_shape((n, m)).unwrap()
    }
}
<|endoftext|>


<commit_before>// NES MEMORY MAP
// http://wiki.nesdev.com/w/index.php/Sample_RAM_map
//
// Address      Size    Description
// ---------------------------------
// $0000-$07FF	$0800	2KB internal RAM
// $0800-$0FFF	$0800	Mirrors of $0000-$07FF
// $1000-$17FF	$0800
// $1800-$1FFF	$0800
// $2000-$2007	$0008	NES PPU registers
// $2008-$3FFF	$1FF8	Mirrors of $2000-2007 (repeats every 8 bytes)
// $4000-$401F	$0020	NES APU and I/O registers
// $4020-$FFFF	$BFE0	Cartridge space: PRG ROM, PRG RAM, and mapper registers (See Note)

const ADDRESSABLE_MEMORY: usize = 0xFFFF;

pub struct Memory {
  addr:[u8; ADDRESSABLE_MEMORY]
}

impl Memory {
  pub fn new() -> Memory {
    Memory {
      addr: [0; ADDRESSABLE_MEMORY]
    }
  }

  pub fn store(&mut self, addr: usize, data: u8) -> Result<(), &'static str> {
    if addr > ADDRESSABLE_MEMORY {
      Err("memory address out of bounds")
    } else {
      self.addr[addr] = data;
      Ok(())
    }
  }

  pub fn load(&mut self, addr: usize) -> Result<u8, &'static str> {
    if addr > ADDRESSABLE_MEMORY {
      Err("memory address out of bounds")
    } else {
      Ok(self.addr[addr])
    }
  }
}

<commit_msg>Better memory map docs<commit_after>// NES MEMORY MAP
// http://emudocs.org/NES/nestech.txt
//
// +---------+-------+-------+-----------------------+
// | Address | Size  | Flags | Description           |
// +---------+-------+-------+-----------------------+
// | $0000   | $800  |       | RAM                   |
// | $0800   | $800  | M     | RAM                   |
// | $1000   | $800  | M     | RAM                   |
// | $1800   | $800  | M     | RAM                   |
// | $2000   | 8     |       | Registers             |
// | $2008   | $1FF8 |  R    | Registers             |
// | $4000   | $20   |       | Registers             |
// | $4020   | $1FDF |       | Expansion ROM         |
// | $6000   | $2000 |       | SRAM                  |
// | $8000   | $4000 |       | PRG-ROM               |
// | $C000   | $4000 |       | PRG-ROM               |
// +---------+-------+-------+-----------------------+
//        Flag Legend: M = Mirror of $0000
//                     R = Mirror of $2000-2008 every 8 bytes
//                         (e.g. $2008=$2000, $2018=$2000, etc.)

const ADDRESSABLE_MEMORY: usize = 0xFFFF;

pub struct Memory {
  addr:[u8; ADDRESSABLE_MEMORY]
}

impl Memory {
  pub fn new() -> Memory {
    Memory {
      addr: [0; ADDRESSABLE_MEMORY]
    }
  }

  pub fn store(&mut self, addr: usize, data: u8) -> Result<(), &'static str> {
    if addr > ADDRESSABLE_MEMORY {
      Err("memory address out of bounds")
    } else {
      self.addr[addr] = data;
      Ok(())
    }
  }

  pub fn load(&mut self, addr: usize) -> Result<u8, &'static str> {
    if addr > ADDRESSABLE_MEMORY {
      Err("memory address out of bounds")
    } else {
      Ok(self.addr[addr])
    }
  }
}

<|endoftext|>


<commit_before>use rustc_serialize::json::{self, Json, Object};
use rustc_serialize::base64::{self, ToBase64};
use amqp::protocol::basic::{Deliver, BasicProperties};
use amqp::{Table, TableEntry};
use error::RbtError;

#[derive(RustcEncodable)]
struct MsgDeliver {
    consumer_tag: String,
    delivery_tag: u64,
    redelivered: bool,
    exchange: String,
    routing_key: String,
}

#[derive(RustcEncodable)]
struct MsgProps {
    content_type: String,
    headers: Object,
}

#[derive(RustcEncodable)]
struct Msg {
    deliver: MsgDeliver,
    props: MsgProps,
    data: Json,
}

pub fn build_output(info:bool, deliver:&Deliver,
                    props:&BasicProperties, body:Vec<u8>) -> Result<Vec<u8>,RbtError> {
    if info {

        // delivery info
        let mdel = MsgDeliver {
            consumer_tag:deliver.consumer_tag.clone(),
            delivery_tag:deliver.delivery_tag.clone(),
            redelivered:deliver.redelivered.clone(),
            exchange:deliver.exchange.clone(),
            routing_key:deliver.routing_key.clone(),
        };

        let content_type = props.content_type.clone().unwrap_or(String::from(""));

        // properties
        let mut mprops = MsgProps {
            content_type:content_type.clone(),
            headers: Object::new(),
        };

        if let Some(ref table) = props.headers {
            mprops.headers = table_to_json(table)?;
        }

        // the body
        let data = figure_out_body(content_type, body)?;

        // and put it together
        let msg = Msg {
            deliver:mdel,
            props:mprops,
            data:data,
        };

        // encode
        let js = json::as_pretty_json(&msg);

        // convert to bytes
        Ok(js.to_string().as_bytes().to_owned())

    } else {

        let content_type = props.content_type.clone().unwrap_or(String::from(""));

        match content_type.as_ref() {
            "application/json" => {
                // interpret body so we can pretty print it
                let body = figure_out_body(content_type, body)?;

                // encode back as pretty
                let js = json::as_pretty_json(&body);

                // convert to bytes
                Ok(js.to_string().as_bytes().to_owned())
            },

            // just return untranslated bytes
            _ => Ok(body)
        }

    }
}

fn figure_out_body(content_type:String, body:Vec<u8>) -> Result<Json,RbtError> {

    // depending on content type, do something
    match content_type.as_ref() {
        "application/json" => Ok(Json::from_str(&String::from_utf8(body)?)?),
        _ => Ok(match content_type.find("text/") {
            Some(_) => Json::String(String::from_utf8(body)?),
            _ => Json::String(body.to_base64(base64::STANDARD))
        })
    }

}

fn table_to_json(table:&Table) -> Result<Object,String> {
    let mut ret = Object::new();
    for (skey, entry) in table {
        let key = skey.clone().to_string();
        let val = entry_to_json(&entry)?;
        ret.insert(key, val);
    }
    Ok(ret)
}

fn entry_to_json(entry:&TableEntry) -> Result<Json,String> {
    match *entry {
        TableEntry::Bool(v)           => Ok(Json::Boolean(v)),
        TableEntry::ShortShortInt(v)  => Ok(Json::I64(v as i64)),
        TableEntry::ShortShortUint(v) => Ok(Json::U64(v as u64)),
        TableEntry::ShortInt(v)       => Ok(Json::I64(v as i64)),
        TableEntry::ShortUint(v)      => Ok(Json::U64(v as u64)),
        TableEntry::LongInt(v)        => Ok(Json::I64(v as i64)),
        TableEntry::LongUint(v)       => Ok(Json::U64(v as u64)),
        TableEntry::LongLongInt(v)    => Ok(Json::I64(v)),
        TableEntry::LongLongUint(v)   => Ok(Json::U64(v)),
        TableEntry::Float(v)          => Ok(Json::F64(v as f64)),
        TableEntry::Double(v)         => Ok(Json::F64(v)),
        TableEntry::LongString(ref v) => Ok(Json::String(v.clone())),
        TableEntry::Void              => Ok(Json::Null),
        TableEntry::FieldTable(ref v) => Ok(Json::Object(table_to_json(&v)?)),
        TableEntry::FieldArray(ref vs) => {
            let mut ret:Vec<Json> = Vec::new();
            for v in vs { ret.push(entry_to_json(v)?) }
            Ok(Json::Array(ret))
        },
        TableEntry::Timestamp(v)      => Ok(Json::U64(v as u64)), // maybe string date?
        TableEntry::DecimalValue(decimals, v) => {
            let ten:f64 = (10 as u64).pow(decimals as u32) as f64;
            let dec:f64 = (v as f64) / ten;
            Ok(Json::F64(dec))
        },
        //_                             => Err(format!("Cant translate {:?}", entry)),
        // TableEntry::ShortString(ref v) => Ok(Json::String(v.clone())),
    }
}
<commit_msg>result not needed<commit_after>use rustc_serialize::json::{self, Json, Object};
use rustc_serialize::base64::{self, ToBase64};
use amqp::protocol::basic::{Deliver, BasicProperties};
use amqp::{Table, TableEntry};
use error::RbtError;

#[derive(RustcEncodable)]
struct MsgDeliver {
    consumer_tag: String,
    delivery_tag: u64,
    redelivered: bool,
    exchange: String,
    routing_key: String,
}

#[derive(RustcEncodable)]
struct MsgProps {
    content_type: String,
    headers: Object,
}

#[derive(RustcEncodable)]
struct Msg {
    deliver: MsgDeliver,
    props: MsgProps,
    data: Json,
}

pub fn build_output(info:bool, deliver:&Deliver,
                    props:&BasicProperties, body:Vec<u8>) -> Result<Vec<u8>,RbtError> {
    if info {

        // delivery info
        let mdel = MsgDeliver {
            consumer_tag:deliver.consumer_tag.clone(),
            delivery_tag:deliver.delivery_tag.clone(),
            redelivered:deliver.redelivered.clone(),
            exchange:deliver.exchange.clone(),
            routing_key:deliver.routing_key.clone(),
        };

        let content_type = props.content_type.clone().unwrap_or(String::from(""));

        // properties
        let mut mprops = MsgProps {
            content_type:content_type.clone(),
            headers: Object::new(),
        };

        if let Some(ref table) = props.headers {
            mprops.headers = table_to_json(table);
        }

        // the body
        let data = figure_out_body(content_type, body)?;

        // and put it together
        let msg = Msg {
            deliver:mdel,
            props:mprops,
            data:data,
        };

        // encode
        let js = json::as_pretty_json(&msg);

        // convert to bytes
        Ok(js.to_string().as_bytes().to_owned())

    } else {

        let content_type = props.content_type.clone().unwrap_or(String::from(""));

        match content_type.as_ref() {
            "application/json" => {
                // interpret body so we can pretty print it
                let body = figure_out_body(content_type, body)?;

                // encode back as pretty
                let js = json::as_pretty_json(&body);

                // convert to bytes
                Ok(js.to_string().as_bytes().to_owned())
            },

            // just return untranslated bytes
            _ => Ok(body)
        }

    }
}

fn figure_out_body(content_type:String, body:Vec<u8>) -> Result<Json,RbtError> {

    // depending on content type, do something
    match content_type.as_ref() {
        "application/json" => Ok(Json::from_str(&String::from_utf8(body)?)?),
        _ => Ok(match content_type.find("text/") {
            Some(_) => Json::String(String::from_utf8(body)?),
            _ => Json::String(body.to_base64(base64::STANDARD))
        })
    }

}

fn table_to_json(table:&Table) -> Object {
    let mut ret = Object::new();
    for (skey, entry) in table {
        ret.insert(skey.clone().to_string(), entry_to_json(&entry));
    }
    ret
}

fn entry_to_json(entry:&TableEntry) -> Json {
    match *entry {
        TableEntry::Bool(v)            => Json::Boolean(v),
        TableEntry::ShortShortInt(v)   => Json::I64(v as i64),
        TableEntry::ShortShortUint(v)  => Json::U64(v as u64),
        TableEntry::ShortInt(v)        => Json::I64(v as i64),
        TableEntry::ShortUint(v)       => Json::U64(v as u64),
        TableEntry::LongInt(v)         => Json::I64(v as i64),
        TableEntry::LongUint(v)        => Json::U64(v as u64),
        TableEntry::LongLongInt(v)     => Json::I64(v),
        TableEntry::LongLongUint(v)    => Json::U64(v),
        TableEntry::Float(v)           => Json::F64(v as f64),
        TableEntry::Double(v)          => Json::F64(v),
        TableEntry::LongString(ref v)  => Json::String(v.clone()),
        TableEntry::Void               => Json::Null,
        TableEntry::FieldTable(ref v)  => Json::Object(table_to_json(&v)),
        TableEntry::Timestamp(v)       => Json::U64(v as u64), // maybe string date?
        TableEntry::FieldArray(ref vs) => {
            let mut ret:Vec<Json> = Vec::new();
            for v in vs { ret.push(entry_to_json(v)) }
            Json::Array(ret)
        },
        TableEntry::DecimalValue(decimals, v) => {
            let ten:f64 = (10 as u64).pow(decimals as u32) as f64;
            let dec:f64 = (v as f64) / ten;
            Json::F64(dec)
        },
        //_                             => Err(format!("Cant translate {:?}", entry)),
        // TableEntry::ShortString(ref v) => Ok(Json::String(v.clone())),
    }
}
<|endoftext|>


<commit_before>use tokenizer::Tokenizer;
use event::{Event, Rule};
use variable_mapper::VariableMapper;

pub fn nested<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    nested_inner(&mut vm, &mut parents)
}

pub fn nested_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
       match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = nested_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n\n");
                        children.push_str(&nested_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                current.push_str(&format!("{} ", name));
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!("{{\n  {}: {};", name, value)),
                    _ => properties.push_str(&format!("\n  {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str(" }\n"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str(" }");
                    },
                    (0, _) => {
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str(" }\n");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
        };
        last = token;
    }
    children
}

pub fn compressed<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    compressed_inner(&mut vm, &mut parents)
}

fn compressed_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
         match token.clone() {
             Event::Start(_) => {
                 match children.len() {
                     0 => children = compressed_inner(tokenizer, parents),
                     _ => {
                         children.push_str(&compressed_inner(tokenizer, parents));
                     },
                 };
             },
             Event::Selector(name) => {
                 parents.push((*name).to_string());
                 match last {
                     Event::Selector(_) => current.push_str(&format!(" {}", name)),
                     _ => current.push_str(&format!("{}", name)),
                 }
             },
             Event::Property(name, value) => {
                 match last {
                     Event::Selector(..) => properties.push_str(&format!("{{{}:{}", name, value)),
                     Event::Property(..) => properties.push_str(&format!(";{}:{}", name, value)),
                     _ => properties.push_str(&format!("{}:{}", name, value)),
                 }
             },
             Event::End(_) => {
                 match (properties.len(), children.len()) {
                     (0, 0) => current.push_str("}"),
                     (_, 0) => {
                         current.push_str(&properties);
                         current.push_str("}");
                     },
                     (0, _) => {
                         current.push_str(" ");
                         current.push_str(&children);
                     },
                     (_, _) => {
                         current.push_str(&properties);
                         current.push_str("}");
                         current.push_str(&parents.connect(" "));
                         current.push_str(" ");
                         current.push_str(&children);
                     },
                 }
                 parents.pop();
                 return current
             },
            Event::Variable(..) => unreachable!(),
        };
        last = token;
    }
    children
}

pub fn expanded<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    expanded_inner(&mut vm, &mut parents)
}

fn expanded_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
        match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = expanded_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n\n");
                        children.push_str(&expanded_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                match last {
                    Event::Selector(_) => current.push_str(&format!(" {}", name)),
                    Event::End(_) => current.push_str(&format!("{}", name)),
                    _ => current.push_str(&format!("{}", name)),
                }
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!(" {{\n  {}: {};", name, value)),
                    _ => properties.push_str(&format!("\n  {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str("\n}"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str("\n}");
                    },
                    (0, _) => {
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str("\n}\n");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
        };

        last = token;
    }
    children
}

pub fn compact<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    compact_inner(&mut vm, &mut parents)
}

fn compact_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
        match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = compact_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n");
                        children.push_str(&compact_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                match last {
                    Event::Selector(_) => current.push_str(&format!(" {}", name)),
                    Event::End(_) => current.push_str(&format!("{}", name)),
                    _ => current.push_str(&format!("{}", name)),
                }
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!(" {{ {}: {};", name, value)),
                    _ => properties.push_str(&format!(" {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str(" }"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str(" }\n");
                    },
                    (0, _) => {
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str(" }\n");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
        };
        last = token;
    }
    children
}

pub fn debug(tokenizer: &mut Tokenizer) -> String {
    let mut output = String::new();
    let mut current = String::new();

    while let Some(token) = tokenizer.next() {
        current.push_str(&format!("{:?}\n", token));
        match token {
            Event::End(_) => {
                output.push_str(&current);
                current = String::new();
            },
            _ => {},
        }
    }
    output
}
<commit_msg>Handle the nested part of the nested format<commit_after>use tokenizer::Tokenizer;
use event::{Event, Rule};
use variable_mapper::VariableMapper;

pub fn nested<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    nested_inner(&mut vm, &mut parents)
}

pub fn nested_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
       match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = nested_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n\n");
                        children.push_str(&nested_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                current.push_str(&format!("{} ", name));
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!("{{\n  {}: {};", name, value)),
                    _ => properties.push_str(&format!("\n  {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str(" }\n"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str(" }");
                    },
                    (0, _) => {
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str(" }\n  ");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children.split('\n').collect::<Vec<_>>().connect("\n  "));
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
        };
        last = token;
    }
    children
}

pub fn compressed<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    compressed_inner(&mut vm, &mut parents)
}

fn compressed_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
         match token.clone() {
             Event::Start(_) => {
                 match children.len() {
                     0 => children = compressed_inner(tokenizer, parents),
                     _ => {
                         children.push_str(&compressed_inner(tokenizer, parents));
                     },
                 };
             },
             Event::Selector(name) => {
                 parents.push((*name).to_string());
                 match last {
                     Event::Selector(_) => current.push_str(&format!(" {}", name)),
                     _ => current.push_str(&format!("{}", name)),
                 }
             },
             Event::Property(name, value) => {
                 match last {
                     Event::Selector(..) => properties.push_str(&format!("{{{}:{}", name, value)),
                     Event::Property(..) => properties.push_str(&format!(";{}:{}", name, value)),
                     _ => properties.push_str(&format!("{}:{}", name, value)),
                 }
             },
             Event::End(_) => {
                 match (properties.len(), children.len()) {
                     (0, 0) => current.push_str("}"),
                     (_, 0) => {
                         current.push_str(&properties);
                         current.push_str("}");
                     },
                     (0, _) => {
                         current.push_str(" ");
                         current.push_str(&children);
                     },
                     (_, _) => {
                         current.push_str(&properties);
                         current.push_str("}");
                         current.push_str(&parents.connect(" "));
                         current.push_str(" ");
                         current.push_str(&children);
                     },
                 }
                 parents.pop();
                 return current
             },
            Event::Variable(..) => unreachable!(),
        };
        last = token;
    }
    children
}

pub fn expanded<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    expanded_inner(&mut vm, &mut parents)
}

fn expanded_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
        match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = expanded_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n\n");
                        children.push_str(&expanded_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                match last {
                    Event::Selector(_) => current.push_str(&format!(" {}", name)),
                    Event::End(_) => current.push_str(&format!("{}", name)),
                    _ => current.push_str(&format!("{}", name)),
                }
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!(" {{\n  {}: {};", name, value)),
                    _ => properties.push_str(&format!("\n  {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str("\n}"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str("\n}");
                    },
                    (0, _) => {
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str("\n}\n");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
        };

        last = token;
    }
    children
}

pub fn compact<'a, I>(tokenizer: &mut I) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut vm = VariableMapper::new(tokenizer);
    let mut parents = Vec::new();
    compact_inner(&mut vm, &mut parents)
}

fn compact_inner<'a, I>(tokenizer: &mut I, parents: &mut Vec<String>) -> String
    where I: Iterator<Item = Event<'a>>
{
    let mut last = Event::End(Rule::SassRule);
    let mut current = String::new();
    let mut properties = String::new();
    let mut children = String::new();

    while let Some(token) = tokenizer.next() {
        match token.clone() {
            Event::Start(_) => {
                match children.len() {
                    0 => children = compact_inner(tokenizer, parents),
                    _ => {
                        children.push_str("\n");
                        children.push_str(&compact_inner(tokenizer, parents));
                    },
                };
            },
            Event::Selector(name) => {
                parents.push((*name).to_string());
                match last {
                    Event::Selector(_) => current.push_str(&format!(" {}", name)),
                    Event::End(_) => current.push_str(&format!("{}", name)),
                    _ => current.push_str(&format!("{}", name)),
                }
            },
            Event::Property(name, value) => {
                match last {
                    Event::Selector(_) => properties.push_str(&format!(" {{ {}: {};", name, value)),
                    _ => properties.push_str(&format!(" {}: {};", name, value)),
                }
            },
            Event::End(_) => {
                match (properties.len(), children.len()) {
                    (0, 0) => current.push_str(" }"),
                    (_, 0) => {
                        current.push_str(&properties);
                        current.push_str(" }\n");
                    },
                    (0, _) => {
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                    (_, _) => {
                        current.push_str(&properties);
                        current.push_str(" }\n");
                        current.push_str(&parents.connect(" "));
                        current.push_str(" ");
                        current.push_str(&children);
                    },
                }
                parents.pop();
                return current
            },
            Event::Variable(..) => unreachable!(),
        };
        last = token;
    }
    children
}

pub fn debug(tokenizer: &mut Tokenizer) -> String {
    let mut output = String::new();
    let mut current = String::new();

    while let Some(token) = tokenizer.next() {
        current.push_str(&format!("{:?}\n", token));
        match token {
            Event::End(_) => {
                output.push_str(&current);
                current = String::new();
            },
            _ => {},
        }
    }
    output
}
<|endoftext|>


<commit_before>//! This program reads the RLE sprite sheets and list files which contain the
//! id's for the sprite type, and converts them into an sqlite database. While
//! an sqlite database maybe isn't the most efficient, it's at least somewhat
//! portable and quick to iterate with. Let alone compressing and transferring.
//!
//! NOTES:
//!  - So it seems that the ID value in the list file isn't global to the entire
//!    game, and instead only global to the list file itself. So at this point
//!    I'm thinking that assigning a global ID might be a good idea, though
//!    this ID would just be for referencing the objects which we pull, and not
//!    between objects because they could change depending on the input data.
//!  - The best way it seems to match the data from the `rle` and `list` tables
//!    is to use the file number and file index

extern crate core_compat;
extern crate rusqlite as sql;

use std::path::Path;
use std::fs::File;
use std::fs::read_dir;
use std::io::Read;

use core_compat::rle::{ResourceFile, Resource};
use core_compat::lst::List;
use core_compat::error::Error;

use sql::Connection;

// This is the list of data folder's and list files for them
static FOLDER_ENTRIES: [(&'static str, &'static str, &'static str); 5] = [
    ("Bullets", "../data/RLEs/Bul", "../data/RLEs/bul.lst"),
    ("Icons", "../data/RLEs/Ico", "../data/RLEs/ico.lst"),
    ("Objects", "../data/RLEs/Obj", "../data/RLEs/obj.lst"),
    ("Tiles", "../data/RLEs/Tle", "../data/RLEs/tle.lst"),
    ("Interface", "../data/RLEs/Int", "../data/RLEs/int.lst"),
    // The sounds one is the only one which is a little different...
    // ("Sounds", "../data/RLEs/Snd", "../data/RLEs/snd.lst"),
];

fn main() {

    // create sqlite database
    // let connection = Connection::open_in_memory().unwrap();
    let mut connection = Connection::open(Path::new("./rm.sqlite")).unwrap();

    let _ = connection.execute("DROP TABLE list", &[]);
    let _ = connection.execute("DROP TABLE rle", &[]);

    connection.execute(
        "CREATE TABLE list (
            gid      INTEGER PRIMARY KEY,
            type     TEXT NOT NULL,
            file_num INTEGER,
            file_idx INTEGER,
            name     TEXT NOT NULL,
            list_id  INTEGER
        )", &[]).unwrap();

    connection.execute(
        "CREATE TABLE rle (
            gid      INTEGER PRIMARY KEY,
            type     TEXT NOT NULL,
            file_num INTEGER,
            file_idx INTEGER,
            length   INTEGER,
            offset_x INTEGER,
            offset_y INTEGER,
            width    INTEGER,
            height   INTEGER,
            image    BLOB
        )", &[]).unwrap();

    // parse the list file and insert them into the database
    for &(_type, folder, list) in FOLDER_ENTRIES.iter() {

        println!("file: {:?}", _type);

        // load the data from the list file
        let list_path = Path::new(list);
        let list = load_list_data(&list_path).unwrap();
        println!("list.items.len() == {:?}", list.items.len());

        // Commit all of the list objects in one transaction
        {
            let tx = connection.transaction().unwrap();
            for item in list.items {
                // insert the data into the database
                tx.execute(
                    "INSERT INTO list (type, name, list_id, file_num, file_idx)
                    VALUES (?1, ?2, ?3, ?4, ?5)",
                    &[&_type, &item.name, &item.id, &item.file_number, &item.index]
                ).unwrap();
            }
            tx.commit().unwrap();
        }

        // load the actual sprites into the database
        let rle_paths = read_dir(folder).unwrap();
        let mut resources = Vec::<Resource>::new();

        for path in rle_paths {

            // open and read the file
            let path = path.unwrap();
            let mut file = File::open(path.path()).unwrap();
            let mut bytes = Vec::<u8>::new();
            file.read_to_end(&mut bytes).unwrap();

            // parse the file number
            let mut file_num = 0xFFFF;
            if let Some(stem) = path.path().file_stem() {
                if let Some(stem) = stem.to_str() {
                    let num: String = stem.matches(char::is_numeric).collect();
                    file_num = num.parse().unwrap_or(0xFFFF);
                }
            }

            // parse && append results
            let res_file = ResourceFile::load(file_num, &mut bytes).unwrap();
            for resource in res_file.resources {
                resources.push(resource);
            }

        }

        // Commit all of the sprite objects in one transaction
        {
            let tx = connection.transaction().unwrap();
            for ref rle in &resources {

                // TODO: hack the Vec<Pixel> into a Vec<U8>
                let mut img = Vec::<u8>::new();
                for ref pixel in &rle.image {
                    img.push(pixel.r);
                    img.push(pixel.g);
                    img.push(pixel.b);
                    img.push(pixel.a);
                }

                // insert the data into the database
                tx.execute(
                    "INSERT INTO rle (
                        type,   file_num, file_idx,
                        length, offset_x, offset_y,
                        width,  height,   image)
                    VALUES (?1, ?2, ?3,
                            ?4, ?5, ?6,
                            ?7, ?8, ?9)",
                    &[&_type,   &rle.file_num, &rle.index,
                    &rle.len,   &rle.offset_x, &rle.offset_y,
                    &rle.width, &rle.height,   &img]
                ).unwrap();
            }
            tx.commit().unwrap();

        }
        println!("resources.len() == {:?}", &resources.len());
    }

    // check the # of entries in the database
    let mut stmt = connection.prepare("SELECT list_id, name FROM list").unwrap();
    let lst_itr = stmt.query_map(&[], |row| {
        let id: u32 = row.get(0);
        let name: String = row.get(1);
        (id, name)
    }).unwrap();
    let lst_vec = lst_itr.filter_map(|x| x.ok()).collect::<Vec<_>>();
    println!("lst_vec.len(): {:?}", lst_vec.len());
}

fn load_list_data(list_path: &Path) -> Result<List, Error> {
    let mut list_file = File::open(list_path)?;
    let mut list_bytes = Vec::<u8>::new();
    list_file.read_to_end(&mut list_bytes)?;
    List::load(&list_bytes, false)
}
<commit_msg>Pull out rle loading into its own function<commit_after>//! This program reads the RLE sprite sheets and list files which contain the
//! id's for the sprite type, and converts them into an sqlite database. While
//! an sqlite database maybe isn't the most efficient, it's at least somewhat
//! portable and quick to iterate with. Let alone compressing and transferring.
//!
//! NOTES:
//!  - So it seems that the ID value in the list file isn't global to the entire
//!    game, and instead only global to the list file itself. So at this point
//!    I'm thinking that assigning a global ID might be a good idea, though
//!    this ID would just be for referencing the objects which we pull, and not
//!    between objects because they could change depending on the input data.
//!  - The best way it seems to match the data from the `rle` and `list` tables
//!    is to use the file number and file index

extern crate core_compat;
extern crate rusqlite as sql;

use std::path::Path;
use std::fs::File;
use std::fs::read_dir;
use std::io::Read;

use core_compat::rle::{ResourceFile, Resource};
use core_compat::lst::List;
use core_compat::error::Error;

use sql::Connection;

// This is the list of data folder's and list files for them
static FOLDER_ENTRIES: [(&'static str, &'static str, &'static str); 5] = [
    ("Bullets", "../data/RLEs/Bul", "../data/RLEs/bul.lst"),
    ("Icons", "../data/RLEs/Ico", "../data/RLEs/ico.lst"),
    ("Objects", "../data/RLEs/Obj", "../data/RLEs/obj.lst"),
    ("Tiles", "../data/RLEs/Tle", "../data/RLEs/tle.lst"),
    ("Interface", "../data/RLEs/Int", "../data/RLEs/int.lst"),
    // The sounds one is the only one which is a little different...
    // ("Sounds", "../data/RLEs/Snd", "../data/RLEs/snd.lst"),
];

fn main() {

    // create sqlite database
    // let connection = Connection::open_in_memory().unwrap();
    let mut connection = Connection::open(Path::new("./rm.sqlite")).unwrap();

    let _ = connection.execute("DROP TABLE list", &[]);
    let _ = connection.execute("DROP TABLE rle", &[]);

    connection.execute(
        "CREATE TABLE list (
            gid      INTEGER PRIMARY KEY,
            type     TEXT NOT NULL,
            file_num INTEGER,
            file_idx INTEGER,
            name     TEXT NOT NULL,
            list_id  INTEGER
        )", &[]).unwrap();

    connection.execute(
        "CREATE TABLE rle (
            gid      INTEGER PRIMARY KEY,
            type     TEXT NOT NULL,
            file_num INTEGER,
            file_idx INTEGER,
            length   INTEGER,
            offset_x INTEGER,
            offset_y INTEGER,
            width    INTEGER,
            height   INTEGER,
            image    BLOB
        )", &[]).unwrap();

    // parse the list file and insert them into the database
    for &(_type, folder, list) in FOLDER_ENTRIES.iter() {

        println!("file: {:?}", _type);

        // load the data from the list file
        let list_path = Path::new(list);
        let list = load_list_data(&list_path).unwrap();
        println!("list.items.len() == {:?}", list.items.len());

        // Commit all of the list objects in one transaction
        {
            let tx = connection.transaction().unwrap();
            for item in list.items {
                // insert the data into the database
                tx.execute(
                    "INSERT INTO list (type, name, list_id, file_num, file_idx)
                    VALUES (?1, ?2, ?3, ?4, ?5)",
                    &[&_type, &item.name, &item.id, &item.file_number, &item.index]
                ).unwrap();
            }
            tx.commit().unwrap();
        }

        // load the actual sprites into the database
        let rle_paths = read_dir(folder).unwrap();
        let mut resources = Vec::<Resource>::new();

        for entry in rle_paths {

            let entry = entry.unwrap();
            let path = entry.path();

            let res_file: ResourceFile = load_rle_data(&path).unwrap();

            for resource in res_file.resources {
                resources.push(resource);
            }

        }

        // Commit all of the sprite objects in one transaction
        {
            let tx = connection.transaction().unwrap();
            for ref rle in &resources {

                // TODO: hack the Vec<Pixel> into a Vec<U8>
                let mut img = Vec::<u8>::new();
                for ref pixel in &rle.image {
                    img.push(pixel.r);
                    img.push(pixel.g);
                    img.push(pixel.b);
                    img.push(pixel.a);
                }

                // insert the data into the database
                tx.execute(
                    "INSERT INTO rle (
                        type,   file_num, file_idx,
                        length, offset_x, offset_y,
                        width,  height,   image)
                    VALUES (?1, ?2, ?3,
                            ?4, ?5, ?6,
                            ?7, ?8, ?9)",
                    &[&_type,   &rle.file_num, &rle.index,
                    &rle.len,   &rle.offset_x, &rle.offset_y,
                    &rle.width, &rle.height,   &img]
                ).unwrap();
            }
            tx.commit().unwrap();

        }
        println!("resources.len() == {:?}", &resources.len());
    }

    // check the # of entries in the database
    let mut stmt = connection.prepare("SELECT list_id, name FROM list").unwrap();
    let lst_itr = stmt.query_map(&[], |row| {
        let id: u32 = row.get(0);
        let name: String = row.get(1);
        (id, name)
    }).unwrap();
    let lst_vec = lst_itr.filter_map(|x| x.ok()).collect::<Vec<_>>();
    println!("lst_vec.len(): {:?}", lst_vec.len());
}

fn load_list_data(path: &Path) -> Result<List, Error> {
    let mut file = File::open(path)?;
    let mut bytes = Vec::<u8>::new();
    file.read_to_end(&mut bytes)?;
    List::load(&bytes, false)
}

fn load_rle_data(path: &Path) -> Result<ResourceFile, Error> {

    // open and read the file
    let mut file = File::open(path)?;
    let mut bytes = Vec::<u8>::new();
    file.read_to_end(&mut bytes)?;

    // parse the file number
    let mut file_num = 0xFFFF;
    if let Some(stem) = path.file_stem() {
        if let Some(stem) = stem.to_str() {
            let num: String = stem.matches(char::is_numeric).collect();
            file_num = num.parse().unwrap_or(0xFFFF);
        }
    }

    // parse && append results
    ResourceFile::load(file_num, &mut bytes)
}<|endoftext|>


<commit_before>extern crate "parser-combinators" as parser_combinators;

use self::parser_combinators::{try, between, spaces, parser, many, many1, digit, optional, hex_digit, not_followed_by, satisfy, Parser, ParserExt, ParseResult};
use self::parser_combinators::primitives::{State, Stream};
use super::ast::*;
use super::ast::ExprNode::*;
use std::str::FromStr;
use std::num::FromStrRadix;

/// Parser for signed integer constants.
///
/// This parses signed integer constants in decimal and hexadecimal.
///
/// TODO: add support for octal
/// TODO: add support for binary
fn sint_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        optional(satisfy(|c| c == '-'))
            .and(
                (satisfy(|c| c == '0')
                    .and(satisfy(|c| c == 'x' || c == 'X')))
                    .with(many1::<Vec<_>, _>(hex_digit()))
                    .map(|x| {
                        isize::from_str_radix(
                            x.iter()
                             .fold(
                                String::new(),
                                |mut s: String, i| { s.push(*i); s })
                             .as_slice(),
                        16).unwrap()
                    })
                .or( many1::<Vec<_>, _>(digit()).map(|x|
                    isize::from_str(x.iter().fold(
                        String::new(), |mut s: String, i| { s.push(*i); s })
                        .as_slice()
                    ).unwrap()
                    )
                )
                )
            .map(|x| {
                if let Some(sign) = x.0 {
                    let mut s = String::new();
                    s.push(sign);
                    s.push('1');
                    x.1 * isize::from_str(s.as_slice()).unwrap()
                } else {
                    x.1
                }
                })
            .skip(not_followed_by(satisfy(|c|
                c == 'u' || c == 'U' || c == '.' || c == 'f' || c == 'F')
            ))
            .map(|x: isize| NumNode::IntConst(IntNode{value: x}))
            .parse_state(input)
}
/// Parser for unsigned integer constants.
///
/// This parses unssigned integer constants in decimal and hexadecimal.
///
/// TODO: add support for octal
/// TODO: add support for binary
fn uint_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        (satisfy(|c| c == '0')
            .and(satisfy(|c| c == 'x' || c == 'X')))
            .with(many1::<Vec<_>, _>(hex_digit()))
            .map(|x| usize::from_str_radix(
                    x.iter()
                     .fold(
                        String::new(),
                        |mut s: String, i| { s.push(*i); s })
                     .as_slice(),
                16).unwrap()
            )
        .or( many1::<Vec<_>, _>(digit())
            .map(|x|usize::from_str(x.iter().fold(
                String::new(), |mut s: String, i| { s.push(*i); s })
                .as_slice()
            ).unwrap())
        )
        .skip(satisfy(|c| c == 'u' || c == 'U'))
        .map(|x: usize| NumNode::UIntConst(UIntNode{value: x}))
        .parse_state(input)
}

/// Parser for floating-point constants.
///
/// This parses floating-point constants. Currently, this parser
/// recognizes numbers with decimal points as floating point, followed
/// by an optional `f` or `F`. Numbers with `f`s but no decimal points,
/// i.e. `1F`, are currently not recognized. While this form of number
/// is not specified by R6RS, I'd like to support it anyway as it's
/// a common form for floating-point numbers. Priority: low.
fn float_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        many1::<Vec<_>, _>(digit())
            .and(satisfy(|c| c == '.'))
            .and(many1::<Vec<_>, _>(digit()))
            .map(|x| {
                let mut s = String::new();
                for i in (x.0).0.iter() { s.push(*i); } ;
                s.push((x.0).1);

                for i in x.1.iter() { s.push(*i); };
                NumNode::FloatConst(FloatNode{
                    value: f64::from_str(s.as_slice()).unwrap()
                })
            })
            .skip(optional(satisfy(|c| c == 'f' || c == 'F')))
            .parse_state(input)
}

/// Parses a floating-point, signed integer, or unsigned integer constant.
pub fn number<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        try(parser(sint_const))
            .or(try(parser(uint_const)))
            .or(try(parser(float_const)))
            .parse_state(input)
}

/// Parser for valid R6RS identifiers.
///
/// An identifier may begin with an alphabetic character or
/// one of the following special characters `!`, `$`, `&`, `:`, `^`,
/// `<`, `>`, `_`,`~`,`\`, or `?`. Subsequent characters may also include
/// numbers or the special characters `+`, `-`, `.`, and `@`.
///
/// Essentially, this parser recognizes the regular expression
/// `[a-zA-Z!\$%:\^<>_~\\\?][a-zA-Z0-9!\$%:\^<>_~\\\?\+\-\.@]*`.
///
/// For more information, consult the
/// [R6RS](http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-7.html).
pub fn name<I>(input: State<I>) -> ParseResult<NameNode, I>
    where I: Stream<Item=char> {
         let initial = satisfy(|c|
            c.is_alphabetic()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?');
        let subsequent = satisfy(|c|
            c.is_alphanumeric()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?'
                // R6RS 'special subsequent' characters
                || c == '+' || c == '-' || c == '.' || c == '@');
        initial
            .and(many::<Vec<_>, _>(subsequent).map(|it|
                it.iter().fold(
                    String::new(),
                    |mut s: String, i| {
                        s.push(*i);
                        s
                    }
                    )
                ))
            .parse_state(input)
            .map(|x| {
                let mut s = String::new();
                s.push((x.0).0);
                s.push_str(&(x.0).1);
                (NameNode{ name: s}, x.1)
            })
}

/// Parses Scheme expressions.
pub fn expr<I>(input: State<I>) -> ParseResult<ExprNode, I>
    where I: Stream<Item=char> {
        let spaces = spaces();
        let sexpr = between(
            satisfy(|c| c == '('),
            satisfy(|c| c == ')'),
            parser(name)
                .and(many(parser(expr)))
                .map(|x| {
                    SExpr(SExprNode {
                        operator: x.0,
                        operands: x.1
                    })
                })
            );
        let list = between(
            satisfy(|c| c == '('),
            satisfy(|c| c == ')'),
            many(parser(expr))
                .map(|x| {
                    ListConst(ListNode {
                        elements: x
                    })
                })
            );
        spaces.clone().with(
            try(sexpr)
                .or(try(list))
                .or(try(parser(name).map(Name)))
                .or(try(parser(number).map(NumConst)))
            ).parse_state(input)
}

#[cfg(test)]
mod tests;<commit_msg>Implemented parser for boolean constants<commit_after>extern crate "parser-combinators" as parser_combinators;

use self::parser_combinators::{try, between, spaces, string, parser, many, many1, digit, optional, hex_digit, not_followed_by, satisfy, Parser, ParserExt, ParseResult};
use self::parser_combinators::primitives::{State, Stream};
use super::ast::*;
use super::ast::ExprNode::*;
use std::str::FromStr;
use std::num::FromStrRadix;

/// Parser for signed integer constants.
///
/// This parses signed integer constants in decimal and hexadecimal.
///
/// TODO: add support for octal
/// TODO: add support for binary
fn sint_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        optional(satisfy(|c| c == '-'))
            .and(
                (satisfy(|c| c == '0')
                    .and(satisfy(|c| c == 'x' || c == 'X')))
                    .with(many1::<Vec<_>, _>(hex_digit()))
                    .map(|x| {
                        isize::from_str_radix(
                            x.iter()
                             .fold(
                                String::new(),
                                |mut s: String, i| { s.push(*i); s })
                             .as_slice(),
                        16).unwrap()
                    })
                .or( many1::<Vec<_>, _>(digit()).map(|x|
                    isize::from_str(x.iter().fold(
                        String::new(), |mut s: String, i| { s.push(*i); s })
                        .as_slice()
                    ).unwrap()
                    )
                )
                )
            .map(|x| {
                if let Some(sign) = x.0 {
                    let mut s = String::new();
                    s.push(sign);
                    s.push('1');
                    x.1 * isize::from_str(s.as_slice()).unwrap()
                } else {
                    x.1
                }
                })
            .skip(not_followed_by(satisfy(|c|
                c == 'u' || c == 'U' || c == '.' || c == 'f' || c == 'F')
            ))
            .map(|x: isize| NumNode::IntConst(IntNode{value: x}))
            .parse_state(input)
}
/// Parser for unsigned integer constants.
///
/// This parses unssigned integer constants in decimal and hexadecimal.
///
/// TODO: add support for octal
/// TODO: add support for binary
fn uint_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        (satisfy(|c| c == '0')
            .and(satisfy(|c| c == 'x' || c == 'X')))
            .with(many1::<Vec<_>, _>(hex_digit()))
            .map(|x| usize::from_str_radix(
                    x.iter()
                     .fold(
                        String::new(),
                        |mut s: String, i| { s.push(*i); s })
                     .as_slice(),
                16).unwrap()
            )
        .or( many1::<Vec<_>, _>(digit())
            .map(|x|usize::from_str(x.iter().fold(
                String::new(), |mut s: String, i| { s.push(*i); s })
                .as_slice()
            ).unwrap())
        )
        .skip(satisfy(|c| c == 'u' || c == 'U'))
        .map(|x: usize| NumNode::UIntConst(UIntNode{value: x}))
        .parse_state(input)
}

/// Parser for floating-point constants.
///
/// This parses floating-point constants. Currently, this parser
/// recognizes numbers with decimal points as floating point, followed
/// by an optional `f` or `F`. Numbers with `f`s but no decimal points,
/// i.e. `1F`, are currently not recognized. While this form of number
/// is not specified by R6RS, I'd like to support it anyway as it's
/// a common form for floating-point numbers. Priority: low.
fn float_const<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        many1::<Vec<_>, _>(digit())
            .and(satisfy(|c| c == '.'))
            .and(many1::<Vec<_>, _>(digit()))
            .map(|x| {
                let mut s = String::new();
                for i in (x.0).0.iter() { s.push(*i); } ;
                s.push((x.0).1);

                for i in x.1.iter() { s.push(*i); };
                NumNode::FloatConst(FloatNode{
                    value: f64::from_str(s.as_slice()).unwrap()
                })
            })
            .skip(optional(satisfy(|c| c == 'f' || c == 'F')))
            .parse_state(input)
}

/// Parses boolean constants.
///
/// Note that this parser recognizes the strings `"true"` and `"false"`
/// as true and false. While this is not specified in R6RS, the use of
/// these tokens is common enough in other programming languages that
/// I've decided that Seax Scheme should support it as well. This may
/// be removed in a future version if it causes unforseen compatibility
/// issues.
///
/// `#t`, `#T`, or `true`  -> `true`
/// `#f`, `#F`, or `false` -> `false`
pub fn bool_const<I>(input: State<I>) -> ParseResult<BoolNode, I>
    where I: Stream<Item=char> {
        let t_const = try(string("#t"))
            .or(try(string("#T")))
            .or(try(string("true")))
            .map(|_| BoolNode{ value: true });
        let f_const = try(string("#f"))
            .or(try(string("#F")))
            .or(try(string("false")))
            .map(|_| BoolNode{ value: false });
        t_const
            .or(f_const)
            .parse_state(input)
    }

/// Parses a floating-point, signed integer, or unsigned integer constant.
pub fn number<I>(input: State<I>) -> ParseResult<NumNode, I>
    where I: Stream<Item=char> {
        try(parser(sint_const))
            .or(try(parser(uint_const)))
            .or(try(parser(float_const)))
            .parse_state(input)
}

/// Parser for valid R6RS identifiers.
///
/// An identifier may begin with an alphabetic character or
/// one of the following special characters `!`, `$`, `&`, `:`, `^`,
/// `<`, `>`, `_`,`~`,`\`, or `?`. Subsequent characters may also include
/// numbers or the special characters `+`, `-`, `.`, and `@`.
///
/// Essentially, this parser recognizes the regular expression
/// `[a-zA-Z!\$%:\^<>_~\\\?][a-zA-Z0-9!\$%:\^<>_~\\\?\+\-\.@]*`.
///
/// For more information, consult the
/// [R6RS](http://www.r6rs.org/final/html/r6rs/r6rs-Z-H-7.html).
pub fn name<I>(input: State<I>) -> ParseResult<NameNode, I>
    where I: Stream<Item=char> {
         let initial = satisfy(|c|
            c.is_alphabetic()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?');
        let subsequent = satisfy(|c|
            c.is_alphanumeric()
                // R6RS 'special initial' characters
                || c == '!' || c == '$' || c == '%' || c == ':' || c == '^'
                || c == '<' || c == '>' || c == '_' || c == '~' || c == '\\'
                || c == '?'
                // R6RS 'special subsequent' characters
                || c == '+' || c == '-' || c == '.' || c == '@');
        initial
            .and(many::<Vec<_>, _>(subsequent).map(|it|
                it.iter().fold(
                    String::new(),
                    |mut s: String, i| {
                        s.push(*i);
                        s
                    }
                    )
                ))
            .parse_state(input)
            .map(|x| {
                let mut s = String::new();
                s.push((x.0).0);
                s.push_str(&(x.0).1);
                (NameNode{ name: s}, x.1)
            })
}

/// Parses Scheme expressions.
pub fn expr<I>(input: State<I>) -> ParseResult<ExprNode, I>
    where I: Stream<Item=char> {
        let spaces = spaces();
        let sexpr = between(
            satisfy(|c| c == '('),
            satisfy(|c| c == ')'),
            parser(name)
                .and(many(parser(expr)))
                .map(|x| {
                    SExpr(SExprNode {
                        operator: x.0,
                        operands: x.1
                    })
                })
            );
        let list = between(
            satisfy(|c| c == '('),
            satisfy(|c| c == ')'),
            many(parser(expr))
                .map(|x| {
                    ListConst(ListNode {
                        elements: x
                    })
                })
            );
        spaces.clone().with(
            try(sexpr)
                .or(try(list))
                .or(try(parser(name).map(Name)))
                .or(try(parser(number).map(NumConst)))
            ).parse_state(input)
}

#[cfg(test)]
mod tests;<|endoftext|>


<commit_before>use crate::iter::{FusedIterator, TrustedLen};

/// Creates a new iterator that endlessly repeats a single element.
///
/// The `repeat()` function repeats a single value over and over again.
///
/// Infinite iterators like `repeat()` are often used with adapters like
/// [`Iterator::take()`], in order to make them finite.
///
/// If the element type of the iterator you need does not implement `Clone`,
/// or if you do not want to keep the repeated element in memory, you can
/// instead use the [`repeat_with()`] function.
///
/// [`repeat_with()`]: crate::iter::repeat_with
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // the number four 4ever:
/// let mut fours = iter::repeat(4);
///
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
///
/// // yup, still four
/// assert_eq!(Some(4), fours.next());
/// ```
///
/// Going finite with [`Iterator::take()`]:
///
/// ```
/// use std::iter;
///
/// // that last example was too many fours. Let's only have four fours.
/// let mut four_fours = iter::repeat(4).take(4);
///
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
///
/// // ... and now we're done
/// assert_eq!(None, four_fours.next());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
    Repeat { element: elt }
}

/// An iterator that repeats an element endlessly.
///
/// This `struct` is created by the [`repeat()`] function. See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat<A> {
    element: A,
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> Iterator for Repeat<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        Some(self.element.clone())
    }
    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (usize::MAX, None)
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> DoubleEndedIterator for Repeat<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        Some(self.element.clone())
    }
}

#[stable(feature = "fused", since = "1.26.0")]
impl<A: Clone> FusedIterator for Repeat<A> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
<commit_msg>Rollup merge of #85338 - lopopolo:core-iter-repeat-gh-81292, r=joshtriplett<commit_after>use crate::iter::{FusedIterator, TrustedLen};

/// Creates a new iterator that endlessly repeats a single element.
///
/// The `repeat()` function repeats a single value over and over again.
///
/// Infinite iterators like `repeat()` are often used with adapters like
/// [`Iterator::take()`], in order to make them finite.
///
/// If the element type of the iterator you need does not implement `Clone`,
/// or if you do not want to keep the repeated element in memory, you can
/// instead use the [`repeat_with()`] function.
///
/// [`repeat_with()`]: crate::iter::repeat_with
///
/// # Examples
///
/// Basic usage:
///
/// ```
/// use std::iter;
///
/// // the number four 4ever:
/// let mut fours = iter::repeat(4);
///
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
/// assert_eq!(Some(4), fours.next());
///
/// // yup, still four
/// assert_eq!(Some(4), fours.next());
/// ```
///
/// Going finite with [`Iterator::take()`]:
///
/// ```
/// use std::iter;
///
/// // that last example was too many fours. Let's only have four fours.
/// let mut four_fours = iter::repeat(4).take(4);
///
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
/// assert_eq!(Some(4), four_fours.next());
///
/// // ... and now we're done
/// assert_eq!(None, four_fours.next());
/// ```
#[inline]
#[stable(feature = "rust1", since = "1.0.0")]
pub fn repeat<T: Clone>(elt: T) -> Repeat<T> {
    Repeat { element: elt }
}

/// An iterator that repeats an element endlessly.
///
/// This `struct` is created by the [`repeat()`] function. See its documentation for more.
#[derive(Clone, Debug)]
#[stable(feature = "rust1", since = "1.0.0")]
pub struct Repeat<A> {
    element: A,
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> Iterator for Repeat<A> {
    type Item = A;

    #[inline]
    fn next(&mut self) -> Option<A> {
        Some(self.element.clone())
    }

    #[inline]
    fn size_hint(&self) -> (usize, Option<usize>) {
        (usize::MAX, None)
    }

    #[inline]
    fn advance_by(&mut self, n: usize) -> Result<(), usize> {
        // Advancing an infinite iterator of a single element is a no-op.
        let _ = n;
        Ok(())
    }

    #[inline]
    fn nth(&mut self, n: usize) -> Option<A> {
        let _ = n;
        Some(self.element.clone())
    }

    fn last(self) -> Option<A> {
        loop {}
    }

    fn count(self) -> usize {
        loop {}
    }
}

#[stable(feature = "rust1", since = "1.0.0")]
impl<A: Clone> DoubleEndedIterator for Repeat<A> {
    #[inline]
    fn next_back(&mut self) -> Option<A> {
        Some(self.element.clone())
    }

    #[inline]
    fn advance_back_by(&mut self, n: usize) -> Result<(), usize> {
        // Advancing an infinite iterator of a single element is a no-op.
        let _ = n;
        Ok(())
    }

    #[inline]
    fn nth_back(&mut self, n: usize) -> Option<A> {
        let _ = n;
        Some(self.element.clone())
    }
}

#[stable(feature = "fused", since = "1.26.0")]
impl<A: Clone> FusedIterator for Repeat<A> {}

#[unstable(feature = "trusted_len", issue = "37572")]
unsafe impl<A: Clone> TrustedLen for Repeat<A> {}
<|endoftext|>