Skip to content

Commit

Permalink
add support for indexmap
Browse files Browse the repository at this point in the history
  • Loading branch information
hardliner66 committed Dec 22, 2023
1 parent a00b4a7 commit 0408578
Show file tree
Hide file tree
Showing 4 changed files with 104 additions and 2 deletions.
27 changes: 25 additions & 2 deletions Cargo.lock

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

1 change: 1 addition & 0 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ pre-release-replacements = [
[features]
default = ["stdlib"]
stdlib = ["liquid-lib/stdlib"]
indexmap = ["liquid-core/indexmap"]

[dependencies]
doc-comment = "0.3"
Expand Down
2 changes: 2 additions & 0 deletions crates/core/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ num-traits = "0.2"
pest = "2.0"
pest_derive = "2.0"
regex = "1.5"
indexmap = { version = "2.1.0", optional = true }

# Exposed in API
time = { version = "0.3", default-features = false, features = ["formatting", "macros", "parsing"] }
Expand All @@ -38,3 +39,4 @@ snapbox = "0.4.14"
[features]
default = []
derive = ["liquid-derive"]
indexmap = ["dep:indexmap"]
76 changes: 76 additions & 0 deletions crates/core/src/model/object/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,9 @@
pub mod map;
mod ser;

#[cfg(feature = "indexmap")]
use indexmap::IndexMap;

use std::collections::BTreeMap;
use std::collections::HashMap;
use std::fmt;
Expand Down Expand Up @@ -358,6 +361,79 @@ impl<'s, O: ObjectView> fmt::Display for ObjectRender<'s, O> {
}
}

#[cfg(feature = "indexmap")]
impl<K: ObjectIndex, V: ValueView> ValueView for IndexMap<K, V> {
fn as_debug(&self) -> &dyn fmt::Debug {
self
}

fn render(&self) -> DisplayCow<'_> {
DisplayCow::Owned(Box::new(ObjectRender { s: self }))
}
fn source(&self) -> DisplayCow<'_> {
DisplayCow::Owned(Box::new(ObjectSource { s: self }))
}
fn type_name(&self) -> &'static str {
"object"
}
fn query_state(&self, state: State) -> bool {
match state {
State::Truthy => true,
State::DefaultValue | State::Empty | State::Blank => self.is_empty(),
}
}

fn to_kstr(&self) -> KStringCow<'_> {
let s = ObjectRender { s: self }.to_string();
KStringCow::from_string(s)
}
fn to_value(&self) -> Value {
Value::Object(
self.iter()
.map(|(k, v)| (crate::model::KString::from_ref(k.as_index()), v.to_value()))
.collect(),
)
}

fn as_object(&self) -> Option<&dyn ObjectView> {
Some(self)
}
}

#[cfg(feature = "indexmap")]
impl<K: ObjectIndex, V: ValueView> ObjectView for IndexMap<K, V> {
fn as_value(&self) -> &dyn ValueView {
self
}

fn size(&self) -> i64 {
self.len() as i64
}

fn keys<'k>(&'k self) -> Box<dyn Iterator<Item = KStringCow<'k>> + 'k> {
let keys = IndexMap::keys(self).map(|s| s.as_index().into());
Box::new(keys)
}

fn values<'k>(&'k self) -> Box<dyn Iterator<Item = &'k dyn ValueView> + 'k> {
let i = IndexMap::values(self).map(as_view);
Box::new(i)
}

fn iter<'k>(&'k self) -> Box<dyn Iterator<Item = (KStringCow<'k>, &'k dyn ValueView)> + 'k> {
let i = IndexMap::iter(self).map(|(k, v)| (k.as_index().into(), as_view(v)));
Box::new(i)
}

fn contains_key(&self, index: &str) -> bool {
IndexMap::contains_key(self, index)
}

fn get<'s>(&'s self, index: &str) -> Option<&'s dyn ValueView> {
IndexMap::get(self, index).map(as_view)
}
}

#[cfg(test)]
mod test {
use super::*;
Expand Down

0 comments on commit 0408578

Please sign in to comment.