package ast type ( // ParamType holds the necessary information about a parameter type for the parser to lookup for. ParamType interface { // The name of the parameter type. // Indent should contain the characters for the parser. Indent() string } // MasterParamType if implemented and its `Master()` returns true then empty type param will be translated to this param type. // Also its functions will be available to the rest of the macro param type's funcs. // // Only one Master is allowed. MasterParamType interface { ParamType Master() bool } // TrailingParamType if implemented and its `Trailing()` returns true // then it should be declared at the end of a route path and can accept any trailing path segment as one parameter. TrailingParamType interface { ParamType Trailing() bool } // AliasParamType if implemeneted nad its `Alias()` returns a non-empty string // then the param type can be written with that string literal too. AliasParamType interface { ParamType Alias() string } ) // IsMaster returns true if the "pt" param type is a master one. func IsMaster(pt ParamType) bool { p, ok := pt.(MasterParamType) return ok && p.Master() } // IsTrailing returns true if the "pt" param type is a marked as trailing, // which should accept more than one path segment when in the end. func IsTrailing(pt ParamType) bool { p, ok := pt.(TrailingParamType) return ok && p.Trailing() } // HasAlias returns any alias of the "pt" param type. // If alias is empty or not found then it returns false as its second output argument. func HasAlias(pt ParamType) (string, bool) { if p, ok := pt.(AliasParamType); ok { alias := p.Alias() return alias, len(alias) > 0 } return "", false } // GetMasterParamType accepts a list of ParamType and returns its master. // If no `Master` specified: // and len(paramTypes) > 0 then it will return the first one, // otherwise it returns nil. func GetMasterParamType(paramTypes ...ParamType) ParamType { for _, pt := range paramTypes { if IsMaster(pt) { return pt } } if len(paramTypes) > 0 { return paramTypes[0] } return nil } // LookupParamType accepts the string // representation of a parameter type. // Example: // "string" // "number" or "int" // "long" or "int64" // "uint8" // "uint64" // "boolean" or "bool" // "alphabetical" // "file" // "path" func LookupParamType(indentOrAlias string, paramTypes ...ParamType) (ParamType, bool) { for _, pt := range paramTypes { if pt.Indent() == indentOrAlias { return pt, true } if alias, has := HasAlias(pt); has { if alias == indentOrAlias { return pt, true } } } return nil, false } // ParamStatement is a struct // which holds all the necessary information about a macro parameter. // It holds its type (string, int, alphabetical, file, path), // its source ({param:type}), // its name ("param"), // its attached functions by the user (min, max...) // and the http error code if that parameter // failed to be evaluated. type ParamStatement struct { Src string // the original unparsed source, i.e: {id:int range(1,5) else 404} Name string // id Type ParamType // int Funcs []ParamFunc // range ErrorCode int // 404 } // ParamFunc holds the name of a parameter's function // and its arguments (values) // A param func is declared with: // {param:int range(1,5)}, // the range is the // param function name // the 1 and 5 are the two param function arguments // range(1,5) type ParamFunc struct { Name string // range Args []string // ["1","5"] }