Skip to content

Commit

Permalink
Merge pull request #15 from ehuss/string-reference
Browse files Browse the repository at this point in the history
Remove string copying.
  • Loading branch information
LeopoldArkham committed Nov 16, 2017
2 parents 1fd0da8 + 39fccd8 commit 356cb6d
Show file tree
Hide file tree
Showing 33 changed files with 1,098 additions and 503 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,5 @@ Cargo.lock
*.rs.bk
tests/res.toml
\.vscode/

*.txt
1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,4 @@ error-chain = "0.11.0"
[dev-dependencies]
test-case-derive = "0.1.4"
pretty_assertions = "0.4.0"
lazy_static = "0.2"
12 changes: 5 additions & 7 deletions src/api.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
use items::*;

impl Item {

impl<'a> Item<'a> {
pub fn is_value(&self) -> bool {
match self.discriminant() {
0 | 1 => false,
Expand Down Expand Up @@ -45,9 +44,9 @@ impl Item {
self.discriminant() == 7 || self.discriminant() == 8
}

pub(crate) fn is_real_table(&self) -> bool {
self.discriminant() == 7 || self.discriminant() == 10
}
// pub(crate) fn is_real_table(&self) -> bool {
// self.discriminant() == 7 || self.discriminant() == 10
// }

pub fn is_inline_table(&self) -> bool {
self.discriminant() == 8
Expand All @@ -60,5 +59,4 @@ impl Item {
pub fn is_aot(&self) -> bool {
self.discriminant() == 10
}

}
}
70 changes: 39 additions & 31 deletions src/container.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,26 +3,27 @@ use std::collections::HashMap;
use items::*;
use errors::*;

#[derive(Debug, Clone)]
pub struct Container {
pub(crate) map: HashMap<Key, usize>,
pub(crate) body: Vec<(Option<Key>, Item)>,
#[derive(Debug, Clone, PartialEq)]
pub struct Container<'a> {
pub(crate) map: HashMap<Key<'a>, usize>,
pub(crate) body: Vec<(Option<Key<'a>>, Item<'a>)>,
}

impl Container {
pub fn new() -> Container {
impl<'a> Container<'a> {
pub fn new() -> Container<'a> {
Container {
map: HashMap::new(),
body: Vec::new(),
}
}

pub fn append<K: Into<Option<Key>>>(&mut self, _key: K, item: Item) -> Result<()> {
pub fn append<K: Into<Option<Key<'a>>>>(&mut self, _key: K, item: Item<'a>) -> Result<()> {
let key = _key.into();
if let Some(k) = key.clone() {
if self.map.contains_key(&k) {
bail!(ErrorKind::DuplicateKey(k.key));
}
// TODO: Fix AoT
// if self.map.contains_key(&k) {
// bail!(ErrorKind::DuplicateKey(k.key.into()));
// }
self.map.insert(k, self.body.len());
}
self.body.push((key, item));
Expand All @@ -40,37 +41,44 @@ impl Container {
true => ("[[", "]]"),
false => ("[", "]"),
};
format!("{}{}{}{}{}{}{}",
format!("{}{}{}{}{}{}{}{}",
v.meta().indent,
open,
k.unwrap().as_string(),
close,
v.meta().comment(),
v.meta().comment_ws,
v.meta().comment,
v.meta().trail,
v.as_string(),)
}
Item::AoT(vec) => {
let mut buf = String::new();
let key = k.unwrap().as_string();
for table in vec {
buf.push_str(&format!("{}[[{}]]{}{}",
table.meta().indent,
key,
table.meta().comment(),
table.meta().trail));
buf.push_str(&format!(
"{}[[{}]]{}{}{}",
table.meta().indent,
key,
table.meta().comment_ws,
table.meta().comment,
table.meta().trail
));
buf.push_str(&table.as_string());
}
buf
}
_ => {
let k = k.unwrap();
format!("{}{}{}{}{}{}",
v.meta().indent,
k.as_string(),
k.sep,
v.as_string(),
v.meta().comment(),
v.meta().trail)
format!(
"{}{}{}{}{}{}{}",
v.meta().indent,
k.as_string(),
k.sep,
v.as_string(),
v.meta().comment_ws,
v.meta().comment,
v.meta().trail
)
}
}
} else {
Expand All @@ -81,7 +89,7 @@ impl Container {
s
}

pub fn iter(&self) -> ContainerIterator {
pub fn iter(&'a self) -> ContainerIterator<'a> {
ContainerIterator {
container: self,
current: 0,
Expand All @@ -97,15 +105,15 @@ impl Container {
}

pub struct ContainerIterator<'a> {
container: &'a Container,
container: &'a Container<'a>,
current: usize,
}

impl<'a> Iterator for ContainerIterator<'a> {
type Item = &'a Item;
type Item = &'a Item<'a>;

// @cleanup: "There must be a better way"
fn next(&mut self) -> Option<&'a Item> {
fn next(&mut self) -> Option<&'a Item<'a>> {
loop {
if self.current == self.container.body.len() {
return None;
Expand All @@ -123,14 +131,14 @@ impl<'a> Iterator for ContainerIterator<'a> {
}

pub struct ContainerIteratorExhaustive<'a> {
container: &'a Container,
container: &'a Container<'a>,
current: usize,
}

impl<'a> Iterator for ContainerIteratorExhaustive<'a> {
type Item = &'a Item;
type Item = &'a Item<'a>;

fn next(&mut self) -> Option<&'a Item> {
fn next(&mut self) -> Option<&'a Item<'a>> {
if self.current != self.container.body.len() {
let r = &self.container.body[self.current];
self.current += 1;
Expand Down
14 changes: 14 additions & 0 deletions src/errors.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,5 +18,19 @@ error_chain! {
description("Unexpected character")
display("Unexpected character: {}", ch)
}
UnexpectedEof {
description("Unepxected end of file")
}
InvalidCharInString(ch: char) {
description("Invalid character in string")
display("Invalid character '{}' in string", ch) // XXX escaping
}
InternalParserError(msg: String) {
description("Internal Parser Error")
display("{}\n The parser has violated one of its invariants.
This is a bug.\n
Please open an issue uqoting this message at
https://github.com/LeopoldArkham/Molten", msg)
}
}
}
41 changes: 22 additions & 19 deletions src/index.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2,53 +2,56 @@ use std::ops::Index;
use tomldoc::TOMLDocument;
use items::*;

impl Index<&'static str> for TOMLDocument {
type Output = Item;
impl<'a> Index<&'static str> for TOMLDocument<'a> {
type Output = Item<'a>;

fn index(&self, name: &str) -> &Self::Output {
let k = Key {
t: KeyType::Bare,
sep: "".to_string(),
key: name.to_string(),
sep: "",
key: name,
};
let idx = self.0.map.get(&k).expect("Invalid key");
&self.0.body[*idx].1
}
}

impl Index<usize> for TOMLDocument {
type Output = Item;
impl<'a> Index<usize> for TOMLDocument<'a> {
type Output = Item<'a>;

fn index(&self, idx: usize) -> &Self::Output {
self.0.iter().nth(idx).expect("Indexing TOMLDoc failed")
// XXX TODO
&self.0.body[idx].1
// self.0.iter().nth(idx).expect("Indexing TOMLDoc failed")
}
}

impl Index<usize> for Item {
type Output = Item;
impl<'a> Index<usize> for Item<'a> {
type Output = Item<'a>;

fn index(&self, idx: usize) -> &Self::Output {
use self::Item::*;
match *self {
Array { ref val, .. } => &val[idx],
Table { ref val, .. } => &val.iter().nth(idx).expect("Indexing Table failed"),
InlineTable { ref val, .. } => {
&val.iter().nth(idx).expect("Indexing InlineTable failed")
}
AoT(ref vec) => &vec.iter().nth(idx).expect("Indexing AoT failed"),
// XXX TODO
// Table { ref val, .. } => &val.iter().nth(idx).expect("Indexing Table failed"),
// InlineTable { ref val, .. } => {
// &val.iter().nth(idx).expect("Indexing InlineTable failed")
// }
// AoT(ref vec) => &vec.iter().nth(idx).expect("Indexing AoT failed"),
_ => panic!(),
}
}
}

impl Index<&'static str> for Item {
type Output = Item;
impl<'a> Index<&'static str> for Item<'a> {
type Output = Item<'a>;

fn index(&self, name: &str) -> &Self::Output {
let k = Key {
t: KeyType::Bare,
sep: "".to_string(),
key: name.to_string(),
sep: "",
key: name,
};

use self::Item::*;
Expand All @@ -59,4 +62,4 @@ impl Index<&'static str> for Item {

}
}
}
}
Loading

0 comments on commit 356cb6d

Please sign in to comment.