You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
241 lines
5.0 KiB
241 lines
5.0 KiB
// ------------------------------------------------------------------------
|
|
// Project atila
|
|
// Active Thing (activething.com) git.activething.com/go
|
|
//
|
|
// File name f.go
|
|
// Created by DEV
|
|
// Modified 29/01/2024
|
|
//
|
|
// Copyright 2024 activething.com
|
|
// ------------------------------------------------------------------------
|
|
// Licensed under the Apache License, Version 2.0 (the "License");
|
|
// you may not use this file except in compliance with the License.
|
|
// You may obtain a copy of the License at
|
|
//
|
|
// http://www.apache.org/licenses/LICENSE-2.0
|
|
//
|
|
// Unless required by applicable law or agreed to in writing, software
|
|
// distributed under the License is distributed on an "AS IS" BASIS,
|
|
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
// See the License for the specific language governing permissions and
|
|
// limitations under the License.
|
|
// ------------------------------------------------------------------------
|
|
|
|
package apacks
|
|
|
|
import (
|
|
"bits"
|
|
"reflect"
|
|
"strings"
|
|
"time"
|
|
"unicode"
|
|
)
|
|
|
|
const (
|
|
|
|
FlagOmit Flags = 1 << iota
|
|
FlagOmitEmpty
|
|
FlagQuote
|
|
FlagScapeHTML
|
|
FlagString
|
|
FlagEncrypted
|
|
|
|
FlagBinary64 Flags = 0b0000100000000000
|
|
FlagBinary32 Flags = 0b0000010000000000
|
|
flagMaskBin Flags = 0b0000110000000000
|
|
|
|
FlagDateRFC822 Flags = 0b0001000000000000
|
|
FlagDateUnix Flags = 0b0010000000000000
|
|
FlagDateANSIC Flags = 0b0100000000000000
|
|
FlagDateRFC850 Flags = 0b1000000000000000
|
|
flagMaskDate Flags = 0b1111000000000000
|
|
|
|
)
|
|
|
|
|
|
type Flags bits.BFlags16
|
|
|
|
|
|
func (f Flags) Omit () bool {
|
|
return f&FlagOmit != 0 }
|
|
|
|
|
|
func (f Flags) OmitEmpty () bool {
|
|
return f&FlagOmitEmpty != 0 }
|
|
|
|
|
|
func (f Flags) Quote () bool {
|
|
return f&FlagQuote != 0 }
|
|
|
|
|
|
func (f Flags) EscapeHTML () bool {
|
|
return f&FlagScapeHTML != 0 }
|
|
|
|
|
|
func (f Flags) String () bool {
|
|
return f&FlagString != 0 }
|
|
|
|
|
|
func (f Flags) Encrypted() bool {
|
|
return f&FlagEncrypted != 0 }
|
|
|
|
|
|
func (f Flags) Binary () bool {
|
|
return f&(FlagBinary64|FlagBinary32) != 0 }
|
|
|
|
|
|
func (f Flags) Bin64 () bool {
|
|
return f&FlagBinary64 != 0 }
|
|
|
|
|
|
func (f Flags) Bin32 () bool {
|
|
return f&FlagBinary32 != 0 }
|
|
|
|
|
|
|
|
|
|
func (f Flags) SetDate (flagDate Flags) Flags {
|
|
return (f&flagMaskDate) | flagDate }
|
|
|
|
|
|
func (f Flags) SetBinary (flagBinary Flags) Flags {
|
|
return (f&flagMaskBin) | flagBinary }
|
|
|
|
|
|
|
|
|
|
func (f Flags) Names () string {
|
|
var ls []string
|
|
if f&FlagOmit != 0 { ls = append(ls,"omit")}
|
|
if f&FlagOmitEmpty != 0 { ls = append(ls,"omitempty")}
|
|
if f&FlagQuote != 0 { ls = append(ls,"quote")}
|
|
if f&FlagScapeHTML != 0 { ls = append(ls,"html")}
|
|
if f&FlagString != 0 { ls = append(ls,"string")}
|
|
|
|
if f&flagMaskBin != 0 {
|
|
ls = append(ls,f.binName())
|
|
}
|
|
if f&flagMaskDate != 0 {
|
|
ls = append(ls,f.dateName())
|
|
}
|
|
|
|
if len(ls) > 0 {
|
|
return strings.Join(ls,",")
|
|
}
|
|
return ""
|
|
}
|
|
|
|
|
|
func (f Flags) binName () string {
|
|
switch f & flagMaskBin {
|
|
case FlagBinary64 : return "b64"
|
|
case FlagBinary32 : return "b32"
|
|
}
|
|
return ""
|
|
}
|
|
|
|
|
|
func (f Flags) dateName() string {
|
|
switch f & flagMaskDate {
|
|
case FlagDateUnix : return "unix"
|
|
case FlagDateRFC822: return "rfc822"
|
|
case FlagDateANSIC : return "ansic"
|
|
case FlagDateRFC850: return "rfc8550"
|
|
default: return "rfc822z"
|
|
}
|
|
}
|
|
|
|
|
|
func (f Flags) DateFormat () string {
|
|
switch f & flagMaskDate {
|
|
case FlagDateUnix : return time.UnixDate
|
|
case FlagDateRFC822: return time.RFC822
|
|
case FlagDateANSIC : return time.ANSIC
|
|
case FlagDateRFC850: return time.RFC850
|
|
default: return time.RFC822Z
|
|
}
|
|
}
|
|
|
|
|
|
func FlagByName (flag string) (f Flags) {
|
|
switch strings.ToLower(flag) {
|
|
|
|
case "-","omit" : return FlagOmit
|
|
case "o","omitempty": return FlagOmitEmpty
|
|
case "q","quote" : return FlagQuote
|
|
case "h","html" : return FlagScapeHTML
|
|
case "s","string" : return FlagString
|
|
case "e","encrypted": return FlagEncrypted
|
|
|
|
// formato binario
|
|
case "b64","bin64" : return FlagBinary64
|
|
case "b32","bin32" : return FlagBinary32
|
|
|
|
// formatos de fechas
|
|
case "unix" : return FlagDateUnix
|
|
case "rfc822" : return FlagDateRFC822
|
|
case "ansic" : return FlagDateANSIC
|
|
case "rfc850" : return FlagDateRFC850
|
|
case "rfc822z": return 0
|
|
|
|
default: return 0
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
func FlagsWithNames(flags ... string) Flags {
|
|
var f Flags
|
|
for _,n := range flags {
|
|
f |= FlagByName(n)
|
|
}
|
|
return f
|
|
}
|
|
|
|
|
|
|
|
func FlagsWithString(flags string, onOption func(string) Flags) Flags {
|
|
|
|
var f Flags
|
|
if len(flags) == 0 {
|
|
return f
|
|
}
|
|
nf := f
|
|
for flags != "" {
|
|
var op string
|
|
op,flags,_ = strings.Cut(flags,",")
|
|
nf |= onOption(op)
|
|
}
|
|
return nf
|
|
}
|
|
|
|
func FlagsFromPackTag (raw reflect.StructTag) (string,Flags,bool) {
|
|
return FlagsFromTag(raw,TagKey,FlagByName) }
|
|
|
|
|
|
|
|
func FlagsFromTag(raw reflect.StructTag, tag string, onOption func(string) Flags) (string,Flags,bool) {
|
|
st,ok := raw.Lookup(tag)
|
|
if !ok {
|
|
return "",0,false
|
|
}
|
|
nm,op,_ := strings.Cut(st,",")
|
|
return nm,FlagsWithString(op,onOption),true
|
|
}
|
|
|
|
|
|
func CheckTag(tag string) bool {
|
|
if tag == "" {
|
|
return false
|
|
}
|
|
for _, c := range tag {
|
|
switch {
|
|
case strings.ContainsRune("!#$%&()*+-./:;<=>?@[]^_{|}~ ", c):
|
|
case !unicode.IsLetter(c) && !unicode.IsDigit(c):
|
|
return false
|
|
}
|
|
}
|
|
return true
|
|
} |