github.com/lmorg/murex@v0.0.0-20240217211045-e081c89cd4ef/lang/define_unmarshal.go (about) 1 package lang 2 3 import ( 4 "errors" 5 "fmt" 6 ) 7 8 // UnmarshalData is a global unmarshaller which should be called from within 9 // murex builtin commands (etc). 10 // See docs/apis/marshaldata.md for more details 11 func UnmarshalData(p *Process, dataType string) (v interface{}, err error) { 12 // This is one of the very few maps in Murex which isn't hidden behind a sync 13 // lock of one description or other. The rational is that even mutexes can 14 // add a noticeable overhead on the performance of tight loops and I expect 15 // this function to be called _a lot_ while also only needing to be written 16 // to via code residing in within builtin types init() function (ie while 17 // murex is effectively single threaded). So there shouldn't be any data- 18 // races -- PROVIDING developers strictly follow the pattern of only writing 19 // to this map within init() func's. 20 if Unmarshallers[dataType] == nil { 21 return nil, errors.New("I don't know how to unmarshal `" + dataType + "`") 22 } 23 24 v, err = Unmarshallers[dataType](p) 25 if err != nil { 26 return nil, errors.New("[" + dataType + " unmarshaller] " + err.Error()) 27 } 28 29 return v, nil 30 } 31 32 func UnmarshalDataBuffered(parent *Process, b []byte, dataType string) (interface{}, error) { 33 fork := parent.Fork(F_CREATE_STDIN | F_NO_STDOUT | F_NO_STDERR) 34 _, err := fork.Stdin.Write(b) 35 if err != nil { 36 return nil, fmt.Errorf("cannot write value to unmarshaller's buffer: %s", err.Error()) 37 } 38 v, err := UnmarshalData(fork.Process, dataType) 39 if err != nil { 40 return nil, fmt.Errorf("cannot unmarshal buffer: %s", err.Error()) 41 } 42 43 return v, nil 44 }