github.com/ipld/go-ipld-prime@v0.21.0/fluent/qp/qp.go (about)

     1  // qp helps to quickly build IPLD nodes.
     2  //
     3  // It contains top-level Build funcs, such as BuildMap and BuildList, which
     4  // return the final node as well as an error.
     5  //
     6  // Underneath, one can use a number of Assemble functions to construct basic
     7  // nodes, such as String or Int.
     8  //
     9  // Finally, functions like MapEntry and ListEntry allow inserting into maps and
    10  // lists.
    11  //
    12  // These all use the same IPLD datamodel interfaces such as NodePrototype and
    13  // NodeAssembler, but with some magic to reduce verbosity.
    14  package qp
    15  
    16  import (
    17  	"fmt"
    18  
    19  	"github.com/ipld/go-ipld-prime/datamodel"
    20  )
    21  
    22  type Assemble = func(datamodel.NodeAssembler)
    23  
    24  func BuildMap(np datamodel.NodePrototype, sizeHint int64, fn func(datamodel.MapAssembler)) (_ datamodel.Node, err error) {
    25  	defer func() {
    26  		if r := recover(); r != nil {
    27  			if rerr, ok := r.(error); ok {
    28  				err = rerr
    29  			} else {
    30  				// A reasonable fallback, for e.g. strings.
    31  				err = fmt.Errorf("%v", r)
    32  			}
    33  		}
    34  	}()
    35  	nb := np.NewBuilder()
    36  	Map(sizeHint, fn)(nb)
    37  	return nb.Build(), nil
    38  }
    39  
    40  type mapParams struct {
    41  	sizeHint int64
    42  	fn       func(datamodel.MapAssembler)
    43  }
    44  
    45  func (mp mapParams) Assemble(na datamodel.NodeAssembler) {
    46  	ma, err := na.BeginMap(mp.sizeHint)
    47  	if err != nil {
    48  		panic(err)
    49  	}
    50  	mp.fn(ma)
    51  	if err := ma.Finish(); err != nil {
    52  		panic(err)
    53  	}
    54  }
    55  
    56  func Map(sizeHint int64, fn func(datamodel.MapAssembler)) Assemble {
    57  	return mapParams{sizeHint, fn}.Assemble
    58  }
    59  
    60  func MapEntry(ma datamodel.MapAssembler, k string, fn Assemble) {
    61  	na, err := ma.AssembleEntry(k)
    62  	if err != nil {
    63  		panic(err)
    64  	}
    65  	fn(na)
    66  }
    67  
    68  func BuildList(np datamodel.NodePrototype, sizeHint int64, fn func(datamodel.ListAssembler)) (_ datamodel.Node, err error) {
    69  	defer func() {
    70  		if r := recover(); r != nil {
    71  			if rerr, ok := r.(error); ok {
    72  				err = rerr
    73  			} else {
    74  				// A reasonable fallback, for e.g. strings.
    75  				err = fmt.Errorf("%v", r)
    76  			}
    77  		}
    78  	}()
    79  	nb := np.NewBuilder()
    80  	List(sizeHint, fn)(nb)
    81  	return nb.Build(), nil
    82  }
    83  
    84  type listParams struct {
    85  	sizeHint int64
    86  	fn       func(datamodel.ListAssembler)
    87  }
    88  
    89  func (lp listParams) Assemble(na datamodel.NodeAssembler) {
    90  	la, err := na.BeginList(lp.sizeHint)
    91  	if err != nil {
    92  		panic(err)
    93  	}
    94  	lp.fn(la)
    95  	if err := la.Finish(); err != nil {
    96  		panic(err)
    97  	}
    98  }
    99  
   100  func List(sizeHint int64, fn func(datamodel.ListAssembler)) Assemble {
   101  	return listParams{sizeHint, fn}.Assemble
   102  }
   103  
   104  func ListEntry(la datamodel.ListAssembler, fn Assemble) {
   105  	fn(la.AssembleValue())
   106  }
   107  
   108  type nullParam struct{}
   109  
   110  func (s nullParam) Assemble(na datamodel.NodeAssembler) {
   111  	if err := na.AssignNull(); err != nil {
   112  		panic(err)
   113  	}
   114  }
   115  
   116  func Null() Assemble {
   117  	return nullParam{}.Assemble
   118  }
   119  
   120  type boolParam bool
   121  
   122  func (s boolParam) Assemble(na datamodel.NodeAssembler) {
   123  	if err := na.AssignBool(bool(s)); err != nil {
   124  		panic(err)
   125  	}
   126  }
   127  
   128  func Bool(b bool) Assemble {
   129  	return boolParam(b).Assemble
   130  }
   131  
   132  type intParam int64
   133  
   134  func (i intParam) Assemble(na datamodel.NodeAssembler) {
   135  	if err := na.AssignInt(int64(i)); err != nil {
   136  		panic(err)
   137  	}
   138  }
   139  
   140  func Int(i int64) Assemble {
   141  	return intParam(i).Assemble
   142  }
   143  
   144  type floatParam float64
   145  
   146  func (f floatParam) Assemble(na datamodel.NodeAssembler) {
   147  	if err := na.AssignFloat(float64(f)); err != nil {
   148  		panic(err)
   149  	}
   150  }
   151  
   152  func Float(f float64) Assemble {
   153  	return floatParam(f).Assemble
   154  }
   155  
   156  type stringParam string
   157  
   158  func (s stringParam) Assemble(na datamodel.NodeAssembler) {
   159  	if err := na.AssignString(string(s)); err != nil {
   160  		panic(err)
   161  	}
   162  }
   163  
   164  func String(s string) Assemble {
   165  	return stringParam(s).Assemble
   166  }
   167  
   168  type bytesParam []byte
   169  
   170  func (p bytesParam) Assemble(na datamodel.NodeAssembler) {
   171  	if err := na.AssignBytes([]byte(p)); err != nil {
   172  		panic(err)
   173  	}
   174  }
   175  
   176  func Bytes(p []byte) Assemble {
   177  	return bytesParam(p).Assemble
   178  }
   179  
   180  type linkParam struct {
   181  	x datamodel.Link
   182  }
   183  
   184  func (l linkParam) Assemble(na datamodel.NodeAssembler) {
   185  	if err := na.AssignLink(l.x); err != nil {
   186  		panic(err)
   187  	}
   188  }
   189  
   190  func Link(l datamodel.Link) Assemble {
   191  	return linkParam{l}.Assemble
   192  }
   193  
   194  type nodeParam struct {
   195  	x datamodel.Node
   196  }
   197  
   198  func (n nodeParam) Assemble(na datamodel.NodeAssembler) {
   199  	if err := na.AssignNode(n.x); err != nil {
   200  		panic(err)
   201  	}
   202  }
   203  
   204  func Node(n datamodel.Node) Assemble {
   205  	return nodeParam{n}.Assemble
   206  }