Skip to content

Commit 9feef91

Browse files
WIP new API. InvokeError. Box<Iterator>. Version bump 0.2.12
1 parent 6621d8f commit 9feef91

File tree

6 files changed

+122
-23
lines changed

6 files changed

+122
-23
lines changed

Cargo.toml

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "incrust"
3-
version = "0.2.11"
3+
version = "0.2.12"
44
authors = ["Alexander Irbis <[email protected]>"]
55
license = "MIT/Apache-2.0"
66
description = "Template engine inspired by Jinja2"

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ Incrust is [available on crates.io](https://crates.io/crates/incrust) and can be
2222

2323
```toml
2424
[dependencies]
25-
incrust = "=0.2.11"
25+
incrust = "=0.2.12"
2626
```
2727

2828
For ease of use hashmaps you may use the [maplit](https://crates.io/crates/maplit)

src/renderer/abc.rs

+19-1
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ pub type EvalResult<T> = Result<Option<T>, EvalError>;
88

99
#[derive(Debug)]
1010
pub enum EvalError {
11-
NotInvocable,
11+
Invoke(InvokeError),
1212
NoneArg,
1313
NotComposable,
1414
AttributeNotExists(String),
@@ -17,6 +17,24 @@ pub enum EvalError {
1717
}
1818

1919

20+
#[derive(Debug)]
21+
pub enum InvokeError {
22+
NotInvocable,
23+
WrongArgsNumber(usize, usize),
24+
WrongArgType(usize, ExpectedArgType),
25+
}
26+
27+
#[derive(Debug)]
28+
pub enum ExpectedArgType {
29+
String,
30+
Int,
31+
Real,
32+
Bool
33+
}
34+
35+
impl From<InvokeError> for EvalError { fn from(err: InvokeError) -> Self { EvalError::Invoke(err) } }
36+
37+
2038
pub type FilterResult<T> = Result<Option<T>, FilterError>;
2139

2240
#[derive(Debug)]

src/renderer/evaluator.rs

+4-4
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
use abc::{EvalResult, EvalError};
1+
use abc::{EvalResult, EvalError, InvokeError};
22
use container::expression::*;
33
use {Arg, Context};
44

@@ -132,14 +132,14 @@ pub fn eval_attribute<'r>(context: &'r Context<'r>, attr: &'r Attribute) -> Eval
132132

133133
pub fn eval_invocation<'r>(context: &'r Context<'r>, inv: &'r Invocation) -> EvalResult<Arg<'r>> {
134134
match eval_factor(context, &inv.on)? {
135-
None => Err(EvalError::NotInvocable),
135+
None => Err(InvokeError::NotInvocable)?,
136136
Some(value) => match value.try_as_invocable() {
137-
None => Err(EvalError::NotInvocable),
137+
None => Err(InvokeError::NotInvocable)?,
138138
Some(invocable) => {
139139
let mut args: Vec<Arg> = Vec::with_capacity(inv.args.len());
140140
for expr in &inv.args {
141141
match eval_expr(context, expr)? {
142-
None => return Err(EvalError::NoneArg),
142+
None => Err(EvalError::NoneArg)?,
143143
Some(val) => args.push(val)
144144
}
145145
}

src/types/abc.rs

+10-9
Original file line numberDiff line numberDiff line change
@@ -91,33 +91,34 @@ pub trait IArithm {
9191
fn try_div<'o>(&self, other: Arg<'o>) -> Option<Arg<'o>>;
9292
}
9393

94-
pub trait IInvocable: Send + Sync {
94+
pub trait IInvocable {
9595
fn invoke<'r: 'rr, 'rr>(&self, args: &'rr [Arg<'r>], context: &'r Context<'r>) -> EvalResult<Arg<'r>>;
9696
}
9797

98-
pub trait IIterable: Send + Sync {
98+
pub trait IIterable {
9999
fn is_empty(&self) -> bool;
100-
fn ivalues(&self) -> VIterator;
100+
fn ivalues<'s: 'i, 'i>(&'s self) -> Box<Iterator<Item=Arg> + 'i>;
101101
}
102102

103-
pub trait IIndexable: Send + Sync {
103+
pub trait IIndexable {
104104
// fn has_index(&self, index: usize) -> bool;
105-
fn get_index(&self, index: usize) -> Option<&Arg>;
106-
// fn as_slice(&self, range: Range) -> &[BType];
105+
fn get_index(&self, index: usize) -> Option<Arg>;
106+
fn is_empty(&self) -> bool;
107107
fn len(&self) -> usize;
108+
// fn as_slice(&self) -> &[Arg];
108109
}
109110

110-
pub trait IComposable: Send + Sync {
111+
pub trait IComposable {
111112
fn get_attr(&self, id: &str) -> Option<Arg>;
112113
// fn attrs(&self) -> &[BType];
113114
}
114115

115-
pub trait IPartialEq: Send + Sync {
116+
pub trait IPartialEq {
116117
fn eq<'o>(&self, other: &'o Arg<'o>) -> bool;
117118
fn ne<'o>(&self, other: &'o Arg<'o>) -> bool { !self.eq(other) }
118119
}
119120

120-
pub trait IPartialOrd: Send + Sync {
121+
pub trait IPartialOrd {
121122
fn partial_cmp<'o>(&self, other: &'o Arg<'o>) -> Option<Ordering>;
122123
fn lt<'o>(&self, other: &'o Arg<'o>) -> Option<bool> {
123124
self.partial_cmp(other).map(|res| res == Ordering::Less)

src/types/list.rs

+87-7
Original file line numberDiff line numberDiff line change
@@ -42,28 +42,29 @@ impl <'r> AsComposable for Vec<Arg<'r>> {
4242
}
4343

4444

45-
// --------------------------------------------------------------------------------------------------------------------
46-
47-
4845
impl <'r> IIterable for Vec<Arg<'r>> {
4946
fn is_empty(&self) -> bool {
5047
Vec::is_empty(self)
5148
}
5249

53-
fn ivalues(&self) -> VIterator {
54-
VIterator { me: self.iter() }
50+
fn ivalues<'s: 'i, 'i>(&'s self) -> Box<Iterator<Item=Arg> + 'i> {
51+
box self.iter().map(Arg::to_ref)
5552
}
5653
}
5754

5855

5956
impl <'r> IIndexable for Vec<Arg<'r>> {
60-
fn get_index(&self, index: usize) -> Option<&Arg> {
61-
self.get(index)
57+
fn get_index(&self, index: usize) -> Option<Arg> {
58+
self.get(index).map(Arg::to_ref)
6259
}
6360

6461
fn len(&self) -> usize {
6562
Vec::len(self)
6663
}
64+
65+
fn is_empty(&self) -> bool {
66+
Vec::is_empty(self)
67+
}
6768
}
6869

6970

@@ -106,3 +107,82 @@ impl <'r> IComposable for Vec<Arg<'r>> {
106107
// }
107108
// }
108109
//}
110+
111+
112+
// --------------------------------------------------------------------------------------------------------------------
113+
114+
115+
impl <'r, 't> Type<'t> for &'r [Arg<'r>] {
116+
// fn clone_type(&self) -> Arg<'static> {
117+
// Arg::Owned(box self.clone())
118+
// }
119+
fn clone_type(&self) -> Arg<'static> {
120+
Arg::Owned(
121+
box self.into_iter()
122+
.map(|v| (*v).clone_type())
123+
.collect::<Vec<Arg<'static>>>()
124+
)
125+
}
126+
}
127+
128+
// todo resolve specialization conflict
129+
//impl IRender for Vec<BType> {
130+
// default fn render<'w>(&self, writer: &mut Writer<'w>) -> fmt::Result {
131+
// debug!("Default render for List {:?}", self);
132+
// write!(writer, "#List")
133+
// }
134+
//}
135+
136+
impl <'r> AsBool for &'r [Arg<'r>] {
137+
fn to_bool(&self) -> bool {
138+
!(*self).is_empty()
139+
}
140+
}
141+
142+
impl <'r> AsIterable for &'r [Arg<'r>] {
143+
fn try_as_iterable(&self) -> Option<&IIterable> {
144+
Some(self)
145+
}
146+
}
147+
148+
impl <'r> AsComposable for &'r [Arg<'r>] {
149+
fn try_as_composable(&self) -> Option<&IComposable> {
150+
Some(self)
151+
}
152+
}
153+
154+
155+
impl <'r> IIterable for &'r [Arg<'r>] {
156+
fn is_empty(&self) -> bool {
157+
(*self).is_empty()
158+
}
159+
160+
fn ivalues<'s: 'i, 'i>(&'s self) -> Box<Iterator<Item=Arg> + 'i> {
161+
box self.iter().map(Arg::to_ref)
162+
}
163+
}
164+
165+
166+
impl <'r> IIndexable for &'r [Arg<'r>] {
167+
fn get_index(&self, index: usize) -> Option<Arg> {
168+
self.get(index).map(Arg::to_ref)
169+
}
170+
171+
fn len(&self) -> usize {
172+
(*self).len()
173+
}
174+
175+
fn is_empty(&self) -> bool {
176+
(*self).is_empty()
177+
}
178+
}
179+
180+
181+
impl <'r> IComposable for &'r [Arg<'r>] {
182+
fn get_attr(&self, id: &str) -> Option<Arg> {
183+
match id {
184+
"length" => Some(ex(self.len() as i64)),
185+
_ => None
186+
}
187+
}
188+
}

0 commit comments

Comments
 (0)