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  }