2021-12-29 20:57:14 +00:00
|
|
|
// Package gg implements graph serialization to/from the gg text format.
|
2017-10-21 18:39:23 +00:00
|
|
|
package gg
|
|
|
|
|
2021-12-26 23:23:41 +00:00
|
|
|
import (
|
|
|
|
"fmt"
|
2021-12-29 19:32:53 +00:00
|
|
|
|
2023-10-28 07:53:37 +00:00
|
|
|
"code.betamike.com/mediocregopher/ginger/graph"
|
2021-12-26 23:23:41 +00:00
|
|
|
)
|
|
|
|
|
2023-10-21 15:42:31 +00:00
|
|
|
// Type aliases for convenience
|
|
|
|
type (
|
|
|
|
Graph = graph.Graph[OptionalValue, Value]
|
|
|
|
OpenEdge = graph.OpenEdge[OptionalValue, Value]
|
|
|
|
)
|
2021-12-28 16:49:02 +00:00
|
|
|
|
2021-12-29 20:57:14 +00:00
|
|
|
// Value represents a value which can be serialized by the gg text format.
|
2018-01-21 15:39:25 +00:00
|
|
|
type Value struct {
|
2021-12-28 16:49:02 +00:00
|
|
|
// Only one of these fields may be set
|
2021-12-27 17:11:07 +00:00
|
|
|
Name *string
|
|
|
|
Number *int64
|
2021-12-30 16:56:20 +00:00
|
|
|
Graph *Graph
|
2021-12-28 16:49:02 +00:00
|
|
|
}
|
|
|
|
|
2022-03-31 15:18:02 +00:00
|
|
|
// Name returns a name Value.
|
|
|
|
func Name(name string) Value {
|
|
|
|
return Value{Name: &name}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Number returns a number Value.
|
|
|
|
func Number(n int64) Value {
|
|
|
|
return Value{Number: &n}
|
|
|
|
}
|
|
|
|
|
2021-12-29 19:32:53 +00:00
|
|
|
// Equal returns true if the passed in Value is equivalent, ignoring the
|
|
|
|
// LexerToken on either Value.
|
|
|
|
//
|
|
|
|
// Will panic if the passed in v2 is not a Value from this package.
|
|
|
|
func (v Value) Equal(v2g graph.Value) bool {
|
|
|
|
|
|
|
|
v2 := v2g.(Value)
|
|
|
|
|
2021-12-27 17:11:07 +00:00
|
|
|
switch {
|
|
|
|
|
|
|
|
case v.Name != nil && v2.Name != nil && *v.Name == *v2.Name:
|
|
|
|
return true
|
|
|
|
|
|
|
|
case v.Number != nil && v2.Number != nil && *v.Number == *v2.Number:
|
|
|
|
return true
|
|
|
|
|
2021-12-29 19:32:53 +00:00
|
|
|
case v.Graph != nil && v2.Graph != nil && v.Graph.Equal(v2.Graph):
|
2021-12-27 17:11:07 +00:00
|
|
|
return true
|
|
|
|
|
|
|
|
default:
|
|
|
|
return false
|
2018-01-21 15:39:25 +00:00
|
|
|
}
|
2017-11-24 18:05:58 +00:00
|
|
|
}
|
|
|
|
|
2021-12-26 23:23:41 +00:00
|
|
|
func (v Value) String() string {
|
|
|
|
|
|
|
|
switch {
|
|
|
|
|
|
|
|
case v.Name != nil:
|
|
|
|
return *v.Name
|
|
|
|
|
|
|
|
case v.Number != nil:
|
|
|
|
return fmt.Sprint(*v.Number)
|
|
|
|
|
|
|
|
case v.Graph != nil:
|
|
|
|
return v.Graph.String()
|
|
|
|
|
|
|
|
default:
|
2023-10-21 15:42:31 +00:00
|
|
|
panic("no fields set on Value")
|
2017-11-05 16:57:57 +00:00
|
|
|
}
|
2017-12-03 19:38:53 +00:00
|
|
|
}
|
2023-10-21 15:42:31 +00:00
|
|
|
|
|
|
|
// OptionalValue is a Value which may be unset. This is used for edge values,
|
|
|
|
// since edges might not have a value.
|
|
|
|
type OptionalValue struct {
|
|
|
|
Value
|
|
|
|
Valid bool
|
|
|
|
}
|
|
|
|
|
|
|
|
// None is the zero OptionalValue (hello rustaceans).
|
|
|
|
var None OptionalValue
|
|
|
|
|
|
|
|
// Some wraps a Value to be an OptionalValue.
|
|
|
|
func Some(v Value) OptionalValue {
|
|
|
|
return OptionalValue{Valid: true, Value: v}
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v OptionalValue) String() string {
|
|
|
|
if !v.Valid {
|
|
|
|
return "<none>"
|
|
|
|
}
|
|
|
|
return v.Value.String()
|
|
|
|
}
|
|
|
|
|
|
|
|
func (v OptionalValue) Equal(v2g graph.Value) bool {
|
|
|
|
var v2 OptionalValue
|
|
|
|
|
|
|
|
if v2Val, ok := v2g.(Value); ok {
|
|
|
|
v2 = Some(v2Val)
|
|
|
|
} else {
|
|
|
|
v2 = v2g.(OptionalValue)
|
|
|
|
}
|
|
|
|
|
|
|
|
if v.Valid != v2.Valid {
|
|
|
|
return false
|
|
|
|
} else if !v.Valid {
|
|
|
|
return true
|
|
|
|
}
|
|
|
|
|
|
|
|
return v.Value.Equal(v2.Value)
|
|
|
|
}
|