@@ -3,11 +3,11 @@ use std::collections::HashMap;
33
44use anathema_state:: { Color , Hex , PendingValue , SubTo , Subscriber , Type } ;
55use anathema_store:: slab:: Key ;
6- use anathema_templates:: Primitive ;
76use anathema_templates:: expressions:: { Equality , LogicalOp , Op } ;
7+ use anathema_templates:: Primitive ;
88
9- use crate :: AttributeStorage ;
109use crate :: value:: ValueKind ;
10+ use crate :: AttributeStorage ;
1111
1212macro_rules! or_null {
1313 ( $val: expr) => {
@@ -18,13 +18,13 @@ macro_rules! or_null {
1818 } ;
1919}
2020
21- pub struct ValueThingy < ' a , ' bp > {
22- sub : Subscriber ,
23- sub_to : & ' a mut SubTo ,
21+ pub struct ValueResolutionContext < ' a , ' bp > {
22+ pub ( crate ) sub : Subscriber ,
23+ pub ( crate ) sub_to : & ' a mut SubTo ,
2424 attribute_storage : & ' a AttributeStorage < ' bp > ,
2525}
2626
27- impl < ' a , ' bp > ValueThingy < ' a , ' bp > {
27+ impl < ' a , ' bp > ValueResolutionContext < ' a , ' bp > {
2828 pub fn new ( attribute_storage : & ' a AttributeStorage < ' bp > , sub : Subscriber , sub_to : & ' a mut SubTo ) -> Self {
2929 Self {
3030 attribute_storage,
@@ -127,7 +127,7 @@ impl<'bp> From<PendingValue> for ValueExpr<'bp> {
127127}
128128
129129// Resolve an expression to a value kind, this is the final value in the chain
130- pub ( crate ) fn resolve_value < ' a , ' bp > ( value_expr : & ValueExpr < ' bp > , ctx : & mut ValueThingy < ' a , ' bp > ) -> ValueKind < ' bp > {
130+ pub ( crate ) fn resolve_value < ' a , ' bp > ( value_expr : & ValueExpr < ' bp > , ctx : & mut ValueResolutionContext < ' a , ' bp > ) -> ValueKind < ' bp > {
131131 match value_expr {
132132 // -----------------------------------------------------------------------------
133133 // - Primitives -
@@ -255,7 +255,8 @@ pub(crate) fn resolve_value<'a, 'bp>(value_expr: &ValueExpr<'bp>, ctx: &mut Valu
255255 // -----------------------------------------------------------------------------
256256 // - Maps and lists -
257257 // -----------------------------------------------------------------------------
258- ValueExpr :: DynMap ( _) | ValueExpr :: Map ( _) => ValueKind :: Map ,
258+ ValueExpr :: Map ( _) => ValueKind :: Map ,
259+ ValueExpr :: DynMap ( map) => ValueKind :: DynMap ( * map) ,
259260 ValueExpr :: Attributes ( _) => ValueKind :: Attributes ,
260261 ValueExpr :: DynList ( value) => {
261262 value. subscribe ( ctx. sub ) ;
@@ -270,7 +271,7 @@ pub(crate) fn resolve_value<'a, 'bp>(value_expr: &ValueExpr<'bp>, ctx: &mut Valu
270271 let expr = resolve_index ( src, index, ctx) ;
271272 resolve_value ( & expr, ctx)
272273 }
273- ValueExpr :: Composite ( _ ) => ValueKind :: Composite ,
274+ ValueExpr :: Composite ( comp ) => ValueKind :: Composite ( * comp ) ,
274275
275276 // -----------------------------------------------------------------------------
276277 // - Call -
@@ -299,7 +300,7 @@ fn resolve_pending(val: PendingValue) -> ValueExpr<'static> {
299300 }
300301}
301302
302- fn resolve_index < ' bp > ( src : & ValueExpr < ' bp > , index : & ValueExpr < ' bp > , ctx : & mut ValueThingy < ' _ , ' bp > ) -> ValueExpr < ' bp > {
303+ fn resolve_index < ' bp > ( src : & ValueExpr < ' bp > , index : & ValueExpr < ' bp > , ctx : & mut ValueResolutionContext < ' _ , ' bp > ) -> ValueExpr < ' bp > {
303304 match src {
304305 ValueExpr :: DynMap ( value) | ValueExpr :: Composite ( value) => {
305306 let s = or_null ! ( value. as_state( ) ) ;
@@ -371,11 +372,11 @@ fn resolve_index<'bp>(src: &ValueExpr<'bp>, index: &ValueExpr<'bp>, ctx: &mut Va
371372 resolve_index ( & src, index, ctx)
372373 }
373374 ValueExpr :: Null => ValueExpr :: Null ,
374- val => unreachable ! ( "resolving index: this should return null eventually: {val:?}" ) ,
375+ val => unreachable ! ( "resolving index: this should return null eventually: {val:?} (you probably did something like x.y on a string) " ) ,
375376 }
376377}
377378
378- fn resolve_expr < ' a , ' bp > ( expr : & ' a ValueExpr < ' bp > , ctx : & mut ValueThingy < ' _ , ' bp > ) -> Option < ValueExpr < ' bp > > {
379+ fn resolve_expr < ' a , ' bp > ( expr : & ' a ValueExpr < ' bp > , ctx : & mut ValueResolutionContext < ' _ , ' bp > ) -> Option < ValueExpr < ' bp > > {
379380 match expr {
380381 ValueExpr :: Either ( first, second) => match resolve_expr ( first, ctx) {
381382 None | Some ( ValueExpr :: Null ) => resolve_expr ( second, ctx) ,
@@ -386,7 +387,7 @@ fn resolve_expr<'a, 'bp>(expr: &'a ValueExpr<'bp>, ctx: &mut ValueThingy<'_, 'bp
386387 }
387388}
388389
389- fn resolve_str < ' a , ' bp > ( index : & ' a ValueExpr < ' bp > , ctx : & mut ValueThingy < ' _ , ' bp > ) -> Option < Kind < & ' bp str > > {
390+ fn resolve_str < ' a , ' bp > ( index : & ' a ValueExpr < ' bp > , ctx : & mut ValueResolutionContext < ' _ , ' bp > ) -> Option < Kind < & ' bp str > > {
390391 match index {
391392 ValueExpr :: Str ( kind) => Some ( * kind) ,
392393 ValueExpr :: Index ( src, index) => match resolve_index ( src, index, ctx) {
@@ -400,7 +401,7 @@ fn resolve_str<'a, 'bp>(index: &'a ValueExpr<'bp>, ctx: &mut ValueThingy<'_, 'bp
400401 }
401402}
402403
403- fn resolve_int < ' a , ' bp > ( index : & ' a ValueExpr < ' bp > , ctx : & mut ValueThingy < ' _ , ' bp > ) -> i64 {
404+ fn resolve_int < ' a , ' bp > ( index : & ' a ValueExpr < ' bp > , ctx : & mut ValueResolutionContext < ' _ , ' bp > ) -> i64 {
404405 let value = resolve_value ( index, ctx) ;
405406 match value {
406407 ValueKind :: Int ( index) => index,
@@ -411,9 +412,10 @@ fn resolve_int<'a, 'bp>(index: &'a ValueExpr<'bp>, ctx: &mut ValueThingy<'_, 'bp
411412 | ValueKind :: Hex ( _)
412413 | ValueKind :: Color ( _)
413414 | ValueKind :: Str ( _)
414- | ValueKind :: Composite
415+ | ValueKind :: Composite ( _ )
415416 | ValueKind :: Null
416417 | ValueKind :: Map
418+ | ValueKind :: DynMap ( _)
417419 | ValueKind :: Attributes
418420 | ValueKind :: List ( _)
419421 | ValueKind :: DynList ( _) => todo ! ( "resolving int: the value is {value:?}" ) ,
@@ -442,7 +444,7 @@ fn float_op(lhs: f64, rhs: f64, op: Op) -> f64 {
442444
443445#[ cfg( test) ]
444446mod test {
445- use anathema_state:: { Changes , States , drain_changes } ;
447+ use anathema_state:: { drain_changes , Changes , Map , States } ;
446448 use anathema_templates:: expressions:: { ident, index, num, strlit} ;
447449
448450 use crate :: testing:: setup;
@@ -500,14 +502,34 @@ mod test {
500502
501503 drain_changes ( & mut changes) ;
502504 for ( subs, _) in changes. drain ( ) {
503- for sub in subs. iter ( ) {
504- if sub == value. sub {
505- value. reload ( & test. attributes ) ;
506- }
505+ if subs. iter ( ) . any ( |sub| sub == value. sub ) {
506+ value. reload ( & test. attributes ) ;
507507 }
508508 }
509-
510509 assert_eq ! ( value. as_str( ) . unwrap( ) , "c" ) ;
511510 } ) ;
512511 }
512+
513+ #[ test]
514+ fn optional_map_from_empty_to_value ( ) {
515+ let mut changes = Changes :: empty ( ) ;
516+
517+ let mut states = States :: new ( ) ;
518+ setup ( & mut states, Default :: default ( ) , |test| {
519+ // let expr = index(index(ident("state"), strlit("opt_map")), strlit("key"));
520+ let expr = index ( ident ( "state" ) , strlit ( "opt_map" ) ) ;
521+
522+ let mut value = test. eval ( & expr) ;
523+ assert ! ( value. as_str( ) . is_none( ) ) ;
524+
525+ test. with_state ( |state| {
526+ let mut map = Map :: empty ( ) ;
527+ map. insert ( "key" , 123 ) ;
528+ state. opt_map . set ( Some ( map) ) ;
529+ } ) ;
530+
531+ drain_changes ( & mut changes) ;
532+ assert ! ( !changes. is_empty( ) ) ;
533+ } ) ;
534+ }
513535}
0 commit comments