Commit b066cf1b authored by Eric Myhre's avatar Eric Myhre

Introduce typedeclaration package. (Think "AST".)

All of these struct definitions are horrifying similar in construction
to the same-named definitions in the typesystem package: simply ever
instance of a Type pointer is instead a TypeName string.  Despite being
unattractive, this is correct: since typesystem can have pointers and
cycles, and typedeclaration can't, this is what we end up with.
Signed-off-by: default avatarEric Myhre <hash@exultant.us>
parent 3cbf672a
package typedeclaration
import (
ipld "github.com/ipld/go-ipld-prime"
)
type TypeName string
// typedeclaration.Type is a union interface; each of the `Type*` concrete types
// in this package are one of its members.
//
// Specifically,
//
// TypeBool
// TypeString
// TypeBytes
// TypeInt
// TypeFloat
// TypeMap
// TypeList
// TypeLink
// TypeUnion
// TypeObject
// TypeEnum
//
// are all of the kinds of Type.
//
// This is a closed union; you can switch upon the above members without
// including a default case. The membership is closed by the unexported
// '_Type' method; you may use the BurntSushi/go-sumtype tool to check
// your switches for completeness.
//
// In contrast to typesystem.Type, the typedeclaration.Type members are meant
// to represent something more like the AST (Abstract Syntax Tree) that
// *describes* a typesystem. It's meant to be serializable, so that
// we can be self-describing. As such, none of the members of
// typedeclaration.Type are permitted to have pointers nor cycles (whereas
// typesystem.Type can and definitely does).
//
// Since we do all of the consistency checking during the final conversion
// and reification of typedeclaration.Type -> typesystem.Type and
// typesystem.Universe, we don't bother much with consistency nor immutablity
// in the design of typedeclaration types; you can use these as builders
// fairly haphazardly, and everything will become nicely immutable after you
// submit it all to typesystem.Construct.
type Type interface {
// Unexported marker method to force the union closed.
_Type()
}
var (
_ Type = TypeBool{}
_ Type = TypeString{}
_ Type = TypeBytes{}
_ Type = TypeInt{}
_ Type = TypeFloat{}
_ Type = TypeMap{}
_ Type = TypeList{}
_ Type = TypeLink{}
_ Type = TypeUnion{}
_ Type = TypeObject{}
_ Type = TypeEnum{}
)
type TypeBool struct {
Name TypeName
}
type TypeString struct {
Name TypeName
}
type TypeBytes struct {
Name TypeName
}
type TypeInt struct {
Name TypeName
}
type TypeFloat struct {
Name TypeName
}
type TypeMap struct {
Name TypeName
Anon bool
KeyType TypeName
ValueType TypeName
ValueNullable bool
}
type TypeList struct {
Name TypeName
Anon bool
ValueType TypeName
ValueNullable bool
}
type TypeLink struct {
Name TypeName
// ...?
}
type TypeUnion struct {
Name TypeName
Style UnionStyle
ValuesKinded map[ipld.ReprKind]TypeName // for Style==Kinded
Values map[string]TypeName // for Style!=Kinded
TypeHintKey string // for Style==Envelope|Inline
ContentKey string // for Style==Envelope
}
type UnionStyle struct{ x string }
var (
UnionStyle_Kinded = UnionStyle{"kinded"}
UnionStyle_Keyed = UnionStyle{"keyed"}
UnionStyle_Envelope = UnionStyle{"envelope"}
UnionStyle_Inline = UnionStyle{"inline"}
)
type TypeObject struct {
Name TypeName
TupleStyle bool // if true, ReprKind=Array instead of map (and optional fields are invalid!)
Fields []ObjectField
}
type ObjectField struct {
Name string
Type TypeName
Optional bool
Nullable bool
}
type TypeEnum struct {
Name TypeName
Values []string
}
func (TypeBool) _Type() {}
func (TypeString) _Type() {}
func (TypeBytes) _Type() {}
func (TypeInt) _Type() {}
func (TypeFloat) _Type() {}
func (TypeMap) _Type() {}
func (TypeList) _Type() {}
func (TypeLink) _Type() {}
func (TypeUnion) _Type() {}
func (TypeObject) _Type() {}
func (TypeEnum) _Type() {}
package typesystem
import (
"github.com/ipld/go-ipld-prime/typed/declaration"
)
func Construct(defns ...typedeclaration.Type) (*Universe, error) {
return nil, nil
}
package typesystem
// FIXME make this a structure that exposes immutable views
type Universe map[TypeName]Type
type Universe struct {
// namedTypes is the set of all named types in this universe.
// The map's key is the value's Name() property and must be unique.
//
// The IsAnonymous property is false for all values in this map that
// support the IsAnonymous property.
//
// Each Type in the universe may only refer to other types in their
// definition if those type are either A) in this namedTypes map,
// or B) are IsAnonymous==true.
namedTypes map[TypeName]Type
}
......@@ -16,7 +16,7 @@ func TestSimpleTypes(t *testing.T) {
anyType{name: "Foo"},
}
Wish(t,
Validate(nil, t1, n1),
Validate(Universe{}, t1, n1),
ShouldEqual, []error(nil))
})
}
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment