feat: predictions

This commit is contained in:
Anatoly Antonov 2025-06-25 23:23:16 +03:00
parent 42e7924be9
commit 11be8f351f
42 changed files with 2221 additions and 516 deletions

View file

@ -1154,24 +1154,127 @@ func (s *PredictionResultPredictionItemTrajectoryItem) Encode(e *jx.Encoder) {
// encodeFields encodes fields.
func (s *PredictionResultPredictionItemTrajectoryItem) encodeFields(e *jx.Encoder) {
{
e.FieldStart("datetime")
json.EncodeDateTime(e, s.Datetime)
}
{
e.FieldStart("latitude")
e.Float64(s.Latitude)
}
{
e.FieldStart("longitude")
e.Float64(s.Longitude)
}
{
e.FieldStart("altitude")
e.Float64(s.Altitude)
}
}
var jsonFieldsNameOfPredictionResultPredictionItemTrajectoryItem = [0]string{}
var jsonFieldsNameOfPredictionResultPredictionItemTrajectoryItem = [4]string{
0: "datetime",
1: "latitude",
2: "longitude",
3: "altitude",
}
// Decode decodes PredictionResultPredictionItemTrajectoryItem from json.
func (s *PredictionResultPredictionItemTrajectoryItem) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode PredictionResultPredictionItemTrajectoryItem to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "datetime":
requiredBitSet[0] |= 1 << 0
if err := func() error {
v, err := json.DecodeDateTime(d)
s.Datetime = v
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"datetime\"")
}
case "latitude":
requiredBitSet[0] |= 1 << 1
if err := func() error {
v, err := d.Float64()
s.Latitude = float64(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"latitude\"")
}
case "longitude":
requiredBitSet[0] |= 1 << 2
if err := func() error {
v, err := d.Float64()
s.Longitude = float64(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"longitude\"")
}
case "altitude":
requiredBitSet[0] |= 1 << 3
if err := func() error {
v, err := d.Float64()
s.Altitude = float64(v)
if err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"altitude\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode PredictionResultPredictionItemTrajectoryItem")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00001111,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfPredictionResultPredictionItemTrajectoryItem) {
name = jsonFieldsNameOfPredictionResultPredictionItemTrajectoryItem[fieldIdx]
} else {
name = strconv.Itoa(fieldIdx)
}
failures = append(failures, validate.FieldError{
Name: name,
Error: validate.ErrFieldRequired,
})
// Reset bit.
result &^= 1 << bitIdx
}
}
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
@ -1188,3 +1291,190 @@ func (s *PredictionResultPredictionItemTrajectoryItem) UnmarshalJSON(data []byte
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode implements json.Marshaler.
func (s *ReadinessResponse) Encode(e *jx.Encoder) {
e.ObjStart()
s.encodeFields(e)
e.ObjEnd()
}
// encodeFields encodes fields.
func (s *ReadinessResponse) encodeFields(e *jx.Encoder) {
{
e.FieldStart("status")
s.Status.Encode(e)
}
{
if s.LastUpdate.Set {
e.FieldStart("last_update")
s.LastUpdate.Encode(e, json.EncodeDateTime)
}
}
{
if s.IsFresh.Set {
e.FieldStart("is_fresh")
s.IsFresh.Encode(e)
}
}
{
if s.ErrorMessage.Set {
e.FieldStart("error_message")
s.ErrorMessage.Encode(e)
}
}
}
var jsonFieldsNameOfReadinessResponse = [4]string{
0: "status",
1: "last_update",
2: "is_fresh",
3: "error_message",
}
// Decode decodes ReadinessResponse from json.
func (s *ReadinessResponse) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode ReadinessResponse to nil")
}
var requiredBitSet [1]uint8
if err := d.ObjBytes(func(d *jx.Decoder, k []byte) error {
switch string(k) {
case "status":
requiredBitSet[0] |= 1 << 0
if err := func() error {
if err := s.Status.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"status\"")
}
case "last_update":
if err := func() error {
s.LastUpdate.Reset()
if err := s.LastUpdate.Decode(d, json.DecodeDateTime); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"last_update\"")
}
case "is_fresh":
if err := func() error {
s.IsFresh.Reset()
if err := s.IsFresh.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"is_fresh\"")
}
case "error_message":
if err := func() error {
s.ErrorMessage.Reset()
if err := s.ErrorMessage.Decode(d); err != nil {
return err
}
return nil
}(); err != nil {
return errors.Wrap(err, "decode field \"error_message\"")
}
default:
return d.Skip()
}
return nil
}); err != nil {
return errors.Wrap(err, "decode ReadinessResponse")
}
// Validate required fields.
var failures []validate.FieldError
for i, mask := range [1]uint8{
0b00000001,
} {
if result := (requiredBitSet[i] & mask) ^ mask; result != 0 {
// Mask only required fields and check equality to mask using XOR.
//
// If XOR result is not zero, result is not equal to expected, so some fields are missed.
// Bits of fields which would be set are actually bits of missed fields.
missed := bits.OnesCount8(result)
for bitN := 0; bitN < missed; bitN++ {
bitIdx := bits.TrailingZeros8(result)
fieldIdx := i*8 + bitIdx
var name string
if fieldIdx < len(jsonFieldsNameOfReadinessResponse) {
name = jsonFieldsNameOfReadinessResponse[fieldIdx]
} else {
name = strconv.Itoa(fieldIdx)
}
failures = append(failures, validate.FieldError{
Name: name,
Error: validate.ErrFieldRequired,
})
// Reset bit.
result &^= 1 << bitIdx
}
}
}
if len(failures) > 0 {
return &validate.Error{Fields: failures}
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s *ReadinessResponse) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *ReadinessResponse) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}
// Encode encodes ReadinessResponseStatus as json.
func (s ReadinessResponseStatus) Encode(e *jx.Encoder) {
e.Str(string(s))
}
// Decode decodes ReadinessResponseStatus from json.
func (s *ReadinessResponseStatus) Decode(d *jx.Decoder) error {
if s == nil {
return errors.New("invalid: unable to decode ReadinessResponseStatus to nil")
}
v, err := d.StrBytes()
if err != nil {
return err
}
// Try to use constant string.
switch ReadinessResponseStatus(v) {
case ReadinessResponseStatusOk:
*s = ReadinessResponseStatusOk
case ReadinessResponseStatusNotReady:
*s = ReadinessResponseStatusNotReady
case ReadinessResponseStatusError:
*s = ReadinessResponseStatusError
default:
*s = ReadinessResponseStatus(v)
}
return nil
}
// MarshalJSON implements stdjson.Marshaler.
func (s ReadinessResponseStatus) MarshalJSON() ([]byte, error) {
e := jx.Encoder{}
s.Encode(&e)
return e.Bytes(), nil
}
// UnmarshalJSON implements stdjson.Unmarshaler.
func (s *ReadinessResponseStatus) UnmarshalJSON(data []byte) error {
d := jx.DecodeBytes(data)
return s.Decode(d)
}