change project structure

This commit is contained in:
2020-11-03 10:47:19 +03:00
parent c76140ffe1
commit 44e955a047
59 changed files with 0 additions and 0 deletions

90
internal/output/output.go Normal file
View File

@ -0,0 +1,90 @@
package output
import (
"fmt"
"io/ioutil"
"log"
"os"
"runtime"
)
var (
endOfLine string = "\n"
devNull *log.Logger = log.New(ioutil.Discard, "", 0)
stdout *log.Logger = log.New(os.Stdout, "", 0)
stderr *log.Logger = log.New(os.Stderr, "", 0)
verbose *log.Logger = devNull
)
func SetQuiet(enabled bool) {
if enabled {
stdout = devNull
stderr = devNull
verbose = devNull
}
}
func SetVerbose(enabled bool) {
if enabled {
verbose = stderr
} else {
verbose = devNull
}
}
func SetEndOfLineNative() {
switch os := runtime.GOOS; os {
case "windows":
setEndOfLineWindows()
default:
setEndOfLineUnix()
}
}
func EOL() string {
return endOfLine
}
func setEndOfLineUnix() {
endOfLine = "\n"
}
func setEndOfLineWindows() {
endOfLine = "\r\n"
}
func Print(v ...interface{}) {
stdout.Print(v...)
}
func Printf(format string, v ...interface{}) {
stdout.Printf(format, v...)
}
func Println(v ...interface{}) {
stdout.Print(fmt.Sprint(v...) + endOfLine)
}
func Error(v ...interface{}) {
stderr.Print(v...)
}
func Errorf(format string, v ...interface{}) {
stderr.Printf(format, v...)
}
func Errorln(v ...interface{}) {
stderr.Print(fmt.Sprint(v...) + endOfLine)
}
func Verbose(v ...interface{}) {
verbose.Print(v...)
}
func Verbosef(format string, v ...interface{}) {
verbose.Printf(format, v...)
}
func Verboseln(v ...interface{}) {
verbose.Print(fmt.Sprint(v...) + endOfLine)
}

26
internal/types/comment.go Normal file
View File

@ -0,0 +1,26 @@
package types
type Comment struct {
Prefix string
Value string
}
func (obj *Comment) Full() string {
return obj.Prefix + obj.Value
}
func (obj *Comment) Line() string {
return obj.Prefix + obj.Value
}
func (obj *Comment) Fulln() string {
return obj.Full() + endOfLine
}
func (obj *Comment) Type() TElement {
return TComment
}
func (obj *Comment) Indent() string {
return obj.Prefix
}

50
internal/types/common.go Normal file
View File

@ -0,0 +1,50 @@
package types
import (
"runtime"
)
type TElement int
const (
TDeleted TElement = 0
TComment TElement = 1
TEmptyLine TElement = 2
TKeyValue TElement = 3
TSection TElement = 4
TTrash TElement = 5
)
var (
endOfLine string = "\n"
existing bool = false
)
func SetEndOfLineNative() {
switch os := runtime.GOOS; os {
case "windows":
SetEndOfLineWindows()
default:
SetEndOfLineUnix()
}
}
func SetEndOfLineUnix() {
endOfLine = "\n"
}
func SetEndOfLineWindows() {
endOfLine = "\r\n"
}
func SetExistingMode(value bool) {
existing = value
}
func createIfNotExist() bool {
return !existing
}
func failIfNotExist() bool {
return existing
}

24
internal/types/deleted.go Normal file
View File

@ -0,0 +1,24 @@
package types
type Deleted struct {
}
func (obj *Deleted) Full() string {
return ""
}
func (obj *Deleted) Line() string {
return ""
}
func (obj *Deleted) Fulln() string {
return ""
}
func (obj *Deleted) Type() TElement {
return TDeleted
}
func (obj *Deleted) Indent() string {
return ""
}

View File

@ -0,0 +1,9 @@
package types
type Element interface {
Full() string
Fulln() string
Line() string
Indent() string
Type() TElement
}

View File

@ -0,0 +1,25 @@
package types
type EmptyLine struct {
Prefix string
}
func (obj *EmptyLine) Full() string {
return obj.Prefix
}
func (obj *EmptyLine) Line() string {
return obj.Prefix
}
func (obj *EmptyLine) Fulln() string {
return obj.Full() + endOfLine
}
func (obj *EmptyLine) Type() TElement {
return TEmptyLine
}
func (obj *EmptyLine) Indent() string {
return obj.Prefix
}

160
internal/types/ini.go Normal file
View File

@ -0,0 +1,160 @@
package types
import (
"errors"
"strings"
)
type Ini struct {
Sections []Element
}
func (obj *Ini) Init() {
obj.Sections = append(obj.Sections, &Section{}) // global section
}
func (obj *Ini) Full() string {
var body strings.Builder
for _, line := range obj.Sections {
body.WriteString(line.Fulln())
}
return body.String()
}
func (obj *Ini) FindSection(name string) (*Section, error) {
for i, sect := range obj.Sections {
if sect.(*Section).Name == name {
return obj.Sections[i].(*Section), nil
}
}
return nil, errors.New("Section not found: " + name)
}
func (obj *Ini) DelSection(name string) error {
gotIt := false
for i, sect := range obj.Sections {
if sect.Type() == TSection &&
sect.(*Section).Name == name {
obj.Sections[i] = &Deleted{}
gotIt = true
}
}
if gotIt {
return nil
} else if failIfNotExist() {
return errors.New("Section not found: " + name)
} else {
return nil
}
}
func (obj *Ini) Get() string {
var sectList strings.Builder
for _, sect := range obj.Sections {
name := sect.(*Section).Name
if name != "" || len(sect.(*Section).Lines) > 0 {
sectList.WriteString(name + endOfLine)
}
}
return strings.TrimSuffix(sectList.String(), endOfLine)
}
func (obj *Ini) GetSection(section string) (string, error) {
sect, err := obj.FindSection(section)
if err != nil {
return "", err
} else {
return sect.Full(), nil
}
}
func (obj *Ini) GetKey(section, key string) (string, error) {
sect, err := obj.FindSection(section)
if err != nil {
return "", err
} else {
return sect.GetKey(key)
}
}
func (obj *Ini) GetKeyVal(section, key, value string) error {
sect, err := obj.FindSection(section)
if err != nil {
return err
} else {
return sect.GetKeyVal(key, value)
}
}
func (obj *Ini) AddSection(section string) *Section {
sect, err := obj.FindSection(section)
if err != nil {
sectSize := len(obj.Sections)
if sectSize > 1 {
prevSect := obj.Sections[sectSize-1].(*Section)
lineSize := len(prevSect.Lines)
if lineSize == 0 || lineSize > 0 && prevSect.Lines[lineSize-1].Type() != TEmptyLine {
obj.Sections[sectSize-1].(*Section).Lines = append(obj.Sections[sectSize-1].(*Section).Lines, &EmptyLine{})
}
}
var newSection Section
newSection.Name = section
newSection.Prefix = obj.Sections[len(obj.Sections)-1].Indent()
sect = &newSection
obj.Sections = append(obj.Sections, sect)
}
return sect
}
func (obj *Ini) SetSection(section string) *Section {
return obj.AddSection(section)
}
func (obj *Ini) AddKey(section, key, value string, reverse bool) error {
sect, err := obj.FindSection(section)
if err != nil {
if createIfNotExist() {
sect = obj.AddSection(section)
} else {
return err
}
}
sect.AddKey(key, value, reverse)
return nil
}
func (obj *Ini) SetKey(section, key, value string) error {
sect, err := obj.FindSection(section)
if err != nil {
if createIfNotExist() {
sect = obj.AddSection(section)
} else {
return err
}
}
return sect.SetKey(key, value)
}
func (obj *Ini) DelKey(section, key string) error {
sect, err := obj.FindSection(section)
if err != nil {
if failIfNotExist() {
return err
} else {
return nil
}
}
return sect.DelKey(key)
}
func (obj *Ini) DelKeyVal(section, key, value string) error {
sect, err := obj.FindSection(section)
if err != nil {
if failIfNotExist() {
return err
} else {
return nil
}
}
return sect.DelKeyVal(key, value)
}

View File

@ -0,0 +1,38 @@
package types
type KeyValue struct {
PrefixKey string
Key string
PostfixKey string
PrefixValue string
Value string
PostfixValue string
Comment Comment
}
func (obj *KeyValue) Full() string {
return obj.PrefixKey +
obj.Key +
obj.PostfixKey +
"=" +
obj.PrefixValue +
obj.Value +
obj.PostfixValue +
obj.Comment.Full()
}
func (obj *KeyValue) Line() string {
return obj.Full()
}
func (obj *KeyValue) Fulln() string {
return obj.Full() + endOfLine
}
func (obj *KeyValue) Type() TElement {
return TKeyValue
}
func (obj *KeyValue) Indent() string {
return obj.PrefixKey
}

200
internal/types/section.go Normal file
View File

@ -0,0 +1,200 @@
package types
import (
"errors"
"strings"
)
type Section struct {
Prefix string
Name string
Postfix string
Comment Comment
Lines []Element
}
func (obj *Section) Headern() string {
if obj.Name == "" {
return ""
} else {
return obj.Prefix + "[" + obj.Name + "]" + obj.Postfix + obj.Comment.Full() + endOfLine
}
}
func (obj *Section) Line() string {
return obj.Header()
}
func (obj *Section) Header() string {
return strings.TrimSuffix(obj.Headern(), endOfLine)
}
func (obj *Section) Fulln() string {
var body strings.Builder
for _, line := range obj.Lines {
body.WriteString(line.Fulln())
}
return obj.Headern() + body.String()
}
func (obj *Section) Full() string {
return strings.TrimSuffix(obj.Fulln(), endOfLine)
}
func (obj *Section) Type() TElement {
return TSection
}
func (obj *Section) Indent() string {
return obj.Prefix
}
func (obj *Section) DelKey(name string) error {
gotIt := false
for i, keyVal := range obj.Lines {
if keyVal.Type() == TKeyValue &&
keyVal.(*KeyValue).Key == name {
obj.Lines[i] = &Deleted{}
gotIt = true
}
}
if gotIt {
return nil
} else if failIfNotExist() {
return errors.New("Parameter not found: " + name)
} else {
return nil
}
}
func (obj *Section) DelKeyVal(name, value string) error {
gotIt := false
for i, keyVal := range obj.Lines {
if keyVal.Type() == TKeyValue &&
keyVal.(*KeyValue).Key == name &&
keyVal.(*KeyValue).Value == value {
obj.Lines[i] = &Deleted{}
gotIt = true
}
}
if gotIt {
return nil
} else if failIfNotExist() {
return errors.New("Parameter:value pair not found: " + name + ":" + value)
} else {
return nil
}
}
func (obj *Section) GetKey(name string) (string, error) {
var err error = nil
var result strings.Builder
for _, keyVal := range obj.Lines {
if keyVal.Type() == TKeyValue && keyVal.(*KeyValue).Key == name {
result.WriteString(keyVal.(*KeyValue).Value + endOfLine)
}
}
if result.String() == "" {
err = errors.New("Parameter not found: " + name)
}
return strings.TrimSuffix(result.String(), endOfLine), err
}
func (obj *Section) GetKeyVal(name, value string) error {
for _, keyVal := range obj.Lines {
if keyVal.Type() == TKeyValue &&
keyVal.(*KeyValue).Key == name &&
keyVal.(*KeyValue).Value == value {
return nil
}
}
return errors.New("Parameter:Value not found: " + name + ":" + value)
}
func (obj *Section) appendKey(name, value string, reverse bool) {
var newKeyValue KeyValue
var replaceIndex int = -1
newKeyValue.Key = name
newKeyValue.Value = value
if reverse {
// for right indent and tabs
for i := 0; i < len(obj.Lines); i++ {
if obj.Lines[i].Type() == TKeyValue {
template := obj.Lines[i].(*KeyValue)
newKeyValue.PrefixKey = template.PrefixKey
newKeyValue.PostfixKey = template.PostfixKey
newKeyValue.PrefixValue = template.PrefixValue
newKeyValue.PostfixValue = template.PostfixValue
break
}
}
obj.Lines = append([]Element{&newKeyValue}, obj.Lines...)
} else {
// replace first emptyline
for i := len(obj.Lines) - 1; i >= 0; i-- {
if obj.Lines[i].Type() == TEmptyLine {
replaceIndex = i
} else {
break
}
}
// for right indent and tabs
for i := len(obj.Lines) - 1; i >= 0; i-- {
if obj.Lines[i].Type() == TKeyValue {
template := obj.Lines[i].(*KeyValue)
newKeyValue.PrefixKey = template.PrefixKey
newKeyValue.PostfixKey = template.PostfixKey
newKeyValue.PrefixValue = template.PrefixValue
newKeyValue.PostfixValue = template.PostfixValue
break
}
}
if replaceIndex == -1 {
obj.Lines = append(obj.Lines, &newKeyValue)
} else {
obj.Lines = append(obj.Lines, obj.Lines[replaceIndex])
obj.Lines[replaceIndex] = &newKeyValue
}
}
}
func (obj *Section) AddKey(name, value string, reverse bool) {
gotIt := false
for i, keyVal := range obj.Lines {
if keyVal.Type() == TKeyValue &&
keyVal.(*KeyValue).Key == name &&
keyVal.(*KeyValue).Value == value {
if !gotIt {
gotIt = true
} else {
obj.Lines[i] = &Deleted{}
}
}
}
if !gotIt {
obj.appendKey(name, value, reverse)
}
}
func (obj *Section) SetKey(name, value string) error {
gotIt := false
for i, keyVal := range obj.Lines {
if keyVal.Type() == TKeyValue &&
keyVal.(*KeyValue).Key == name {
if !gotIt {
keyVal.(*KeyValue).Value = value
gotIt = true
} else {
obj.Lines[i] = &Deleted{}
}
}
}
if !gotIt {
if createIfNotExist() {
obj.appendKey(name, value, false)
} else {
return errors.New("Parameter not found: " + name)
}
}
return nil
}

25
internal/types/trash.go Normal file
View File

@ -0,0 +1,25 @@
package types
type Trash struct {
Value string
}
func (obj *Trash) Full() string {
return obj.Value
}
func (obj *Trash) Line() string {
return obj.Value
}
func (obj *Trash) Fulln() string {
return obj.Full() + endOfLine
}
func (obj *Trash) Type() TElement {
return TTrash
}
func (obj *Trash) Indent() string {
return ""
}