Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(value): Add null value #140

Merged
merged 1 commit into from
Oct 30, 2017
Merged

Conversation

gnunicorn
Copy link
Contributor

This adds the missing null type to the values of liquid, thus allowing to
parse serde_json and others containing null-values in the data directly

@epage
Copy link
Member

epage commented Oct 27, 2017

My hope has been to avoid the billion dollar mistake.

Is there a use case for you to have null in your data?

@gnunicorn
Copy link
Contributor Author

Well, this is for parsing data in cobalt, where any json can contain a null value and serde currently refuses to load the data into value then -- giving you rather obscure errors.

I don't think we are repeating that case here but are downwards compatible to those formats. We aren't repeating that problem, as all values have a way to be checked for being empty and will before interacting with it and null.

I see your point that this might not be something we want in liquid though and therefore should be handled inside cobalt (where I'd argue, we should be able to parse any valid JSON and null is a valid JSON value). If you agree on that we might want to discuss how to do that though: can we extend the serde-parsing into Value from cobalt? Then we could just use false. But I'd need some hints on how to achieve that.

@epage
Copy link
Member

epage commented Oct 27, 2017

What is the reason for having null in your cobalt data? Is it because you are loading a existing data source and don't plan to touch the null part of the data? Do you need to touch the null part and need liquid to handle it gracefully?

I see your point that this might not be something we want in liquid though and therefore should be handled inside cobalt (where I'd argue, we should be able to parse any valid JSON and null is a valid JSON value).

Really, the question is whether we are loading arbitrary json/yaml/toml or loading liquid values. My initial impression is to load liquid Values unless someone has a reasonable use case that can't be supported.

@epage
Copy link
Member

epage commented Oct 27, 2017

for AreWebYet I am just downloading crates.io JSON-dumps of packages and put them into the data folder. Those can and do contain null values (e.g. https://github.com/bashyHQ/arewewebyet/blob/gh-pages/_data/pkgs/afterparty.json )

Thanks for the use case. I am fine moving forward with this.

@gnunicorn gnunicorn force-pushed the add-null-value branch 2 times, most recently from 52de3ef to 7cda923 Compare October 30, 2017 17:14
@gnunicorn
Copy link
Contributor Author

@epage it's green.

Copy link
Member

@epage epage left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, I know I said we just needed green. If you want, this can go in now and we can open issues on these comments.

src/value.rs Outdated
@@ -164,6 +165,7 @@ impl ToString for Value {
Value::Num(ref x) => x.to_string(),
Value::Bool(ref x) => x.to_string(),
Value::Str(ref x) => x.to_owned(),
Value::Null => "null".to_owned(),
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sorry, just thought about this last night. Are we aligned with Shopify on this?

Does it matter?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I am not sure, what we use the ToString for within templates. From the Shopify docs it is rather vague how this would come to be used. In their cheat sheet they only explain Nil to be falsy and all other of their filters and loops seem to make a check for truthy-ness before executing, which probably stems from that being the implied case in ruby. And is already a behavior we don't have that way (which we discussed the other day).

I am also happy to make it "", which is probably closer to the interpretation of their underlying ruby implementation...

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You're link answered the question of what ToString should do

Tags or outputs that return nil will not print anything to the page.

https://help.shopify.com/themes/liquid/basics/types#nil

btw if Shopify calls it Nil then we probably should too (Value::Nil).

src/value.rs Outdated
@@ -16,6 +16,7 @@ pub enum Value {
Str(String),
Array(Array),
Object(Object),
Null,
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder how serde decides that None gets serialized as this.

We should add a serde test for this
https://github.com/cobalt-org/liquid-rust/blob/master/tests/value.rs

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I honestly have no idea. I don't really get the inner-workings of serde -- but it is on my bucket list :D .

I used serde_json as the base and it defined Null in their value and in JSON there also is no None but only null. For TOML and YAML I am not even sure a nothing-type even exists, I think it is just represented as empty strings ...

@epage
Copy link
Member

epage commented Oct 30, 2017

Thanks for making the changes!

@gnunicorn
Copy link
Contributor Author

@epage don't be too happy to soon. I pushed before fixing the commit logs because the tests is going mad on me and wanted your input on it:

running 2 tests
test serialize_nil ... ok
test deserialize_nil ... FAILED

failures:

---- deserialize_nil stdout ----
	thread 'deserialize_nil' panicked at 'assertion failed: `(left == right)`
  left: `Nil`,
 right: `Nil`', tests/value.rs:79:4
note: Run with `RUST_BACKTRACE=1` for a backtrace.


failures:
    deserialize_nil

test result: FAILED. 1 passed; 1 failed; 0 ignored; 0 measured; 10 filtered out

Any ideas?

@epage
Copy link
Member

epage commented Oct 30, 2017

I wonder if actual is a liquid::Str.

This adds the missing Nil (null) type to the values of liquid, thus allowing
to parse serde_json and others containing null-values in the data directly
@epage epage merged commit bf67d97 into cobalt-org:master Oct 30, 2017
@epage
Copy link
Member

epage commented Oct 30, 2017

I assume you'd like me to publish liquid and cobalt with this as soon as possible?

epage added a commit that referenced this pull request Nov 8, 2017
* **syntax:** Add `arr[0]` and `obj["name"]` indexing (PR #141, fixes #127)
* **value:**  Add nil value to support foreign data (PR #140)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants