From e154d85aab9f78ae62803029b8dee5f4fc7f0050 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?G=C3=A9r=C3=A9my=20Hutin?= Date: Fri, 7 Apr 2023 02:01:59 +0200 Subject: [PATCH] types declaration and json marshaling --- types/base.go | 83 ++++++++++++++++++++++++++++ types/building.go | 73 +++++++++++++++++++++++++ types/corridor.go | 42 ++++++++++++++ types/device.go | 64 ++++++++++++++++++++++ types/go.mod | 3 + types/group.go | 34 ++++++++++++ types/rack.go | 130 ++++++++++++++++++++++++++++++++++++++++++++ types/room.go | 124 ++++++++++++++++++++++++++++++++++++++++++ types/site.go | 46 ++++++++++++++++ types/types_test.go | 61 +++++++++++++++++++++ 10 files changed, 660 insertions(+) create mode 100644 types/base.go create mode 100644 types/building.go create mode 100644 types/corridor.go create mode 100644 types/device.go create mode 100644 types/go.mod create mode 100644 types/group.go create mode 100644 types/rack.go create mode 100644 types/room.go create mode 100644 types/site.go create mode 100644 types/types_test.go diff --git a/types/base.go b/types/base.go new file mode 100644 index 000000000..ae86f1c1c --- /dev/null +++ b/types/base.go @@ -0,0 +1,83 @@ +package ogreetypes + +import ( + "encoding/json" + "fmt" + "time" +) + +type Vector2 struct { + X float64 `json:"x"` + Y float64 `json:"y"` +} + +type Vector2Wrapper struct { + v Vector2 +} + +func (v Vector2Wrapper) MarshalJSON() ([]byte, error) { + return json.Marshal(fmt.Sprintf("{\"x\":%f,\"y\":%f}", v.v.X, v.v.Y)) +} + +func (v *Vector2Wrapper) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + return json.Unmarshal([]byte(s), &v.v) +} + +type Vector3 struct { + X float64 `json:"x"` + Y float64 `json:"y"` + Z float64 `json:"z"` +} + +type Vector3Wrapper struct { + v Vector3 +} + +func (v Vector3Wrapper) MarshalJSON() ([]byte, error) { + return json.Marshal(fmt.Sprintf("{\"x\":%f,\"y\":%f,\"z\":%f}", v.v.X, v.v.Y, v.v.Z)) +} + +func (v *Vector3Wrapper) UnmarshalJSON(data []byte) error { + var s string + err := json.Unmarshal(data, &s) + if err != nil { + return err + } + return json.Unmarshal([]byte(s), &v.v) +} + +type Color string + +type MetricImperialUnit string + +const ( + MetricMM MetricImperialUnit = "mm" + MetricCM MetricImperialUnit = "cm" + MetricM MetricImperialUnit = "m" + MetricF MetricImperialUnit = "f" +) + +type FloorMetric string + +const ( + FloorM FloorMetric = "m" + FloorT FloorMetric = "t" + FloorF FloorMetric = "f" +) + +type Slug string + +type Header struct { + Description []string `json:"description"` + Domain string `json:"domain"` + CreatedDate *time.Time `json:"createdDate,omitempty"` + LastUpdated *time.Time `json:"lastUpdated,omitempty"` + Name string `json:"name"` + Id string `json:"id,omitempty"` + ParentId string `json:"parentId"` +} diff --git a/types/building.go b/types/building.go new file mode 100644 index 000000000..18424a209 --- /dev/null +++ b/types/building.go @@ -0,0 +1,73 @@ +package ogreetypes + +import ( + "encoding/json" +) + +type BuildingTemplate struct { + Slug Slug `json:"slug"` + Center Vector2 `json:"center"` + SizeWDHm Vector3 `json:"sizeWDHm"` + Vertices []Vector2 `json:"vertices"` +} + +func (b BuildingTemplate) MarshalJSON() ([]byte, error) { + type Alias BuildingTemplate + return json.Marshal(struct { + Category string `json:"category"` + Alias + }{ + Category: "building", + Alias: Alias(b), + }) +} + +type Building struct { + Header `json:"-"` + Height float64 `json:"height"` + HeightUnit MetricImperialUnit `json:"heightUnit"` + PosXY Vector2 `json:"-"` + PosXYUnit MetricImperialUnit `json:"posXYUnit"` + Size Vector2 `json:"-"` + SizeUnit MetricImperialUnit `json:"sizeUnit"` + Rotation float64 `json:"rotation"` + Template string `json:"template,omitempty"` +} + +type BuildingAlias Building + +type BuildingJsonAttributes struct { + BuildingAlias + PosXYAux Vector2Wrapper `json:"posXY"` + SizeAux Vector2Wrapper `json:"size"` +} + +type BuildingJson struct { + Category string `json:"category"` + Header + Attributes BuildingJsonAttributes `json:"attributes"` +} + +func (b Building) MarshalJSON() ([]byte, error) { + return json.Marshal(BuildingJson{ + Category: "building", + Header: b.Header, + Attributes: BuildingJsonAttributes{ + BuildingAlias: BuildingAlias(b), + PosXYAux: Vector2Wrapper{b.PosXY}, + SizeAux: Vector2Wrapper{b.Size}, + }, + }) +} + +func (b *Building) UnmarshalJSON(data []byte) error { + var bjson BuildingJson + if err := json.Unmarshal(data, &bjson); err != nil { + return err + } + *b = Building(bjson.Attributes.BuildingAlias) + b.Header = bjson.Header + b.PosXY = bjson.Attributes.PosXYAux.v + b.Size = bjson.Attributes.SizeAux.v + return nil +} diff --git a/types/corridor.go b/types/corridor.go new file mode 100644 index 000000000..63545064e --- /dev/null +++ b/types/corridor.go @@ -0,0 +1,42 @@ +package ogreetypes + +import "encoding/json" + +type Temperature string + +const ( + COLD Temperature = "cold" + WARM Temperature = "warm" +) + +type Corridor struct { + Header + Content string `json:"content"` + Temperature Temperature `json:"temperature"` +} + +type CorridorAlias Corridor + +type CorridorJson struct { + Category string `json:"category"` + Header + Attributes CorridorAlias `json:"attributes"` +} + +func (c Corridor) MarshalJSON() ([]byte, error) { + return json.Marshal(CorridorJson{ + Category: "corridor", + Header: c.Header, + Attributes: CorridorAlias(c), + }) +} + +func (c *Corridor) UnmarshalJSON(data []byte) error { + var cjson CorridorJson + if err := json.Unmarshal(data, &cjson); err != nil { + return err + } + *c = Corridor(cjson.Attributes) + c.Header = cjson.Header + return nil +} diff --git a/types/device.go b/types/device.go new file mode 100644 index 000000000..8465f58a7 --- /dev/null +++ b/types/device.go @@ -0,0 +1,64 @@ +package ogreetypes + +import "encoding/json" + +type DeviceOrientation string + +const ( + DeviceFront DeviceOrientation = "front" + DeviceRear DeviceOrientation = "rear" + DeviceFrontflipped DeviceOrientation = "frontflipped" + DeviceRearflipped DeviceOrientation = "rearflipped" +) + +type DeviceTemplate = RackTemplate + +type Device struct { + Header + FbxModel string `json:"fbxModel,omitempty"` + Height float64 `json:"height"` + HeightUnit RackUnit `json:"heightUnit"` + Orientation DeviceOrientation `json:"orientation"` + Size Vector2 `json:"-"` + SizeUnit MetricImperialUnit `json:"sizeUnit"` + Slot string `json:"slot,omitempty"` + Template string `json:"template"` + Type string `json:"type,omitempty"` + PosU *int `json:"posU,omitempty"` + SizeU *int `json:"sizeU,omitempty"` +} + +type DeviceAlias Device + +type DeviceJsonAttributes struct { + DeviceAlias + SizeAux Vector2Wrapper `json:"size"` +} + +type DeviceJson struct { + Category string `json:"category"` + Header + Attributes DeviceJsonAttributes `json:"attributes"` +} + +func (d Device) MarshalJSON() ([]byte, error) { + return json.Marshal(DeviceJson{ + Category: "device", + Header: d.Header, + Attributes: DeviceJsonAttributes{ + DeviceAlias: DeviceAlias(d), + SizeAux: Vector2Wrapper{d.Size}, + }, + }) +} + +func (d *Device) UnmarshalJSON(data []byte) error { + var djson DeviceJson + if err := json.Unmarshal(data, &djson); err != nil { + return err + } + *d = Device(djson.Attributes.DeviceAlias) + d.Header = djson.Header + d.Size = djson.Attributes.SizeAux.v + return nil +} diff --git a/types/go.mod b/types/go.mod new file mode 100644 index 000000000..5680369be --- /dev/null +++ b/types/go.mod @@ -0,0 +1,3 @@ +module ogreetypes + +go 1.19 diff --git a/types/group.go b/types/group.go new file mode 100644 index 000000000..8199d955b --- /dev/null +++ b/types/group.go @@ -0,0 +1,34 @@ +package ogreetypes + +import "encoding/json" + +type Group struct { + Header `json:"-"` + Content string `json:"content"` +} + +type GroupAlias Group + +type GroupJson struct { + Category string `json:"category"` + Header + Attributes GroupAlias `json:"attributes"` +} + +func (g Group) MarshalJSON() ([]byte, error) { + return json.Marshal(GroupJson{ + Category: "group", + Header: g.Header, + Attributes: GroupAlias(g), + }) +} + +func (g *Group) UnmarshalJSON(data []byte) error { + var gjson GroupJson + if err := json.Unmarshal(data, &gjson); err != nil { + return err + } + *g = Group(gjson.Attributes) + g.Header = gjson.Header + return nil +} diff --git a/types/rack.go b/types/rack.go new file mode 100644 index 000000000..437a05e02 --- /dev/null +++ b/types/rack.go @@ -0,0 +1,130 @@ +package ogreetypes + +import ( + "encoding/json" + "time" +) + +type RackOrientation string + +const ( + RackFront RackOrientation = "front" + RackRear RackOrientation = "rear" + RackLeft RackOrientation = "left" + RackRight RackOrientation = "right" +) + +type RackUnit string + +const ( + RackMM RackUnit = "mm" + RackCM RackUnit = "cm" + RackM RackUnit = "m" + RackU RackUnit = "u" + RackOU RackUnit = "ou" + RackF RackUnit = "f" +) + +type LabelPosition string + +const ( + LabelFront LabelPosition = "front" + LabelRear LabelPosition = "rear" + LabelFrontrear LabelPosition = "frontrear" + LabelTop LabelPosition = "top" + LabelRight LabelPosition = "right" + LabelLeft LabelPosition = "left" +) + +type ComponentOrientation string + +const ( + ComponentHorizontal ComponentOrientation = "horizontal" + ComponentVertical ComponentOrientation = "vertical" +) + +type Component struct { + Factor string `json:"factor,omitempty"` + Color *Color `json:"color,omitempty"` + ElemOrient *ComponentOrientation `json:"elemOrient,omitempty"` + ElemPos Vector3 `json:"elemPos"` + ElemSize Vector3 `json:"elemSize"` + LabelPos LabelPosition `json:"labelPos"` + Location string `json:"location"` + Type string `json:"type"` +} + +type RackTemplate struct { + Attributes map[string]string `json:"attributes"` + Colors map[string]Color `json:"colors,omitempty"` + Components []Component `json:"components"` + CreatedDate *time.Time `json:"createdDate,omitempty"` + LastUpdated *time.Time `json:"lastUpdated,omitempty"` + Description string `json:"description"` + FbxModel string `json:"fbxModel"` + Id string `json:"id,omitempty"` + SizeWDHmm Vector3 `json:"sizeWDHmm"` + Slug Slug `json:"slug"` + Slots []Component `json:"slots"` +} + +func (r RackTemplate) MarshalJSON() ([]byte, error) { + type Alias RackTemplate + return json.Marshal(struct { + category string + Alias + }{ + category: "rack", + Alias: Alias(r), + }) +} + +type Rack struct { + Header + Height float64 `json:"height"` + HeightUnit RackUnit `json:"heightUnit"` + Orientation RackOrientation `json:"orientation"` + PosXYZ Vector3 `json:"-"` + PosXYUnit FloorMetric `json:"posXYUnit"` + Size Vector2 `json:"-"` + SizeUnit MetricImperialUnit `json:"sizeUnit"` + Template string `json:"template"` +} + +type RackAlias Rack + +type RackJsonAttributes struct { + RackAlias + PosXYZAux Vector3Wrapper `json:"posXYZ"` + SizeAux Vector2Wrapper `json:"size"` +} + +type RackJson struct { + Category string `json:"category"` + Header + Attributes RackJsonAttributes `json:"attributes"` +} + +func (r Rack) MarshalJSON() ([]byte, error) { + return json.Marshal(RackJson{ + Category: "rack", + Header: r.Header, + Attributes: RackJsonAttributes{ + RackAlias: RackAlias(r), + PosXYZAux: Vector3Wrapper{r.PosXYZ}, + SizeAux: Vector2Wrapper{r.Size}, + }, + }) +} + +func (r *Rack) UnmarshalJSON(data []byte) error { + var rjson RackJson + if err := json.Unmarshal(data, &rjson); err != nil { + return err + } + *r = Rack(rjson.Attributes.RackAlias) + r.Header = rjson.Header + r.PosXYZ = rjson.Attributes.PosXYZAux.v + r.Size = rjson.Attributes.SizeAux.v + return nil +} diff --git a/types/room.go b/types/room.go new file mode 100644 index 000000000..2089219df --- /dev/null +++ b/types/room.go @@ -0,0 +1,124 @@ +package ogreetypes + +import ( + "encoding/json" + "time" +) + +type AxisOrientation string + +const ( + XY AxisOrientation = "+x+y" + XMY AxisOrientation = "+x-y" + MXY AxisOrientation = "-x+y" + MXMY AxisOrientation = "-x-y" +) + +type SeparatorType string + +const ( + WIREFRAME SeparatorType = "wireframe" + PLAIN SeparatorType = "plain" +) + +type Separator struct { + StartPosXYm Vector2 `json:"startPosXYm"` + EndPosXYm Vector2 `json:"endPosXYm"` + Type SeparatorType `json:"type"` +} + +type Pillar struct { + CenterXY Vector2 `json:"centerXY"` + SizeXY Vector2 `json:"sizeXY"` + Rotation float64 `json:"rotation"` +} + +type Tile struct { + Color string `json:"color"` + Label string `json:"label"` + Location string `json:"location"` + Name string `json:"name"` + Texture string `json:"texture"` +} + +type RoomTemplate struct { + Center *Vector2 `json:"center,omitempty"` + Colors map[string]Color `json:"colors,omitempty"` + CreatedDate *time.Time `json:"createdDate,omitempty"` + LastUpdated *time.Time `json:"lastUpdated,omitempty"` + FloorUnit FloorMetric `json:"floorUnit"` + Id string `json:"id,omitempty"` + AxisOrientation AxisOrientation `json:"axisOrientation"` + ReservedArea []int `json:"reservedArea,omitempty"` + TechnicalArea []int `json:"technicalArea,omitempty"` + Separators []Separator `json:"separators,omitempty"` + Pillars []Pillar `json:"pillars,omitempty"` + SizeWDHm Vector3 `json:"sizeWDHm"` + Slug Slug `json:"slug"` + TileAngle *float64 `json:"tileAngle,omitempty"` + Tiles []Tile `json:"tiles,omitempty"` + Vertices []Vector2 `json:"vertices,omitempty"` +} + +func (r RoomTemplate) MarshalJSON() ([]byte, error) { + type Alias RoomTemplate + return json.Marshal(struct { + category string + Alias + }{ + category: "room", + Alias: Alias(r), + }) +} + +type Room struct { + Header + FloorUnit FloorMetric `json:"floorUnit"` + Height float64 `json:"height"` + HeightUnit MetricImperialUnit `json:"heightUnit"` + Orientation AxisOrientation `json:"axisOrientation"` + Rotation float64 `json:"rotation"` + PosXY Vector2 `json:"posXY"` + PosXYUnit MetricImperialUnit `json:"posXYUnit"` + Size Vector2 `json:"size"` + SizeUnit MetricImperialUnit `json:"sizeUnit"` + Template string `json:"template,omitempty"` +} + +type RoomAlias Room + +type RoomJsonAttributes struct { + RoomAlias + PosXYAux Vector2Wrapper `json:"posXY"` + SizeAux Vector2Wrapper `json:"size"` +} + +type RoomJson struct { + Category string `json:"category"` + Header + Attributes RoomJsonAttributes `json:"attributes"` +} + +func (r Room) MarshalJSON() ([]byte, error) { + return json.Marshal(RoomJson{ + Category: "room", + Header: r.Header, + Attributes: RoomJsonAttributes{ + RoomAlias: RoomAlias(r), + PosXYAux: Vector2Wrapper{r.PosXY}, + SizeAux: Vector2Wrapper{r.Size}, + }, + }) +} + +func (r *Room) UnmarshalJSON(data []byte) error { + var rjson RoomJson + if err := json.Unmarshal(data, &rjson); err != nil { + return err + } + *r = Room(rjson.Attributes.RoomAlias) + r.Header = rjson.Header + r.PosXY = rjson.Attributes.PosXYAux.v + r.Size = rjson.Attributes.SizeAux.v + return nil +} diff --git a/types/site.go b/types/site.go new file mode 100644 index 000000000..67dd69b96 --- /dev/null +++ b/types/site.go @@ -0,0 +1,46 @@ +package ogreetypes + +import "encoding/json" + +type SiteOrientation string + +const ( + EN SiteOrientation = "EN" + NW SiteOrientation = "NW" + WS SiteOrientation = "WS" + SE SiteOrientation = "SE" +) + +type Site struct { + Header + Orientation *SiteOrientation `json:"orientation,omitempty"` + ReservedColor *Color `json:"reservedColor,omitempty"` + TechnicalColor *Color `json:"technicalColor,omitempty"` + UsableColor *Color `json:"usableColor,omitempty"` +} + +type SiteAlias Site + +type SiteJson struct { + Category string `json:"category"` + Header + Attributes SiteAlias `json:"attributes"` +} + +func (s Site) MarshalJSON() ([]byte, error) { + return json.Marshal(SiteJson{ + Category: "site", + Header: s.Header, + Attributes: SiteAlias(s), + }) +} + +func (s *Site) UnmarshalJSON(data []byte) error { + var sjson SiteJson + if err := json.Unmarshal(data, &sjson); err != nil { + return err + } + *s = Site(sjson.Attributes) + s.Header = sjson.Header + return nil +} diff --git a/types/types_test.go b/types/types_test.go new file mode 100644 index 000000000..4233f74e6 --- /dev/null +++ b/types/types_test.go @@ -0,0 +1,61 @@ +package ogreetypes + +import ( + "encoding/json" + "reflect" + "testing" +) + +func TestBuilding(t *testing.T) { + b := Building{ + Header: Header{ + Description: []string{"test"}, + CreatedDate: nil, + LastUpdated: nil, + Name: "test", + Id: "", + ParentId: "test", + }, + Height: 0.1, + PosXY: Vector2{X: 0.1, Y: 0.2}, + Size: Vector2{X: 0.1, Y: 0.2}, + } + bytes, err := json.MarshalIndent(b, "", " ") + if err != nil { + t.Errorf(err.Error()) + } + var bback Building + err = json.Unmarshal(bytes, &bback) + if err != nil { + t.Errorf(err.Error()) + } + if !reflect.DeepEqual(b, bback) { + t.Errorf("unmarshalled building does not match original building") + } +} + +func TestGroup(t *testing.T) { + g := Group{ + Header: Header{ + Description: []string{"test"}, + CreatedDate: nil, + LastUpdated: nil, + Name: "test", + Id: "", + ParentId: "test", + }, + Content: "test", + } + bytes, err := json.MarshalIndent(g, "", " ") + if err != nil { + t.Errorf(err.Error()) + } + var gback Group + err = json.Unmarshal(bytes, &gback) + if err != nil { + t.Errorf(err.Error()) + } + if !reflect.DeepEqual(g, gback) { + t.Errorf("unmarshalled group does not match original group") + } +}