Skip to content

Commit ec674ca

Browse files
committed
Add better handling of values with decimal64 schema type
1 parent 4d5b258 commit ec674ca

File tree

3 files changed

+73
-5
lines changed

3 files changed

+73
-5
lines changed

pkg/datastore/data_rpc.go

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -781,11 +781,22 @@ func validateLeafTypeValue(lt *sdcpb.SchemaLeafType, v any) error {
781781
return fmt.Errorf("value %q does not match identityRef type %q, must be one of [%s]", v, lt.TypeName, strings.Join(lt.Values, ", "))
782782
}
783783
return nil
784+
case "decimal64":
785+
switch v := v.(type) {
786+
case float64: // if it's a float64 then it's a valid decimal64
787+
case string:
788+
if c := strings.Count(v, "."); c == 0 || c > 1 {
789+
return fmt.Errorf("value %q is not a valid Decimal64", v)
790+
}
791+
default:
792+
return fmt.Errorf("unexpected type for a Decimal64 value %q: %T", v, v)
793+
}
794+
return nil
784795
case "leafref":
785796
// TODO: does this need extra validation?
786797
return nil
787798
default:
788-
return fmt.Errorf("unhandled type %v", lt.GetType())
799+
return fmt.Errorf("unhandled type %v for value %q", lt.GetType(), v)
789800
}
790801
}
791802

@@ -1391,6 +1402,16 @@ func convertTypedValueToYANGType(schemaElem *sdcpb.SchemaElem, tv *sdcpb.TypedVa
13911402
return nil, err
13921403
}
13931404
return &sdcpb.TypedValue{Value: &sdcpb.TypedValue_BoolVal{BoolVal: v}}, nil
1405+
case "decimal64":
1406+
d64, err := utils.ParseDecimal64(utils.TypedValueToString(tv))
1407+
if err != nil {
1408+
return nil, err
1409+
}
1410+
return &sdcpb.TypedValue{
1411+
Value: &sdcpb.TypedValue_DecimalVal{
1412+
DecimalVal: d64,
1413+
},
1414+
}, nil
13941415
case "float":
13951416
v, err := strconv.ParseFloat(utils.TypedValueToString(tv), 32)
13961417
if err != nil {

pkg/datastore/target/netconf/conversion/leaf_convert.go

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import (
2020
"regexp"
2121
"strings"
2222

23+
"github.com/sdcio/data-server/pkg/utils"
2324
sdcpb "github.com/sdcio/sdc-protos/sdcpb"
2425
log "github.com/sirupsen/logrus"
2526
)
@@ -71,6 +72,8 @@ func Convert(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error)
7172
return ConvertIdentityRef(value, lst)
7273
case "instance-identifier": //TODO: https://www.rfc-editor.org/rfc/rfc6020.html#section-9.13
7374
return ConvertInstanceIdentifier(value, lst)
75+
case "decimal64":
76+
return ConvertDecimal64(value, lst)
7477
}
7578
log.Warnf("type %q not implemented", lst.Type)
7679
return ConvertString(value, lst)
@@ -280,6 +283,19 @@ func ConvertString(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue,
280283

281284
}
282285

286+
func ConvertDecimal64(value string, lst *sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) {
287+
d64, err := utils.ParseDecimal64(value)
288+
if err != nil {
289+
return nil, err
290+
}
291+
292+
return &sdcpb.TypedValue{
293+
Value: &sdcpb.TypedValue_DecimalVal{
294+
DecimalVal: d64,
295+
},
296+
}, nil
297+
}
298+
283299
func ConvertUnion(value string, slts []*sdcpb.SchemaLeafType) (*sdcpb.TypedValue, error) {
284300
// iterate over the union types try to convert without error
285301
for _, slt := range slts {

pkg/utils/value.go

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -85,12 +85,12 @@ func GetSchemaValue(updValue *sdcpb.TypedValue) (interface{}, error) {
8585
value = updValue.GetBoolVal()
8686
case *sdcpb.TypedValue_BytesVal:
8787
value = updValue.GetBytesVal()
88-
// case *sdcpb.TypedValue_DecimalVal:
89-
// value = updValue.GetDecimalVal()
88+
case *sdcpb.TypedValue_DecimalVal:
89+
value = updValue.GetDecimalVal()
9090
case *sdcpb.TypedValue_FloatVal:
9191
value = updValue.GetFloatVal()
92-
// case *sdcpb.TypedValue_DoubleVal:
93-
// value = updValue.GetDoubleVal()
92+
case *sdcpb.TypedValue_DoubleVal:
93+
value = updValue.GetDoubleVal()
9494
case *sdcpb.TypedValue_IntVal:
9595
value = updValue.GetIntVal()
9696
case *sdcpb.TypedValue_StringVal:
@@ -536,3 +536,34 @@ func TypedValueToString(tv *sdcpb.TypedValue) string {
536536
}
537537
return ""
538538
}
539+
540+
func ParseDecimal64(v string) (*sdcpb.Decimal64, error) {
541+
// Remove any leading or trailing spaces.
542+
trimmed := strings.TrimSpace(v)
543+
544+
// Split the string into integer and fractional parts.
545+
parts := strings.SplitN(trimmed, ".", 2)
546+
intPart := parts[0]
547+
var fracPart string
548+
if len(parts) > 1 {
549+
fracPart = parts[1]
550+
}
551+
552+
// Combine integer and fractional parts into one number.
553+
combined := intPart + fracPart
554+
555+
// Parse combined parts into a uint64.
556+
digits, err := strconv.ParseInt(combined, 10, 64)
557+
if err != nil {
558+
return nil, err
559+
}
560+
561+
// Calculate precision as the length of the fractional part.
562+
precision := uint32(len(fracPart))
563+
564+
// Return the Decimal64 representation.
565+
return &sdcpb.Decimal64{
566+
Digits: digits,
567+
Precision: precision,
568+
}, nil
569+
}

0 commit comments

Comments
 (0)