Skip to content

Commit

Permalink
feat: skip attribute for for function
Browse files Browse the repository at this point in the history
  • Loading branch information
w-henderson committed Jul 15, 2023
1 parent 7cc02ec commit 67aa4c9
Show file tree
Hide file tree
Showing 8 changed files with 47 additions and 12 deletions.
4 changes: 2 additions & 2 deletions Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -221,7 +221,7 @@ Stuart currently supports the following functions:
| `end` | Ends a section or another function. | `end("section_name")`, `end(function_name)` |
| `insert` | Inserts a section into the template, only used in `root.html`. | `insert("section_name")` |
| `import` | Imports a JSON file as a variable. | `import($data, "data.json")` |
| `for` | Iterates over a JSON array or a directory of markdown files. The loop is ended with `end(for)`. | `for($tag, "tags.json")`, `for($post, "posts/", limit=3, order="desc", sortby="date")`, `for($item, $array)` |
| `for` | Iterates over a JSON array or a directory of markdown files. The loop is ended with `end(for)`. | `for($tag, "tags.json")`, `for($post, "posts/", skip=3, limit=3, order="desc", sortby="date")`, `for($item, $array)` |
| `dateformat` | Formats a date using the [chrono](https://docs.rs/chrono/0.4.19/chrono/format/strftime/index.html) format string. The date input can be any kind of formatted date or timestamp. | `dateformat($date, "%Y-%m-%d")` |
| `if[eq,ne,gt,ge,lt,le]` | Performs a comparison between two values. The block is ended with `end(if[eq,ne,...])`. | `ifeq($a, $b)`, `ifge($age, 18)` |
| `ifdefined` | Checks if a variable is defined. The block is ended with `end(ifdefined)`. | `ifdefined($variable)`, `ifdefined($variable.property)` |
Expand Down
2 changes: 1 addition & 1 deletion stuart-core/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "stuart_core"
version = "0.2.4"
version = "0.2.5"
edition = "2021"
license = "MIT"
homepage = "https://github.com/w-henderson/Stuart"
Expand Down
32 changes: 26 additions & 6 deletions stuart-core/src/functions/parsers/for.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,8 @@ pub struct ForFunction {
variable_name: String,
source: String,
source_type: ForFunctionSourceType,
limit: Option<u16>,
skip: Option<usize>,
limit: Option<usize>,
sort_variable: Option<String>,
sort_order: SortOrder,
}
Expand Down Expand Up @@ -65,12 +66,24 @@ impl FunctionParser for ForParser {
ForFunctionSourceType::JSONObject
};

let mut skip = None;
let mut limit = None;
let mut sort_variable = None;
let mut sort_order = SortOrder::Asc;

for (name, arg) in &raw.named_args {
match name.as_str() {
"skip" => {
quiet_assert!(arg.as_integer().is_some())?;
quiet_assert!(skip.is_none())?;

skip = Some(
arg.as_integer()
.unwrap()
.try_into()
.map_err(|_| ParseError::InvalidArgument)?,
);
}
"limit" => {
quiet_assert!(arg.as_integer().is_some())?;
quiet_assert!(limit.is_none())?;
Expand Down Expand Up @@ -103,6 +116,7 @@ impl FunctionParser for ForParser {
variable_name: variable_name.to_string(),
source,
source_type,
skip,
limit,
sort_variable,
sort_order,
Expand Down Expand Up @@ -201,13 +215,19 @@ impl Function for ForFunction {
});
}

let variable_iter: Box<dyn Iterator<Item = Value>> = match (self.limit, self.sort_order) {
(None, SortOrder::Asc) => Box::new(variables.into_iter()),
(None, SortOrder::Desc) => Box::new(variables.into_iter().rev()),
(Some(l), SortOrder::Asc) => Box::new(variables.into_iter().take(l as usize)),
(Some(l), SortOrder::Desc) => Box::new(variables.into_iter().rev().take(l as usize)),
let mut variable_iter: Box<dyn Iterator<Item = Value>> = match self.sort_order {
SortOrder::Asc => Box::new(variables.into_iter()),
SortOrder::Desc => Box::new(variables.into_iter().rev()),
};

if let Some(s) = self.skip {
variable_iter = Box::new(variable_iter.skip(s));
}

if let Some(l) = self.limit {
variable_iter = Box::new(variable_iter.take(l));
}

for variable in variable_iter {
scope.tokens.rewind_to(waypoint);

Expand Down
1 change: 1 addition & 0 deletions stuart-core/src/tests/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ define_testcases![
for_loop_json_file,
for_loop_json_object,
for_loop_nested,
for_loop_skip_limit,
dateformat,
excerpt,
ifdefined,
Expand Down
7 changes: 7 additions & 0 deletions stuart-core/src/tests/testcases/for_loop_skip_limit/in.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{{ begin("main") }}
<ul>
{{ for($country, "data.json", skip=1, limit=1) }}
<li>{{ $country.name }}</li>
{{ end(for) }}
</ul>
{{ end("main") }}
7 changes: 7 additions & 0 deletions stuart-core/src/tests/testcases/for_loop_skip_limit/out.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
<html>
<body>
<ul>
<li>United States</li>
</ul>
</body>
</html>
4 changes: 2 additions & 2 deletions stuart/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "stuart"
version = "0.2.4"
version = "0.2.5"
edition = "2021"
license = "MIT"
homepage = "https://github.com/w-henderson/Stuart"
Expand All @@ -15,7 +15,7 @@ name = "stuart"
path = "src/main.rs"

[dependencies]
stuart_core = { version = "^0.2.4", path = "../stuart-core" }
stuart_core = { version = "^0.2.5", path = "../stuart-core" }

clap = "^3.2"
toml = "^0.5"
Expand Down

0 comments on commit 67aa4c9

Please sign in to comment.