raw.go raw

   1  // Copyright (C) MongoDB, Inc. 2017-present.
   2  //
   3  // Licensed under the Apache License, Version 2.0 (the "License"); you may
   4  // not use this file except in compliance with the License. You may obtain
   5  // a copy of the License at http://www.apache.org/licenses/LICENSE-2.0
   6  
   7  package bson
   8  
   9  import (
  10  	"errors"
  11  	"io"
  12  
  13  	"go.mongodb.org/mongo-driver/x/bsonx/bsoncore"
  14  )
  15  
  16  // ErrNilReader indicates that an operation was attempted on a nil bson.Reader.
  17  var ErrNilReader = errors.New("nil reader")
  18  
  19  // Raw is a raw encoded BSON document. It can be used to delay BSON document decoding or precompute
  20  // a BSON encoded document.
  21  //
  22  // A Raw must be a full BSON document. Use the RawValue type for individual BSON values.
  23  type Raw []byte
  24  
  25  // ReadDocument reads a BSON document from the io.Reader and returns it as a bson.Raw. If the
  26  // reader contains multiple BSON documents, only the first document is read.
  27  func ReadDocument(r io.Reader) (Raw, error) {
  28  	doc, err := bsoncore.NewDocumentFromReader(r)
  29  	return Raw(doc), err
  30  }
  31  
  32  // NewFromIOReader reads a BSON document from the io.Reader and returns it as a bson.Raw. If the
  33  // reader contains multiple BSON documents, only the first document is read.
  34  //
  35  // Deprecated: Use ReadDocument instead.
  36  func NewFromIOReader(r io.Reader) (Raw, error) {
  37  	return ReadDocument(r)
  38  }
  39  
  40  // Validate validates the document. This method only validates the first document in
  41  // the slice, to validate other documents, the slice must be resliced.
  42  func (r Raw) Validate() (err error) { return bsoncore.Document(r).Validate() }
  43  
  44  // Lookup search the document, potentially recursively, for the given key. If
  45  // there are multiple keys provided, this method will recurse down, as long as
  46  // the top and intermediate nodes are either documents or arrays.If an error
  47  // occurs or if the value doesn't exist, an empty RawValue is returned.
  48  func (r Raw) Lookup(key ...string) RawValue {
  49  	return convertFromCoreValue(bsoncore.Document(r).Lookup(key...))
  50  }
  51  
  52  // LookupErr searches the document and potentially subdocuments or arrays for the
  53  // provided key. Each key provided to this method represents a layer of depth.
  54  func (r Raw) LookupErr(key ...string) (RawValue, error) {
  55  	val, err := bsoncore.Document(r).LookupErr(key...)
  56  	return convertFromCoreValue(val), err
  57  }
  58  
  59  // Elements returns this document as a slice of elements. The returned slice will contain valid
  60  // elements. If the document is not valid, the elements up to the invalid point will be returned
  61  // along with an error.
  62  func (r Raw) Elements() ([]RawElement, error) {
  63  	doc := bsoncore.Document(r)
  64  	if len(doc) == 0 {
  65  		return nil, nil
  66  	}
  67  	elems, err := doc.Elements()
  68  	if err != nil {
  69  		return nil, err
  70  	}
  71  	relems := make([]RawElement, 0, len(elems))
  72  	for _, elem := range elems {
  73  		relems = append(relems, RawElement(elem))
  74  	}
  75  	return relems, nil
  76  }
  77  
  78  // Values returns this document as a slice of values. The returned slice will contain valid values.
  79  // If the document is not valid, the values up to the invalid point will be returned along with an
  80  // error.
  81  func (r Raw) Values() ([]RawValue, error) {
  82  	vals, err := bsoncore.Document(r).Values()
  83  	rvals := make([]RawValue, 0, len(vals))
  84  	for _, val := range vals {
  85  		rvals = append(rvals, convertFromCoreValue(val))
  86  	}
  87  	return rvals, err
  88  }
  89  
  90  // Index searches for and retrieves the element at the given index. This method will panic if
  91  // the document is invalid or if the index is out of bounds.
  92  func (r Raw) Index(index uint) RawElement { return RawElement(bsoncore.Document(r).Index(index)) }
  93  
  94  // IndexErr searches for and retrieves the element at the given index.
  95  func (r Raw) IndexErr(index uint) (RawElement, error) {
  96  	elem, err := bsoncore.Document(r).IndexErr(index)
  97  	return RawElement(elem), err
  98  }
  99  
 100  // String returns the BSON document encoded as Extended JSON.
 101  func (r Raw) String() string { return bsoncore.Document(r).String() }
 102