 9bdcbe0447
			
		
	
	9bdcbe0447
	
	
	
		
			
			Major integrations and fixes: - Added BACKBEAT SDK integration for P2P operation timing - Implemented beat-aware status tracking for distributed operations - Added Docker secrets support for secure license management - Resolved KACHING license validation via HTTPS/TLS - Updated docker-compose configuration for clean stack deployment - Disabled rollback policies to prevent deployment failures - Added license credential storage (CHORUS-DEV-MULTI-001) Technical improvements: - BACKBEAT P2P operation tracking with phase management - Enhanced configuration system with file-based secrets - Improved error handling for license validation - Clean separation of KACHING and CHORUS deployment stacks 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
		
			
				
	
	
		
			110 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			110 lines
		
	
	
		
			3.3 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
| package obj
 | |
| 
 | |
| import (
 | |
| 	"fmt"
 | |
| 	"reflect"
 | |
| 
 | |
| 	"github.com/polydawn/refmt/obj/atlas"
 | |
| 	. "github.com/polydawn/refmt/tok"
 | |
| )
 | |
| 
 | |
| type unmarshalMachineStructAtlas struct {
 | |
| 	cfg *atlas.AtlasEntry // set on initialization
 | |
| 
 | |
| 	rv         reflect.Value
 | |
| 	expectLen  int                  // Length header from mapOpen token.  If it was set, we validate it.
 | |
| 	index      int                  // Progress marker: our distance into the stream of pairs.
 | |
| 	value      bool                 // Progress marker: whether the next token is a value.
 | |
| 	fieldEntry atlas.StructMapEntry // Which field we expect next: set when consuming a key.
 | |
| }
 | |
| 
 | |
| func (mach *unmarshalMachineStructAtlas) Reset(_ *unmarshalSlab, rv reflect.Value, _ reflect.Type) error {
 | |
| 	mach.rv = rv
 | |
| 	// not necessary to reset expectLen because MapOpen tokens also consistently use the -1 convention.
 | |
| 	mach.index = -1
 | |
| 	mach.value = false
 | |
| 	return nil
 | |
| }
 | |
| 
 | |
| func (mach *unmarshalMachineStructAtlas) Step(driver *Unmarshaller, slab *unmarshalSlab, tok *Token) (done bool, err error) {
 | |
| 	// Starter state.
 | |
| 	if mach.index < 0 {
 | |
| 		switch tok.Type {
 | |
| 		case TMapOpen:
 | |
| 			// Great.  Consumed.
 | |
| 			mach.expectLen = tok.Length
 | |
| 			mach.index++
 | |
| 			return false, nil
 | |
| 		case TMapClose:
 | |
| 			return true, ErrMalformedTokenStream{tok.Type, "start of map"}
 | |
| 		case TArrOpen:
 | |
| 			return true, ErrMalformedTokenStream{tok.Type, "start of map"}
 | |
| 		case TArrClose:
 | |
| 			return true, ErrMalformedTokenStream{tok.Type, "start of map"}
 | |
| 		case TNull:
 | |
| 			mach.rv.Set(reflect.Zero(mach.rv.Type()))
 | |
| 			return true, nil
 | |
| 		default:
 | |
| 			return true, ErrMalformedTokenStream{tok.Type, "start of map"}
 | |
| 		}
 | |
| 	}
 | |
| 
 | |
| 	// Accept value:
 | |
| 	if mach.value {
 | |
| 		var child_rv reflect.Value
 | |
| 		var child_rt reflect.Type
 | |
| 		if mach.fieldEntry.Ignore {
 | |
| 			// Use a dummy slot to slurp up the value.  This could be more efficient.
 | |
| 			child_rt = reflect.TypeOf((*interface{})(nil)).Elem()
 | |
| 			child_rv = reflect.New(child_rt).Elem()
 | |
| 		} else {
 | |
| 			child_rt = mach.fieldEntry.Type
 | |
| 			child_rv = mach.fieldEntry.ReflectRoute.TraverseToValue(mach.rv)
 | |
| 		}
 | |
| 		mach.index++
 | |
| 		mach.value = false
 | |
| 		return false, driver.Recurse(
 | |
| 			tok,
 | |
| 			child_rv,
 | |
| 			child_rt,
 | |
| 			slab.requisitionMachine(child_rt),
 | |
| 		)
 | |
| 	}
 | |
| 
 | |
| 	// Accept key or end:
 | |
| 	if mach.index > 0 {
 | |
| 		slab.release()
 | |
| 	}
 | |
| 	switch tok.Type {
 | |
| 	case TMapClose:
 | |
| 		// If we got length header, validate that; error if mismatch.
 | |
| 		if mach.expectLen >= 0 {
 | |
| 			if mach.expectLen != mach.index {
 | |
| 				return true, fmt.Errorf("malformed map token stream: declared length %d, actually got %d entries", mach.expectLen, mach.index)
 | |
| 			}
 | |
| 		}
 | |
| 
 | |
| 		// Future: this would be a reasonable place to check that all required fields have been filled in, if we add such a feature.
 | |
| 
 | |
| 		return true, nil
 | |
| 	case TString:
 | |
| 		for n := 0; n < len(mach.cfg.StructMap.Fields); n++ {
 | |
| 			fieldEntry := mach.cfg.StructMap.Fields[n]
 | |
| 			if fieldEntry.SerialName != tok.Str {
 | |
| 				continue
 | |
| 			}
 | |
| 			mach.fieldEntry = fieldEntry
 | |
| 			mach.value = true
 | |
| 			break
 | |
| 		}
 | |
| 		if mach.value == false {
 | |
| 			// FUTURE: it should be configurable per atlas.StructMap whether this is considered an error or to be tolerated.
 | |
| 			// Currently we're being extremely strict about it, which is a divergence from the stdlib json behavior.
 | |
| 			return true, ErrNoSuchField{tok.Str, mach.cfg.Type.String()}
 | |
| 		}
 | |
| 	default:
 | |
| 		return true, ErrMalformedTokenStream{tok.Type, "map key"}
 | |
| 	}
 | |
| 	return false, nil
 | |
| }
 |