@@ -18,6 +18,10 @@ pub enum Value {
18
18
Object ( Object ) ,
19
19
/// Nothing.
20
20
Nil ,
21
+ /// No content.
22
+ Empty ,
23
+ /// Evaluates to empty string.
24
+ Blank ,
21
25
}
22
26
23
27
/// Type representing a Liquid array, payload of the `Value::Array` variant
@@ -55,7 +59,7 @@ impl Value {
55
59
let arr: Vec < String > = x. iter ( ) . map ( |( k, v) | format ! ( "{}: {}" , k, v) ) . collect ( ) ;
56
60
borrow:: Cow :: Owned ( arr. join ( ", " ) )
57
61
}
58
- Value :: Nil => borrow:: Cow :: Borrowed ( "" ) ,
62
+ Value :: Nil | Value :: Empty | Value :: Blank => borrow:: Cow :: Borrowed ( "" ) ,
59
63
}
60
64
}
61
65
@@ -154,12 +158,44 @@ impl Value {
154
158
}
155
159
}
156
160
161
+ /// Extracts the empty value if it is empty
162
+ pub fn as_empty ( & self ) -> Option < ( ) > {
163
+ match * self {
164
+ Value :: Empty => Some ( ( ) ) ,
165
+ _ => None ,
166
+ }
167
+ }
168
+
169
+ /// Tests whether this value is empty
170
+ pub fn is_empty ( & self ) -> bool {
171
+ match * self {
172
+ Value :: Empty => true ,
173
+ _ => false ,
174
+ }
175
+ }
176
+
177
+ /// Extracts the blank value if it is blank
178
+ pub fn as_blank ( & self ) -> Option < ( ) > {
179
+ match * self {
180
+ Value :: Blank => Some ( ( ) ) ,
181
+ _ => None ,
182
+ }
183
+ }
184
+
185
+ /// Tests whether this value is blank
186
+ pub fn is_blank ( & self ) -> bool {
187
+ match * self {
188
+ Value :: Blank => true ,
189
+ _ => false ,
190
+ }
191
+ }
192
+
157
193
/// Evaluate using Liquid "truthiness"
158
194
pub fn is_truthy ( & self ) -> bool {
159
195
// encode Ruby truthiness: all values except false and nil are true
160
196
match * self {
161
197
Value :: Scalar ( ref x) => x. is_truthy ( ) ,
162
- Value :: Nil => false ,
198
+ Value :: Nil | Value :: Empty | Value :: Blank => false ,
163
199
_ => true ,
164
200
}
165
201
}
@@ -169,6 +205,8 @@ impl Value {
169
205
match * self {
170
206
Value :: Scalar ( ref x) => x. is_default ( ) ,
171
207
Value :: Nil => true ,
208
+ Value :: Empty => true ,
209
+ Value :: Blank => true ,
172
210
Value :: Array ( ref x) => x. is_empty ( ) ,
173
211
Value :: Object ( ref x) => x. is_empty ( ) ,
174
212
}
@@ -179,6 +217,8 @@ impl Value {
179
217
match * self {
180
218
Value :: Scalar ( ref x) => x. type_name ( ) ,
181
219
Value :: Nil => "nil" ,
220
+ Value :: Empty => "empty" ,
221
+ Value :: Blank => "blank" ,
182
222
Value :: Array ( _) => "array" ,
183
223
Value :: Object ( _) => "object" ,
184
224
}
@@ -316,7 +356,37 @@ fn value_eq(lhs: &Value, rhs: &Value) -> bool {
316
356
( & Value :: Scalar ( ref x) , & Value :: Scalar ( ref y) ) => x == y,
317
357
( & Value :: Array ( ref x) , & Value :: Array ( ref y) ) => x == y,
318
358
( & Value :: Object ( ref x) , & Value :: Object ( ref y) ) => x == y,
319
- ( & Value :: Nil , & Value :: Nil ) => true ,
359
+ ( & Value :: Nil , & Value :: Nil ) |
360
+ ( & Value :: Empty , & Value :: Empty ) |
361
+ ( & Value :: Blank , & Value :: Blank ) |
362
+ ( & Value :: Empty , & Value :: Blank ) |
363
+ ( & Value :: Blank , & Value :: Empty ) => true ,
364
+
365
+ // encode a best-guess of empty rules
366
+ // See tables in https://stackoverflow.com/questions/885414/a-concise-explanation-of-nil-v-empty-v-blank-in-ruby-on-rails
367
+ ( & Value :: Empty , & Value :: Scalar ( ref s) ) | ( & Value :: Scalar ( ref s) , & Value :: Empty ) => {
368
+ s. to_str ( ) . is_empty ( )
369
+ }
370
+ ( & Value :: Empty , & Value :: Array ( ref s) ) | ( & Value :: Array ( ref s) , & Value :: Empty ) => {
371
+ s. is_empty ( )
372
+ }
373
+ ( & Value :: Empty , & Value :: Object ( ref s) ) | ( & Value :: Object ( ref s) , & Value :: Empty ) => {
374
+ s. is_empty ( )
375
+ }
376
+
377
+ // encode a best-guess of blank rules
378
+ // See tables in https://stackoverflow.com/questions/885414/a-concise-explanation-of-nil-v-empty-v-blank-in-ruby-on-rails
379
+ ( & Value :: Nil , & Value :: Blank ) |
380
+ ( & Value :: Blank , & Value :: Nil ) => true ,
381
+ ( & Value :: Blank , & Value :: Scalar ( ref s) ) | ( & Value :: Scalar ( ref s) , & Value :: Blank ) => {
382
+ s. to_str ( ) . trim ( ) . is_empty ( ) || ! s. to_bool ( ) . unwrap_or ( true )
383
+ }
384
+ ( & Value :: Blank , & Value :: Array ( ref s) ) | ( & Value :: Array ( ref s) , & Value :: Blank ) => {
385
+ s. is_empty ( )
386
+ }
387
+ ( & Value :: Blank , & Value :: Object ( ref s) ) | ( & Value :: Object ( ref s) , & Value :: Blank ) => {
388
+ s. is_empty ( )
389
+ }
320
390
321
391
// encode Ruby truthiness: all values except false and nil are true
322
392
( & Value :: Nil , & Value :: Scalar ( ref b) ) | ( & Value :: Scalar ( ref b) , & Value :: Nil ) => {
@@ -445,4 +515,35 @@ mod test {
445
515
assert ! ( Value :: scalar( true ) != Value :: Nil ) ;
446
516
assert ! ( Value :: scalar( "" ) != Value :: Nil ) ;
447
517
}
518
+
519
+ #[ test]
520
+ fn empty_equality ( ) {
521
+ // Truth table from https://stackoverflow.com/questions/885414/a-concise-explanation-of-nil-v-empty-v-blank-in-ruby-on-rails
522
+ assert_eq ! ( Value :: Empty , Value :: Empty ) ;
523
+ assert_eq ! ( Value :: Empty , Value :: Blank ) ;
524
+ assert_eq ! ( Value :: Empty , liquid_value!( "" ) ) ;
525
+ assert_ne ! ( Value :: Empty , liquid_value!( " " ) ) ;
526
+ assert_eq ! ( Value :: Empty , liquid_value!( [ ] ) ) ;
527
+ assert_ne ! ( Value :: Empty , liquid_value!( [ nil] ) ) ;
528
+ assert_eq ! ( Value :: Empty , liquid_value!( { } ) ) ;
529
+ assert_ne ! ( Value :: Empty , liquid_value!( { "a" : nil} ) ) ;
530
+ }
531
+
532
+ #[ test]
533
+ fn blank_equality ( ) {
534
+ // Truth table from https://stackoverflow.com/questions/885414/a-concise-explanation-of-nil-v-empty-v-blank-in-ruby-on-rails
535
+ assert_eq ! ( Value :: Blank , Value :: Blank ) ;
536
+ assert_eq ! ( Value :: Blank , Value :: Empty ) ;
537
+ assert_eq ! ( Value :: Blank , liquid_value!( nil) ) ;
538
+ assert_eq ! ( Value :: Blank , liquid_value!( false ) ) ;
539
+ assert_ne ! ( Value :: Blank , liquid_value!( true ) ) ;
540
+ assert_ne ! ( Value :: Blank , liquid_value!( 0 ) ) ;
541
+ assert_ne ! ( Value :: Blank , liquid_value!( 1 ) ) ;
542
+ assert_eq ! ( Value :: Blank , liquid_value!( "" ) ) ;
543
+ assert_eq ! ( Value :: Blank , liquid_value!( " " ) ) ;
544
+ assert_eq ! ( Value :: Blank , liquid_value!( [ ] ) ) ;
545
+ assert_ne ! ( Value :: Blank , liquid_value!( [ nil] ) ) ;
546
+ assert_eq ! ( Value :: Blank , liquid_value!( { } ) ) ;
547
+ assert_ne ! ( Value :: Blank , liquid_value!( { "a" : nil} ) ) ;
548
+ }
448
549
}
0 commit comments