package main import ( "bytes" "encoding/json" "fmt" "strconv" "strings" "github.com/google/uuid" ) type Action interface { Run(row ContentRow) error //publishRow(row ContentRow) error //publishErrorRow(row ContentRow) error //Start() //Finish() Status() ActionStatus Validate() error GetActionID() uuid.UUID GetActionConfig() ActionConfig } type Schema struct { Columns []ColumnDefinition } type ColumnDefinition struct { Name string ID uuid.UUID Type DataType DefaultValue string } type ContentRow struct { Schema *Schema Values map[uuid.UUID]string Raw string Source *uuid.UUID } type ActionConfig struct { ActionID uuid.UUID Type ActionType OutputSchema *Schema Inputs []InputDefinition } type InputDefinition struct { InputSchema *Schema ActionID *uuid.UUID // TODO: decide if input types exist } type ActionStatus struct { State StateValue ExpectedRows int64 HandledRows int64 } // DataType - Custom type to hold value for data type ranging from 1-5 type DataType int // Declare related constants for each datatype starting with index 1 const ( String DataType = iota + 1 Integer Float Date DateTime ) // String - Creating common behavior give the type a String function func (d DataType) String() string { return [...]string{"String", "Integer", "Float", "Date", "DateTime"}[d-1] } // EnumIndex - Creating common behavior give the type a EnumIndex function func (d DataType) EnumIndex() int { return int(d) } // MarshalJSON marshals the enum as a quoted json string func (s DataType) MarshalJSON() ([]byte, error) { buffer := bytes.NewBufferString(`"`) buffer.WriteString(s.String()) buffer.WriteString(`"`) return buffer.Bytes(), nil } // UnmarshalJSON unmashals a quoted json string to the enum value func (s *DataType) UnmarshalJSON(b []byte) error { var j string err := json.Unmarshal(b, &j) if err != nil { return err } // Note that if the string cannot be found then it will be set to the zero value, 'String' in this case. var toID = map[string]DataType{ "String": String, "Integer": Integer, "Float": Float, "Date": Date, "DateTime": DateTime, } *s = toID[j] return nil } func ValidateDataType(in string, dataType DataType) (bool, error) { switch dataType { case String: return ValidStringDataType(in), nil case Integer: return ValidIntegerDataType(in) case Float: return ValidFloatDataType(in) case Date: return ValidDateDataType(in) case DateTime: return ValidDateTimeDataType(in) default: return false, nil } } func ValidStringDataType(in string) bool { return true } func ValidIntegerDataType(in string) (bool, error) { i, err := strconv.ParseInt(in, 10, 64) if err != nil { return false, err } return strings.EqualFold(in, fmt.Sprintf("%v", i)), nil } func ValidFloatDataType(in string) (bool, error) { i, err := strconv.ParseFloat(in, 64) if err != nil { return false, err } return strings.EqualFold(in, fmt.Sprintf("%v", i)), nil } func ValidDateDataType(in string) (bool, error) { // TODO: implement return false, nil } func ValidDateTimeDataType(in string) (bool, error) { // TODO: implement return false, nil } // ActionType - Custom type to hold value for data type ranging from 1-5 type ActionType int const ( StdIn ActionType = iota + 1 ModifyColumn StdOut ) // String - Creating common behavior give the type a String function func (d ActionType) String() string { return [...]string{"StdIn", "ModifyColumn", "StdOut"}[d-1] } // EnumIndex - Creating common behavior give the type a EnumIndex function func (d ActionType) EnumIndex() int { return int(d) } // MarshalJSON marshals the enum as a quoted json string func (s ActionType) MarshalJSON() ([]byte, error) { buffer := bytes.NewBufferString(`"`) buffer.WriteString(s.String()) buffer.WriteString(`"`) return buffer.Bytes(), nil } // UnmarshalJSON unmashals a quoted json string to the enum value func (s *ActionType) UnmarshalJSON(b []byte) error { var j string err := json.Unmarshal(b, &j) if err != nil { return err } // Note that if the string cannot be found then it will be set to the zero value, 'String' in this case. var toID = map[string]ActionType{ "StdIn": StdIn, "ModifyColumn": ModifyColumn, "StdOut": StdOut, } *s = toID[j] return nil } // StateValue - Custom type to hold value for data type ranging from 1-5 type StateValue int // Declare related constants for each datatype starting with index 1 const ( NotStarted StateValue = iota + 1 Paused Running Finished ) // String - Creating common behavior give the type a String function func (d StateValue) String() string { return [...]string{"NotStarted", "Paused", "Running", "Finished"}[d-1] } // EnumIndex - Creating common behavior give the type a EnumIndex function func (d StateValue) EnumIndex() int { return int(d) } // MarshalJSON marshals the enum as a quoted json string func (s StateValue) MarshalJSON() ([]byte, error) { buffer := bytes.NewBufferString(`"`) buffer.WriteString(s.String()) buffer.WriteString(`"`) return buffer.Bytes(), nil } // UnmarshalJSON unmashals a quoted json string to the enum value func (s *StateValue) UnmarshalJSON(b []byte) error { var j string err := json.Unmarshal(b, &j) if err != nil { return err } // Note that if the string cannot be found then it will be set to the zero value, 'String' in this case. var toID = map[string]StateValue{ "NotStarted": NotStarted, "Paused": Paused, "Running": Running, "Finished": Finished, } *s = toID[j] return nil }