equal_expression.go raw
1 // Copyright 2022-2025 The sacloud/iaas-api-go Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License");
4 // you may not use this file except in compliance with the License.
5 // You may obtain a copy of the License at
6 //
7 // http://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS,
11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 // See the License for the specific language governing permissions and
13 // limitations under the License.
14
15 package search
16
17 import (
18 "encoding/json"
19 "fmt"
20 "strings"
21 "time"
22 )
23
24 // EqualExpression Equalで比較する際の条件
25 type EqualExpression struct {
26 Op LogicalOperator
27 Conditions []interface{}
28 }
29
30 // PartialMatch 部分一致(Partial Match)かつAND条件を示すEqualFilterを作成
31 //
32 // AndEqualのエイリアス
33 func PartialMatch(conditions ...string) *EqualExpression {
34 return AndEqual(conditions...)
35 }
36
37 // ExactMatch 完全一致(Partial Match)かつOR条件を示すEqualFilterを作成
38 //
39 // OrEqualのエイリアス
40 func ExactMatch(conditions ...string) *EqualExpression {
41 var values []interface{}
42 for _, p := range conditions {
43 values = append(values, p)
44 }
45 return OrEqual(values...)
46 }
47
48 // AndEqual 部分一致(Partial Match)かつAND条件を示すEqualFilterを作成
49 func AndEqual(conditions ...string) *EqualExpression {
50 var values []interface{}
51 for _, p := range conditions {
52 values = append(values, p)
53 }
54
55 return &EqualExpression{
56 Op: OpAnd,
57 Conditions: values,
58 }
59 }
60
61 // OrEqual 完全一致(Exact Match)かつOR条件を示すEqualFilterを作成
62 func OrEqual(conditions ...interface{}) *EqualExpression {
63 return &EqualExpression{
64 Op: OpOr,
65 Conditions: conditions,
66 }
67 }
68
69 // TagsAndEqual タグのAND検索
70 func TagsAndEqual(tags ...string) *EqualExpression {
71 return OrEqual(tags) // 配列のまま渡す
72 }
73
74 // MarshalJSON .
75 func (eq *EqualExpression) MarshalJSON() ([]byte, error) {
76 var conditions []interface{}
77 for _, cond := range eq.Conditions {
78 var c interface{}
79 switch v := cond.(type) {
80 case time.Time:
81 c = v.Format(time.RFC3339)
82 case string:
83 c = escapeFilterString(v)
84 case int, int8, int16, int32, int64,
85 uint, uint8, uint16, uint32, uint64,
86 float32, float64:
87 c = fmt.Sprintf("%v", v)
88 default:
89 c = v
90 }
91 if c != nil {
92 conditions = append(conditions, c)
93 }
94 }
95
96 var value interface{}
97 switch eq.Op {
98 case OpOr:
99 value = conditions
100 case OpAnd:
101 var strConds []string
102 for _, c := range conditions {
103 strConds = append(strConds, c.(string)) // Note: OpAndで文字列以外の要素が指定された場合のことは考慮しない
104 }
105 value = strings.Join(strConds, "%20")
106 default:
107 return nil, fmt.Errorf("invalid search.LogicalOperator: %v", eq.Op)
108 }
109
110 return json.Marshal(value)
111 }
112