mirror of
https://github.com/dolthub/dolt.git
synced 2026-01-30 19:09:34 -06:00
Add types.Enum
This is needed to be able to round trip enums. If there is no codegen for an enum that is read from the datastore we now return a types.Enum which can be serialized back to the same sequence.
This commit is contained in:
@@ -21,13 +21,15 @@ func (e {{.Name}}) TypeRef() {{$typesPackage}}TypeRef {
|
||||
|
||||
func init() {
|
||||
__typeRefFor{{.Name}} = {{$typesPackage}}MakeTypeRef(__{{.PackageName}}PackageInFile_{{.FileID}}_CachedRef, {{.Ordinal}})
|
||||
{{$typesPackage}}RegisterFromValFunction(__typeRefFor{{.Name}}, func(v {{$typesPackage}}Value) {{$typesPackage}}Value {
|
||||
return {{.Name}}(uint32(v.({{$typesPackage}}UInt32)))
|
||||
})
|
||||
{{$typesPackage}}RegisterEnum(__typeRefFor{{.Name}}, builderFor{{.Name}}, readerFor{{.Name}})
|
||||
}
|
||||
|
||||
func (e {{.Name}}) InternalImplementation() uint32 {
|
||||
return uint32(e)
|
||||
func builderFor{{.Name}}(v uint32) {{$typesPackage}}Value {
|
||||
return {{.Name}}(v)
|
||||
}
|
||||
|
||||
func readerFor{{.Name}}(v {{$typesPackage}}Value) uint32 {
|
||||
return uint32(v.({{.Name}}))
|
||||
}
|
||||
|
||||
func (e {{.Name}}) Equals(other {{$typesPackage}}Value) bool {
|
||||
|
||||
@@ -47,13 +47,15 @@ func (e Handedness) TypeRef() types.TypeRef {
|
||||
|
||||
func init() {
|
||||
__typeRefForHandedness = types.MakeTypeRef(__genPackageInFile_enum_struct_CachedRef, 0)
|
||||
types.RegisterFromValFunction(__typeRefForHandedness, func(v types.Value) types.Value {
|
||||
return Handedness(uint32(v.(types.UInt32)))
|
||||
})
|
||||
types.RegisterEnum(__typeRefForHandedness, builderForHandedness, readerForHandedness)
|
||||
}
|
||||
|
||||
func (e Handedness) InternalImplementation() uint32 {
|
||||
return uint32(e)
|
||||
func builderForHandedness(v uint32) types.Value {
|
||||
return Handedness(v)
|
||||
}
|
||||
|
||||
func readerForHandedness(v types.Value) uint32 {
|
||||
return uint32(v.(Handedness))
|
||||
}
|
||||
|
||||
func (e Handedness) Equals(other types.Value) bool {
|
||||
|
||||
@@ -150,13 +150,15 @@ func (e E) TypeRef() types.TypeRef {
|
||||
|
||||
func init() {
|
||||
__typeRefForE = types.MakeTypeRef(__genPackageInFile_sha1_1c216c6_CachedRef, 1)
|
||||
types.RegisterFromValFunction(__typeRefForE, func(v types.Value) types.Value {
|
||||
return E(uint32(v.(types.UInt32)))
|
||||
})
|
||||
types.RegisterEnum(__typeRefForE, builderForE, readerForE)
|
||||
}
|
||||
|
||||
func (e E) InternalImplementation() uint32 {
|
||||
return uint32(e)
|
||||
func builderForE(v uint32) types.Value {
|
||||
return E(v)
|
||||
}
|
||||
|
||||
func readerForE(v types.Value) uint32 {
|
||||
return uint32(v.(E))
|
||||
}
|
||||
|
||||
func (e E) Equals(other types.Value) bool {
|
||||
|
||||
@@ -109,3 +109,136 @@ func (s StructWithDupList) SetL(val ListOfUInt8) StructWithDupList {
|
||||
s.ref = &ref.Ref{}
|
||||
return s
|
||||
}
|
||||
|
||||
// ListOfUInt8
|
||||
|
||||
type ListOfUInt8 struct {
|
||||
l types.List
|
||||
ref *ref.Ref
|
||||
}
|
||||
|
||||
func NewListOfUInt8() ListOfUInt8 {
|
||||
return ListOfUInt8{types.NewList(), &ref.Ref{}}
|
||||
}
|
||||
|
||||
type ListOfUInt8Def []uint8
|
||||
|
||||
func (def ListOfUInt8Def) New() ListOfUInt8 {
|
||||
l := make([]types.Value, len(def))
|
||||
for i, d := range def {
|
||||
l[i] = types.UInt8(d)
|
||||
}
|
||||
return ListOfUInt8{types.NewList(l...), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Def() ListOfUInt8Def {
|
||||
d := make([]uint8, l.Len())
|
||||
for i := uint64(0); i < l.Len(); i++ {
|
||||
d[i] = uint8(l.l.Get(i).(types.UInt8))
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) InternalImplementation() types.List {
|
||||
return l.l
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Equals(other types.Value) bool {
|
||||
return other != nil && __typeRefForListOfUInt8.Equals(other.TypeRef()) && l.Ref() == other.Ref()
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Ref() ref.Ref {
|
||||
return types.EnsureRef(l.ref, l)
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Chunks() (chunks []ref.Ref) {
|
||||
chunks = append(chunks, l.TypeRef().Chunks()...)
|
||||
chunks = append(chunks, l.l.Chunks()...)
|
||||
return
|
||||
}
|
||||
|
||||
// A Noms Value that describes ListOfUInt8.
|
||||
var __typeRefForListOfUInt8 types.TypeRef
|
||||
|
||||
func (m ListOfUInt8) TypeRef() types.TypeRef {
|
||||
return __typeRefForListOfUInt8
|
||||
}
|
||||
|
||||
func init() {
|
||||
__typeRefForListOfUInt8 = types.MakeCompoundTypeRef(types.ListKind, types.MakePrimitiveTypeRef(types.UInt8Kind))
|
||||
types.RegisterFromValFunction(__typeRefForListOfUInt8, func(v types.Value) types.Value {
|
||||
return ListOfUInt8{v.(types.List), &ref.Ref{}}
|
||||
})
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Len() uint64 {
|
||||
return l.l.Len()
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Empty() bool {
|
||||
return l.Len() == uint64(0)
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Get(i uint64) uint8 {
|
||||
return uint8(l.l.Get(i).(types.UInt8))
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Slice(idx uint64, end uint64) ListOfUInt8 {
|
||||
return ListOfUInt8{l.l.Slice(idx, end), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Set(i uint64, val uint8) ListOfUInt8 {
|
||||
return ListOfUInt8{l.l.Set(i, types.UInt8(val)), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Append(v ...uint8) ListOfUInt8 {
|
||||
return ListOfUInt8{l.l.Append(l.fromElemSlice(v)...), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Insert(idx uint64, v ...uint8) ListOfUInt8 {
|
||||
return ListOfUInt8{l.l.Insert(idx, l.fromElemSlice(v)...), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Remove(idx uint64, end uint64) ListOfUInt8 {
|
||||
return ListOfUInt8{l.l.Remove(idx, end), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) RemoveAt(idx uint64) ListOfUInt8 {
|
||||
return ListOfUInt8{(l.l.RemoveAt(idx)), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) fromElemSlice(p []uint8) []types.Value {
|
||||
r := make([]types.Value, len(p))
|
||||
for i, v := range p {
|
||||
r[i] = types.UInt8(v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
type ListOfUInt8IterCallback func(v uint8, i uint64) (stop bool)
|
||||
|
||||
func (l ListOfUInt8) Iter(cb ListOfUInt8IterCallback) {
|
||||
l.l.Iter(func(v types.Value, i uint64) bool {
|
||||
return cb(uint8(v.(types.UInt8)), i)
|
||||
})
|
||||
}
|
||||
|
||||
type ListOfUInt8IterAllCallback func(v uint8, i uint64)
|
||||
|
||||
func (l ListOfUInt8) IterAll(cb ListOfUInt8IterAllCallback) {
|
||||
l.l.IterAll(func(v types.Value, i uint64) {
|
||||
cb(uint8(v.(types.UInt8)), i)
|
||||
})
|
||||
}
|
||||
|
||||
type ListOfUInt8FilterCallback func(v uint8, i uint64) (keep bool)
|
||||
|
||||
func (l ListOfUInt8) Filter(cb ListOfUInt8FilterCallback) ListOfUInt8 {
|
||||
nl := NewListOfUInt8()
|
||||
l.IterAll(func(v uint8, i uint64) {
|
||||
if cb(v, i) {
|
||||
nl = nl.Append(v)
|
||||
}
|
||||
})
|
||||
return nl
|
||||
}
|
||||
|
||||
@@ -49,13 +49,15 @@ func (e LocalE) TypeRef() types.TypeRef {
|
||||
|
||||
func init() {
|
||||
__typeRefForLocalE = types.MakeTypeRef(__genPackageInFile_struct_with_imports_CachedRef, 0)
|
||||
types.RegisterFromValFunction(__typeRefForLocalE, func(v types.Value) types.Value {
|
||||
return LocalE(uint32(v.(types.UInt32)))
|
||||
})
|
||||
types.RegisterEnum(__typeRefForLocalE, builderForLocalE, readerForLocalE)
|
||||
}
|
||||
|
||||
func (e LocalE) InternalImplementation() uint32 {
|
||||
return uint32(e)
|
||||
func builderForLocalE(v uint32) types.Value {
|
||||
return LocalE(v)
|
||||
}
|
||||
|
||||
func readerForLocalE(v types.Value) uint32 {
|
||||
return uint32(v.(LocalE))
|
||||
}
|
||||
|
||||
func (e LocalE) Equals(other types.Value) bool {
|
||||
|
||||
@@ -163,136 +163,3 @@ func (s StructWithList) SetI(val int64) StructWithList {
|
||||
s.ref = &ref.Ref{}
|
||||
return s
|
||||
}
|
||||
|
||||
// ListOfUInt8
|
||||
|
||||
type ListOfUInt8 struct {
|
||||
l types.List
|
||||
ref *ref.Ref
|
||||
}
|
||||
|
||||
func NewListOfUInt8() ListOfUInt8 {
|
||||
return ListOfUInt8{types.NewList(), &ref.Ref{}}
|
||||
}
|
||||
|
||||
type ListOfUInt8Def []uint8
|
||||
|
||||
func (def ListOfUInt8Def) New() ListOfUInt8 {
|
||||
l := make([]types.Value, len(def))
|
||||
for i, d := range def {
|
||||
l[i] = types.UInt8(d)
|
||||
}
|
||||
return ListOfUInt8{types.NewList(l...), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Def() ListOfUInt8Def {
|
||||
d := make([]uint8, l.Len())
|
||||
for i := uint64(0); i < l.Len(); i++ {
|
||||
d[i] = uint8(l.l.Get(i).(types.UInt8))
|
||||
}
|
||||
return d
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) InternalImplementation() types.List {
|
||||
return l.l
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Equals(other types.Value) bool {
|
||||
return other != nil && __typeRefForListOfUInt8.Equals(other.TypeRef()) && l.Ref() == other.Ref()
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Ref() ref.Ref {
|
||||
return types.EnsureRef(l.ref, l)
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Chunks() (chunks []ref.Ref) {
|
||||
chunks = append(chunks, l.TypeRef().Chunks()...)
|
||||
chunks = append(chunks, l.l.Chunks()...)
|
||||
return
|
||||
}
|
||||
|
||||
// A Noms Value that describes ListOfUInt8.
|
||||
var __typeRefForListOfUInt8 types.TypeRef
|
||||
|
||||
func (m ListOfUInt8) TypeRef() types.TypeRef {
|
||||
return __typeRefForListOfUInt8
|
||||
}
|
||||
|
||||
func init() {
|
||||
__typeRefForListOfUInt8 = types.MakeCompoundTypeRef(types.ListKind, types.MakePrimitiveTypeRef(types.UInt8Kind))
|
||||
types.RegisterFromValFunction(__typeRefForListOfUInt8, func(v types.Value) types.Value {
|
||||
return ListOfUInt8{v.(types.List), &ref.Ref{}}
|
||||
})
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Len() uint64 {
|
||||
return l.l.Len()
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Empty() bool {
|
||||
return l.Len() == uint64(0)
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Get(i uint64) uint8 {
|
||||
return uint8(l.l.Get(i).(types.UInt8))
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Slice(idx uint64, end uint64) ListOfUInt8 {
|
||||
return ListOfUInt8{l.l.Slice(idx, end), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Set(i uint64, val uint8) ListOfUInt8 {
|
||||
return ListOfUInt8{l.l.Set(i, types.UInt8(val)), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Append(v ...uint8) ListOfUInt8 {
|
||||
return ListOfUInt8{l.l.Append(l.fromElemSlice(v)...), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Insert(idx uint64, v ...uint8) ListOfUInt8 {
|
||||
return ListOfUInt8{l.l.Insert(idx, l.fromElemSlice(v)...), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) Remove(idx uint64, end uint64) ListOfUInt8 {
|
||||
return ListOfUInt8{l.l.Remove(idx, end), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) RemoveAt(idx uint64) ListOfUInt8 {
|
||||
return ListOfUInt8{(l.l.RemoveAt(idx)), &ref.Ref{}}
|
||||
}
|
||||
|
||||
func (l ListOfUInt8) fromElemSlice(p []uint8) []types.Value {
|
||||
r := make([]types.Value, len(p))
|
||||
for i, v := range p {
|
||||
r[i] = types.UInt8(v)
|
||||
}
|
||||
return r
|
||||
}
|
||||
|
||||
type ListOfUInt8IterCallback func(v uint8, i uint64) (stop bool)
|
||||
|
||||
func (l ListOfUInt8) Iter(cb ListOfUInt8IterCallback) {
|
||||
l.l.Iter(func(v types.Value, i uint64) bool {
|
||||
return cb(uint8(v.(types.UInt8)), i)
|
||||
})
|
||||
}
|
||||
|
||||
type ListOfUInt8IterAllCallback func(v uint8, i uint64)
|
||||
|
||||
func (l ListOfUInt8) IterAll(cb ListOfUInt8IterAllCallback) {
|
||||
l.l.IterAll(func(v types.Value, i uint64) {
|
||||
cb(uint8(v.(types.UInt8)), i)
|
||||
})
|
||||
}
|
||||
|
||||
type ListOfUInt8FilterCallback func(v uint8, i uint64) (keep bool)
|
||||
|
||||
func (l ListOfUInt8) Filter(cb ListOfUInt8FilterCallback) ListOfUInt8 {
|
||||
nl := NewListOfUInt8()
|
||||
l.IterAll(func(v uint8, i uint64) {
|
||||
if cb(v, i) {
|
||||
nl = nl.Append(v)
|
||||
}
|
||||
})
|
||||
return nl
|
||||
}
|
||||
|
||||
@@ -150,13 +150,15 @@ func (e E) TypeRef() types.TypeRef {
|
||||
|
||||
func init() {
|
||||
__typeRefForE = types.MakeTypeRef(__leafDepPackageInFile_leafDep_CachedRef, 1)
|
||||
types.RegisterFromValFunction(__typeRefForE, func(v types.Value) types.Value {
|
||||
return E(uint32(v.(types.UInt32)))
|
||||
})
|
||||
types.RegisterEnum(__typeRefForE, builderForE, readerForE)
|
||||
}
|
||||
|
||||
func (e E) InternalImplementation() uint32 {
|
||||
return uint32(e)
|
||||
func builderForE(v uint32) types.Value {
|
||||
return E(v)
|
||||
}
|
||||
|
||||
func readerForE(v types.Value) uint32 {
|
||||
return uint32(v.(E))
|
||||
}
|
||||
|
||||
func (e E) Equals(other types.Value) bool {
|
||||
|
||||
@@ -150,7 +150,7 @@ func (r *jsonArrayReader) readMap(t TypeRef, pkg *Package) Value {
|
||||
|
||||
func (r *jsonArrayReader) readEnum(t TypeRef, pkg *Package) Value {
|
||||
t = fixupTypeRef(t, pkg)
|
||||
return ToNomsValueFromTypeRef(t, UInt32(r.read().(float64)))
|
||||
return enumFromTypeRef(uint32(r.read().(float64)), t)
|
||||
}
|
||||
|
||||
func (r *jsonArrayReader) readPackage(t TypeRef, pkg *Package) Value {
|
||||
|
||||
@@ -359,38 +359,30 @@ func TestReadEnum(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cs := chunks.NewMemoryStore()
|
||||
|
||||
tref := MakeEnumTypeRef("E", "a", "b", "c")
|
||||
pkg := NewPackage([]TypeRef{tref}, []ref.Ref{})
|
||||
typeDef := MakeEnumTypeRef("E", "a", "b", "c")
|
||||
pkg := NewPackage([]TypeRef{typeDef}, []ref.Ref{})
|
||||
pkgRef := RegisterPackage(&pkg)
|
||||
enumTr := MakeTypeRef(pkgRef, 0)
|
||||
RegisterFromValFunction(enumTr, func(v Value) Value {
|
||||
return testEnum{v.(UInt32), enumTr}
|
||||
})
|
||||
|
||||
a := parseJson(`[%d, "%s", 0, 1]`, UnresolvedKind, pkgRef.String())
|
||||
r := newJsonArrayReader(a, cs)
|
||||
|
||||
v := r.readTopLevelValue().(testEnum)
|
||||
assert.Equal(uint32(1), uint32(v.UInt32))
|
||||
v := r.readTopLevelValue().(Enum)
|
||||
assert.Equal(uint32(1), v.v)
|
||||
}
|
||||
|
||||
func TestReadValueEnum(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cs := chunks.NewMemoryStore()
|
||||
|
||||
tref := MakeEnumTypeRef("E", "a", "b", "c")
|
||||
pkg := NewPackage([]TypeRef{tref}, []ref.Ref{})
|
||||
typeDef := MakeEnumTypeRef("E", "a", "b", "c")
|
||||
pkg := NewPackage([]TypeRef{typeDef}, []ref.Ref{})
|
||||
pkgRef := RegisterPackage(&pkg)
|
||||
enumTr := MakeTypeRef(pkgRef, 0)
|
||||
RegisterFromValFunction(enumTr, func(v Value) Value {
|
||||
return testEnum{v.(UInt32), enumTr}
|
||||
})
|
||||
|
||||
a := parseJson(`[%d, %d, "%s", 0, 1]`, ValueKind, UnresolvedKind, pkgRef.String())
|
||||
r := newJsonArrayReader(a, cs)
|
||||
|
||||
v := r.readTopLevelValue().(testEnum)
|
||||
assert.Equal(uint32(1), uint32(v.UInt32))
|
||||
v := r.readTopLevelValue().(Enum)
|
||||
assert.Equal(uint32(1), v.v)
|
||||
}
|
||||
|
||||
func TestReadRef(t *testing.T) {
|
||||
@@ -460,14 +452,11 @@ func TestReadStructWithEnum(t *testing.T) {
|
||||
return v
|
||||
})
|
||||
enumTr := MakeTypeRef(pkgRef, 1)
|
||||
RegisterFromValFunction(enumTr, func(v Value) Value {
|
||||
return testEnum{v.(UInt32), enumTr}
|
||||
})
|
||||
|
||||
v := r.readTopLevelValue().(Struct)
|
||||
|
||||
assert.True(v.Get("x").Equals(Int16(42)))
|
||||
assert.True(v.Get("e").Equals(UInt32(1)))
|
||||
assert.True(v.Get("e").Equals(Enum{1, enumTr}))
|
||||
assert.True(v.Get("b").Equals(Bool(true)))
|
||||
}
|
||||
|
||||
|
||||
@@ -126,10 +126,6 @@ func (w *jsonArrayWriter) writeValue(v Value, tr TypeRef, pkg *Package) {
|
||||
}
|
||||
|
||||
// TODO: This is ugly. BUG 452
|
||||
type enumImplementation interface {
|
||||
InternalImplementation() uint32
|
||||
}
|
||||
|
||||
type listImplementation interface {
|
||||
InternalImplementation() List
|
||||
}
|
||||
@@ -146,10 +142,6 @@ type setImplementation interface {
|
||||
InternalImplementation() Set
|
||||
}
|
||||
|
||||
func getEnumFromEnumKind(v Value) uint32 {
|
||||
return v.(enumImplementation).InternalImplementation()
|
||||
}
|
||||
|
||||
func getListFromListKind(v Value) List {
|
||||
if v, ok := v.(List); ok {
|
||||
return v
|
||||
@@ -243,7 +235,7 @@ func (w *jsonArrayWriter) writeUnresolvedKindValue(v Value, tr TypeRef, pkg *Pac
|
||||
default:
|
||||
d.Chk.Fail("An Unresolved TypeRef can only reference a StructKind or Enum Kind.", "Actually referenced: %+v", typeDef)
|
||||
case EnumKind:
|
||||
w.write(getEnumFromEnumKind(v))
|
||||
w.writeEnum(v, tr, pkg)
|
||||
case StructKind:
|
||||
w.writeStruct(v, tr, typeDef, pkg)
|
||||
}
|
||||
@@ -282,3 +274,9 @@ func (w *jsonArrayWriter) writeStruct(v Value, typeRef, typeDef TypeRef, pkg *Pa
|
||||
w.writeValue(<-c, desc.Union[unionIndex].T, pkg)
|
||||
}
|
||||
}
|
||||
|
||||
func (w *jsonArrayWriter) writeEnum(v Value, t TypeRef, pkg *Package) {
|
||||
t = fixupTypeRef(t, pkg)
|
||||
i := enumPrimitiveValueFromTypeRef(v, t)
|
||||
w.write(i)
|
||||
}
|
||||
|
||||
@@ -282,19 +282,6 @@ func TestWriteStructWithBlob(t *testing.T) {
|
||||
assert.EqualValues([]interface{}{UnresolvedKind, pkgRef.String(), int16(0), "AAE="}, w.toArray())
|
||||
}
|
||||
|
||||
type testEnum struct {
|
||||
UInt32
|
||||
t TypeRef
|
||||
}
|
||||
|
||||
func (e testEnum) TypeRef() TypeRef {
|
||||
return e.t
|
||||
}
|
||||
|
||||
func (e testEnum) InternalImplementation() uint32 {
|
||||
return uint32(e.UInt32)
|
||||
}
|
||||
|
||||
func TestWriteEnum(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cs := chunks.NewMemoryStore()
|
||||
@@ -305,7 +292,7 @@ func TestWriteEnum(t *testing.T) {
|
||||
tref := MakeTypeRef(pkgRef, 0)
|
||||
|
||||
w := newJsonArrayWriter(cs)
|
||||
w.writeTopLevelValue(testEnum{UInt32: UInt32(1), t: tref})
|
||||
w.writeTopLevelValue(Enum{1, tref})
|
||||
assert.EqualValues([]interface{}{UnresolvedKind, pkgRef.String(), int16(0), uint32(1)}, w.toArray())
|
||||
}
|
||||
|
||||
@@ -318,7 +305,7 @@ func TestWriteListOfEnum(t *testing.T) {
|
||||
pkgRef := RegisterPackage(&pkg)
|
||||
et := MakeTypeRef(pkgRef, 0)
|
||||
tref := MakeCompoundTypeRef(ListKind, et)
|
||||
v := NewList(testEnum{UInt32(0), et}, testEnum{UInt32(1), et}, testEnum{UInt32(2), et})
|
||||
v := NewList(Enum{0, et}, Enum{1, et}, Enum{2, et})
|
||||
|
||||
w := newJsonArrayWriter(cs)
|
||||
w.writeTopLevelValue(testList{List: v, t: tref})
|
||||
|
||||
29
types/enum.go
Normal file
29
types/enum.go
Normal file
@@ -0,0 +1,29 @@
|
||||
package types
|
||||
|
||||
import "github.com/attic-labs/noms/ref"
|
||||
|
||||
type Enum struct {
|
||||
v uint32
|
||||
t TypeRef
|
||||
}
|
||||
|
||||
func newEnum(v uint32, t TypeRef) Enum {
|
||||
return Enum{v, t}
|
||||
}
|
||||
|
||||
func (e Enum) Equals(other Value) bool {
|
||||
return other != nil && e.t.Equals(other.TypeRef()) && e.Ref() == other.Ref()
|
||||
}
|
||||
|
||||
func (e Enum) Ref() ref.Ref {
|
||||
throwaway := ref.Ref{}
|
||||
return EnsureRef(&throwaway, e)
|
||||
}
|
||||
|
||||
func (e Enum) Chunks() []ref.Ref {
|
||||
return nil
|
||||
}
|
||||
|
||||
func (e Enum) TypeRef() TypeRef {
|
||||
return e.t
|
||||
}
|
||||
34
types/enum_test.go
Normal file
34
types/enum_test.go
Normal file
@@ -0,0 +1,34 @@
|
||||
package types
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"github.com/attic-labs/noms/Godeps/_workspace/src/github.com/stretchr/testify/assert"
|
||||
"github.com/attic-labs/noms/chunks"
|
||||
"github.com/attic-labs/noms/ref"
|
||||
)
|
||||
|
||||
func TestGenericEnumWriteRead(t *testing.T) {
|
||||
assert := assert.New(t)
|
||||
cs := chunks.NewMemoryStore()
|
||||
|
||||
typeDefA := MakeEnumTypeRef("EA", "aA", "bA")
|
||||
typeDefB := MakeEnumTypeRef("EB", "aB", "bB")
|
||||
pkg := NewPackage([]TypeRef{typeDefA, typeDefB}, []ref.Ref{})
|
||||
pkgRef := RegisterPackage(&pkg)
|
||||
typeRefA := MakeTypeRef(pkgRef, 0)
|
||||
typeRefB := MakeTypeRef(pkgRef, 1)
|
||||
|
||||
vA := Enum{1, typeRefA}
|
||||
vB := Enum{1, typeRefB}
|
||||
|
||||
assert.False(vA.Equals(vB))
|
||||
|
||||
rA := WriteValue(vA, cs)
|
||||
vA2 := ReadValue(rA, cs)
|
||||
|
||||
assert.True(vA.Equals(vA2))
|
||||
assert.True(vA2.Equals(vA))
|
||||
assert.False(vB.Equals(vA2))
|
||||
assert.False(vA2.Equals(vB))
|
||||
}
|
||||
@@ -8,6 +8,8 @@ import (
|
||||
|
||||
type structBuilderFunc func() chan Value
|
||||
type structReaderFunc func(v Value) chan Value
|
||||
type enumBuilderFunc func(v uint32) Value
|
||||
type enumReaderFunc func(v Value) uint32
|
||||
type toNomsValueFunc func(v Value) Value
|
||||
|
||||
type structFuncs struct {
|
||||
@@ -15,10 +17,16 @@ type structFuncs struct {
|
||||
reader structReaderFunc
|
||||
}
|
||||
|
||||
type enumFuncs struct {
|
||||
builder enumBuilderFunc
|
||||
reader enumReaderFunc
|
||||
}
|
||||
|
||||
var (
|
||||
packages map[ref.Ref]*Package = map[ref.Ref]*Package{}
|
||||
toNomsValueMap map[ref.Ref]toNomsValueFunc = map[ref.Ref]toNomsValueFunc{}
|
||||
structFuncMap map[ref.Ref]structFuncs = map[ref.Ref]structFuncs{}
|
||||
enumFuncMap map[ref.Ref]enumFuncs = map[ref.Ref]enumFuncs{}
|
||||
)
|
||||
|
||||
// LookupPackage looks for a Package by ref.Ref in the global cache of Noms type packages.
|
||||
@@ -68,3 +76,21 @@ func structReaderForTypeRef(v Value, typeRef, typeDef TypeRef) chan Value {
|
||||
}
|
||||
return structReader(v.(Struct), typeRef, typeDef)
|
||||
}
|
||||
|
||||
func RegisterEnum(t TypeRef, bf enumBuilderFunc, rf enumReaderFunc) {
|
||||
enumFuncMap[t.Ref()] = enumFuncs{bf, rf}
|
||||
}
|
||||
|
||||
func enumFromTypeRef(v uint32, t TypeRef) Value {
|
||||
if s, ok := enumFuncMap[t.Ref()]; ok {
|
||||
return s.builder(v)
|
||||
}
|
||||
return newEnum(v, t)
|
||||
}
|
||||
|
||||
func enumPrimitiveValueFromTypeRef(v Value, t TypeRef) uint32 {
|
||||
if s, ok := enumFuncMap[t.Ref()]; ok {
|
||||
return s.reader(v)
|
||||
}
|
||||
return v.(Enum).v
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user