11use pyo3:: { Bound , PyResult , Python } ;
22use pyo3:: prelude:: PyDictMethods ;
33use pyo3:: types:: PyDict ;
4-
4+ use crate :: retrievers :: retriever :: RetState ;
55use crate :: types:: base_struct:: BaseStruct ;
66use crate :: types:: diff:: diff:: { Diff , Diffable , IDiff } ;
77use crate :: types:: diff:: merge:: { Conflict , Mergeable } ;
@@ -24,13 +24,35 @@ impl Mergeable<ParseableType> for StructMergeable<'_, '_> {
2424 _off : isize
2525 ) -> isize {
2626 let mut inner = self . 1 . inner_mut ( ) ;
27- let data = & mut inner. data ;
27+ let ( data, repeats , _ ) = inner. split ( ) ;
2828 match change {
2929 Diff :: None => _off,
3030 Diff :: Inserted ( _val) | Diff :: Deleted ( _val) => {
3131 unreachable ! ( "BFP Internal Error: merge called on structs of different versions" )
3232 }
3333 Diff :: Changed ( val) => {
34+ let retriever = & self . 0 . retrievers ( ) [ idx] ;
35+ match retriever. state ( repeats) {
36+ RetState :: Value | RetState :: NoneValue if val. is_none ( ) => {
37+ repeats[ idx] = Some ( -1 ) ;
38+ }
39+ RetState :: Value | RetState :: NoneValue => {
40+ repeats[ idx] = None ;
41+ }
42+ RetState :: List | RetState :: NoneList if val. is_none ( ) => {
43+ repeats[ idx] = Some ( -2 ) ;
44+ }
45+ RetState :: List | RetState :: NoneList => {
46+ let repeat = retriever. repeat ( repeats) ;
47+ let len = val. try_len ( )
48+ . expect ( "non-null value coming from another struct must be of the correct type" ) as isize ;
49+ if repeat == -2 {
50+ repeats[ idx] = Some ( len) ;
51+ } else if repeats[ idx] . is_none ( ) && repeat != len {
52+ unreachable ! ( "BFP Internal Error: Non-null value coming from another struct must be of the correct type" )
53+ }
54+ }
55+ } ;
3456 data[ idx] = Some ( val) ;
3557 _off
3658 }
0 commit comments