github.com/MontFerret/ferret@v0.18.0/pkg/drivers/selector.go (about)

     1  package drivers
     2  
     3  import (
     4  	"hash/fnv"
     5  
     6  	"github.com/wI2L/jettison"
     7  
     8  	"github.com/MontFerret/ferret/pkg/runtime/core"
     9  	"github.com/MontFerret/ferret/pkg/runtime/values"
    10  )
    11  
    12  type (
    13  	QuerySelectorKind int
    14  
    15  	QuerySelector struct {
    16  		core.Value
    17  		kind  QuerySelectorKind
    18  		value values.String
    19  	}
    20  )
    21  
    22  const (
    23  	UnknownSelector QuerySelectorKind = iota
    24  	CSSSelector
    25  	XPathSelector
    26  )
    27  
    28  var (
    29  	qsvStr = map[QuerySelectorKind]string{
    30  		UnknownSelector: "unknown",
    31  		CSSSelector:     "css",
    32  		XPathSelector:   "xpath",
    33  	}
    34  )
    35  
    36  func (v QuerySelectorKind) String() string {
    37  	str, found := qsvStr[v]
    38  
    39  	if found {
    40  		return str
    41  	}
    42  
    43  	return qsvStr[UnknownSelector]
    44  }
    45  
    46  func NewCSSSelector(value values.String) QuerySelector {
    47  	return QuerySelector{
    48  		kind:  CSSSelector,
    49  		value: value,
    50  	}
    51  }
    52  
    53  func NewXPathSelector(value values.String) QuerySelector {
    54  	return QuerySelector{
    55  		kind:  XPathSelector,
    56  		value: value,
    57  	}
    58  }
    59  
    60  func (q QuerySelector) Kind() QuerySelectorKind {
    61  	return q.kind
    62  }
    63  
    64  func (q QuerySelector) MarshalJSON() ([]byte, error) {
    65  	return jettison.MarshalOpts(map[string]string{
    66  		"kind":  q.kind.String(),
    67  		"value": q.value.String(),
    68  	}, jettison.NoHTMLEscaping())
    69  }
    70  
    71  func (q QuerySelector) Type() core.Type {
    72  	return QuerySelectorType
    73  }
    74  
    75  func (q QuerySelector) String() string {
    76  	return q.value.String()
    77  }
    78  
    79  func (q QuerySelector) Compare(other core.Value) int64 {
    80  	if other.Type() != QuerySelectorType {
    81  		return Compare(QuerySelectorType, other.Type())
    82  	}
    83  
    84  	otherQS := other.(*QuerySelector)
    85  
    86  	if q.kind == otherQS.Kind() {
    87  		return q.value.Compare(values.NewString(otherQS.String()))
    88  	}
    89  
    90  	if q.kind == CSSSelector {
    91  		return -1
    92  	}
    93  
    94  	return 0
    95  }
    96  
    97  func (q QuerySelector) Unwrap() interface{} {
    98  	return q.value
    99  }
   100  
   101  func (q QuerySelector) Hash() uint64 {
   102  	h := fnv.New64a()
   103  
   104  	h.Write([]byte(q.Type().String()))
   105  	h.Write([]byte(":"))
   106  	h.Write([]byte(q.kind.String()))
   107  	h.Write([]byte(":"))
   108  	h.Write([]byte(q.value.String()))
   109  
   110  	return h.Sum64()
   111  }
   112  
   113  func (q QuerySelector) Copy() core.Value {
   114  	return q
   115  }