1 Commits dd85328e15 ... 03bb9f4e7b

Author SHA1 Message Date
  zry 03bb9f4e7b Add 'TimeFormatEx' and its dependency. 4 years ago

+ 7 - 7
tests/test4/main.go

@@ -7,18 +7,18 @@ import (
 )
 
 func main() {
-	tf := timefmt.NewTimeFormatter("!<y>-<mon>-<d> <h24>:<min>:<s> <tz> <tzA>", false)
+	tf := timefmt.NewDefaultTimeFormatter("!<y>-<mon>-<d> <h24>:<min>:<s> <tz> <tzA>", false)
 	fmt.Println(tf.Format(time.Now()))
-	tf = timefmt.NewTimeFormatter("!<UTC><y>-<mon>-<d> <h24>:<min>:<s> <tz> <tzA>", false)
+	tf = timefmt.NewDefaultTimeFormatter("!<UTC><y>-<mon>-<d> <h24>:<min>:<s> <tz> <tzA>", false)
 	fmt.Println(tf.Format(time.Now()))
-	tf = timefmt.NewTimeFormatter("!<Timezone:+0900JST><y>-<mon>-<d> <h24>:<min>:<s><br><tz> <tzA>", true)
+	tf = timefmt.NewDefaultTimeFormatter("!<Timezone:+0900JST><y>-<mon>-<d> <h24>:<min>:<s><br><tz> <tzA>", true)
 	fmt.Println(tf.Format(time.Now()))
-	tf = timefmt.NewTimeFormatter("!<Timezone:+0900JST><y>-<mon>-<d> <h24>:<min>:<s><br><tz> <tzA>", false)
+	tf = timefmt.NewDefaultTimeFormatter("!<Timezone:+0900JST><y>-<mon>-<d> <h24>:<min>:<s><br><tz> <tzA>", false)
 	fmt.Println(tf.Format(time.Now()))
-	tf = timefmt.NewTimeFormatter("yyyy-MM-dd HH:mm:ss z Z", false)
+	tf = timefmt.NewDefaultTimeFormatter("yyyy-MM-dd HH:mm:ss z Z", false)
 	fmt.Println(tf.Format(time.Now()))
-	tf = timefmt.NewTimeFormatter("!yyyy-MM-dd HH:mm:ss z Z", false)
+	tf = timefmt.NewDefaultTimeFormatter("!yyyy-MM-dd HH:mm:ss z Z", false)
 	fmt.Println(tf.Format(time.Now()))
-	tf = timefmt.NewTimeFormatter("!!yyyy-MM-dd HH:mm:ss z Z", false)
+	tf = timefmt.NewDefaultTimeFormatter("!!yyyy-MM-dd HH:mm:ss z Z", false)
 	fmt.Println(tf.Format(time.Now()))
 }

+ 40 - 0
tests/test5/main.go

@@ -0,0 +1,40 @@
+package main
+
+import (
+	"fmt"
+	"git.swzry.com/zry/YAGTF/yagtf/tfelem"
+	"git.swzry.com/zry/YAGTF/yagtf/timefmt"
+	"time"
+)
+
+func main() {
+	printer := timefmt.NewTimePrinterEx()
+	parser := timefmt.NewFormatParser(true)
+	parser.AddExDataTag("level", func() timefmt.TimeElementEx {
+		return tfelem.NewExDataElement(4, "level")
+	})
+	parser.AddExDataTag("app", func() timefmt.TimeElementEx {
+		return tfelem.NewExDataElement(64, "app")
+	})
+	parser.AddExDataTag("msg", func() timefmt.TimeElementEx {
+		return tfelem.NewExDataElement(2048, "msg")
+	})
+	tf := timefmt.NewTimeFormatterEx(printer, parser, false)
+	tf.ParseFormat("![<y>-<mon>-<d> <h24>:<min>:<s> <tz> <tzA>] <lt><level><gt> <app> : <msg>")
+	logtest(tf, "INFO", "test1.app", "hello, world")
+	logtest(tf, "WARN", "test2.app", "hello, gensokyo")
+	logtest(tf, "INFO", "test3.app", "the quick brown fox jumps over a lazy dog.")
+	logtest(tf, "INFO", "test4.app", "Unicode Test With Emoji 1:☁⚡🪁🗝️👨, 👨💡, 📍✔️. ⛪❌📍. ☁⚡, ☁⚡⛪, ⛪🔥, 🏢️📍✔️.")
+	logtest(tf, "INFO", "test5.app", "Unicode Test With Emoji 2:🇨🇳, 1980 < 📅 < 2015, 👶✖️1 = ✔️; 📅 > 2015, 👶✖️2 = ✔️.")
+	logtest(tf, "INFO", "test6.app", "Unicode Test With Emoji 3:👦✂🔌, ⚡👦, 🚑🏥, 😷💉, 😷😱, 👦☠️. 👵🏽😭, 💴⚰️, 👮⚰️❌, 🔥💀->⚱️✔️.")
+	logtest(tf, "INFO", "test7.app", "Unicode Test With Emoji 4:👦🚬🚄, 👮🚭, 💴, 👦👿, 👦💣💥🚔, 👮😱, 👮🔫👦, 👦☠️.")
+	logtest(tf, "INFO", "test8.app", "Unicode Test With Chinese and Emoji: 魔理沙偷走了重要的📚, 帕秋莉👿.")
+}
+
+func logtest(tf *timefmt.TimeFormatterEx, level string, app string, msg string) {
+	exdata := make(map[string]string)
+	exdata["level"] = level
+	exdata["app"] = app
+	exdata["msg"] = msg
+	fmt.Println(tf.Format(time.Now(), exdata))
+}

+ 30 - 0
yagtf/tfelem/exdata.go

@@ -0,0 +1,30 @@
+package tfelem
+
+import (
+	"time"
+)
+
+type ExDataElement struct {
+	expsize   int
+	fieldname string
+}
+
+func (this *ExDataElement) ExpectedSize() int {
+	return this.expsize
+}
+
+func (this *ExDataElement) PrintElementEx(t time.Time, data map[string]string) string {
+	v, ok := data[this.fieldname]
+	if ok {
+		return v
+	} else {
+		return ""
+	}
+}
+
+func NewExDataElement(expsize int, fieldname string) *ExDataElement {
+	return &ExDataElement{
+		expsize:   expsize,
+		fieldname: fieldname,
+	}
+}

+ 21 - 0
yagtf/timefmt/basic_wrap.go

@@ -0,0 +1,21 @@
+package timefmt
+
+import (
+	"time"
+)
+
+type BasicTimeElementWrap struct {
+	basic TimeElement
+}
+
+func (this *BasicTimeElementWrap) ExpectedSize() int {
+	return this.basic.ExpectedSize()
+}
+
+func (this *BasicTimeElementWrap) PrintElementEx(t time.Time, data map[string]string) string {
+	return this.basic.PrintElement(t)
+}
+
+func NewBasicTimeElementWrap(b TimeElement) *BasicTimeElementWrap {
+	return &BasicTimeElementWrap{basic: b}
+}

+ 86 - 0
yagtf/timefmt/exprinter.go

@@ -0,0 +1,86 @@
+package timefmt
+
+import (
+	"bytes"
+	"git.swzry.com/zry/YAGTF/yagtf/tfelem"
+	"time"
+)
+
+type TimeElementEx interface {
+	PrintElementEx(t time.Time, exdata map[string]string) string
+	ExpectedSize() int
+}
+
+type TimePrinterEx struct {
+	elementList  []TimeElementEx
+	expectedSize int
+	forceTz      bool
+	forceUTC     bool
+	forceLocal   bool
+	forceTzVal   *time.Location
+}
+
+func (this *TimePrinterEx) UseArgumentSpecifiedTimezone() {
+	this.forceTz = false
+}
+
+func (this *TimePrinterEx) UseTimezone(tz *time.Location) {
+	this.forceTz = true
+	this.forceLocal = false
+	this.forceUTC = false
+	this.forceTzVal = tz
+}
+
+func (this *TimePrinterEx) UseLocalTimezone() {
+	this.forceTz = true
+	this.forceLocal = true
+	this.forceUTC = false
+}
+
+func (this *TimePrinterEx) UseUTC() {
+	this.forceTz = true
+	this.forceLocal = false
+	this.forceUTC = true
+}
+
+func (this *TimePrinterEx) AddPureText(text string) {
+	e := &tfelem.PureTextElement{
+		PureText: text,
+	}
+	this.AddTimeElement(e)
+}
+
+func (this *TimePrinterEx) AddTimeElement(e TimeElement) {
+	this.AddTimeElementEx(NewBasicTimeElementWrap(e))
+}
+
+func (this *TimePrinterEx) AddTimeElementEx(e TimeElementEx) {
+	this.elementList = append(this.elementList, e)
+	this.expectedSize += e.ExpectedSize()
+}
+
+func (this *TimePrinterEx) PrintTimeEx(t time.Time, exdata map[string]string) string {
+	bsl := make([]byte, 0, this.expectedSize+bufSizeRedunt)
+	buf := bytes.NewBuffer(bsl)
+	ttz := t
+	if this.forceTz {
+		if this.forceLocal {
+			ttz = t.Local()
+		} else if this.forceUTC {
+			ttz = t.UTC()
+		} else {
+			ttz = t.In(this.forceTzVal)
+		}
+	}
+	for _, v := range this.elementList {
+		buf.WriteString(v.PrintElementEx(ttz, exdata))
+	}
+	return buf.String()
+}
+
+func NewTimePrinterEx() *TimePrinterEx {
+	tp := &TimePrinterEx{}
+	tp.elementList = make([]TimeElementEx, 0)
+	tp.expectedSize = 0
+	return tp
+}

+ 87 - 9
yagtf/timefmt/parser.go

@@ -12,18 +12,85 @@ const parserTokenBufferSize = 128
 const regexpTimezoneTag = "^Timezone:([+-][0-9]{4})([A-Z]{3})$"
 
 type TimeElementFactoryFunc func() TimeElement
-type NonDisplayTagFunc func(tp *TimePrinter)
+type TimeElementExFactoryFunc func() TimeElementEx
+type NonDisplayTagFunc func(tp *FormatPrinterParsingAbstract)
+
+type FormatPrinterParsingAbstract struct {
+	isEx bool
+	tp   *TimePrinter
+	tpe  *TimePrinterEx
+}
+
+func (this *FormatPrinterParsingAbstract) IsEx() bool {
+	return this.isEx
+}
+
+func (this *FormatPrinterParsingAbstract) AddPureText(txt string) {
+	if this.isEx {
+		this.tpe.AddPureText(txt)
+	} else {
+		this.tp.AddPureText(txt)
+	}
+}
+
+func (this *FormatPrinterParsingAbstract) AddExDataTag(e TimeElementEx) {
+	this.tpe.AddTimeElementEx(e)
+}
+
+func (this *FormatPrinterParsingAbstract) AddElement(e TimeElement) {
+	if this.isEx {
+		this.tpe.AddTimeElement(e)
+	} else {
+		this.tp.AddElement(e)
+	}
+}
+
+func (this *FormatPrinterParsingAbstract) UseTimezone(tz *time.Location) {
+	if this.isEx {
+		this.tpe.UseTimezone(tz)
+	} else {
+		this.tp.UseTimezone(tz)
+	}
+}
+
+func (this *FormatPrinterParsingAbstract) UseUTC() {
+	if this.isEx {
+		this.tpe.UseUTC()
+	} else {
+		this.tp.UseUTC()
+	}
+}
+
+func (this *FormatPrinterParsingAbstract) UseLocalTimezone() {
+	if this.isEx {
+		this.tpe.UseLocalTimezone()
+	} else {
+		this.tp.UseLocalTimezone()
+	}
+}
+
+func (this *FormatPrinterParsingAbstract) GetTP() *TimePrinter {
+	return this.tp
+}
+
+func (this *FormatPrinterParsingAbstract) GetTPE() *TimePrinterEx {
+	return this.tpe
+}
 
 type FormatParser struct {
 	tagList   map[string]TimeElementFactoryFunc
 	ndTagList map[string]NonDisplayTagFunc
+	exTagList map[string]TimeElementExFactoryFunc
 	tzsReg    *regexp.Regexp
+	isEx      bool
 }
 
-func NewFormatParser() *FormatParser {
+func NewFormatParser(isEx bool) *FormatParser {
 	f := &FormatParser{
 		tagList:   make(map[string]TimeElementFactoryFunc),
 		ndTagList: make(map[string]NonDisplayTagFunc),
+		exTagList: make(map[string]TimeElementExFactoryFunc),
+		isEx:      isEx,
 	}
 	f.addDefaultElementClasses()
 	f.tzsReg, _ = regexp.Compile(regexpTimezoneTag)
@@ -45,7 +112,11 @@ func (this *FormatParser) AddNonDisplayTag(tagname string, nf NonDisplayTagFunc)
 	this.ndTagList[tagname] = nf
 }
 
-func (this *FormatParser) ParseFormatString(tp *TimePrinter, fs string) {
+func (this *FormatParser) AddExDataTag(tagname string, ff TimeElementExFactoryFunc) {
+	this.exTagList[tagname] = ff
+}
+
+func (this *FormatParser) ParseFormatString(tp *FormatPrinterParsingAbstract, fs string) {
 	if len(fs) < 1 {
 		return
 	}
@@ -56,7 +127,7 @@ func (this *FormatParser) ParseFormatString(tp *TimePrinter, fs string) {
 	}
 }
 
-func (this *FormatParser) parseBasicFmt(tp *TimePrinter, fs string) {
+func (this *FormatParser) parseBasicFmt(tp *FormatPrinterParsingAbstract, fs string) {
 	s := fs
 	s = strings.Replace(s, "!", "<#000>", -1)
 	s = strings.Replace(s, "yyyy", "<#001>", -1)
@@ -86,7 +157,7 @@ func (this *FormatParser) parseBasicFmt(tp *TimePrinter, fs string) {
 	this.parseAdvancedFmt(tp, s)
 }
 
-func (this *FormatParser) parseAdvancedFmt(tp *TimePrinter, fs string) {
+func (this *FormatParser) parseAdvancedFmt(tp *FormatPrinterParsingAbstract, fs string) {
 	if len(fs) > 1 {
 		if fs[0] == '!' {
 			this.parseBasicFmt(tp, fs[1:])
@@ -117,7 +188,7 @@ func (this *FormatParser) parseAdvancedFmt(tp *TimePrinter, fs string) {
 	}
 }
 
-func (this *FormatParser) processTimezoneTag(tp *TimePrinter, tzs string, tzname string) {
+func (this *FormatParser) processTimezoneTag(tp *FormatPrinterParsingAbstract, tzs string, tzname string) {
 	sg := 0
 	if tzs[0] == '+' {
 		sg = 1
@@ -144,12 +215,19 @@ func (this *FormatParser) processTimezoneTag(tp *TimePrinter, tzs string, tzname
 	tp.UseTimezone(tz)
 }
 
-func (this *FormatParser) processTag(tp *TimePrinter, tag string) {
+func (this *FormatParser) processTag(tp *FormatPrinterParsingAbstract, tag string) {
 	rrs := this.tzsReg.FindStringSubmatch(tag)
 	if len(rrs) == 3 {
 		this.processTimezoneTag(tp, rrs[1], rrs[2])
 		return
 	}
+	if this.isEx {
+		v0, ok := this.exTagList[tag]
+		if ok {
+			tp.AddExDataTag(v0())
+			return
+		}
+	}
 	v1, ok := this.ndTagList[tag]
 	if ok {
 		v1(tp)
@@ -164,8 +242,8 @@ func (this *FormatParser) processTag(tp *TimePrinter, tag string) {
 }
 
 func (this *FormatParser) addDefaultElementClasses() {
-	this.AddNonDisplayTag("UTC", func(tp *TimePrinter) { tp.UseUTC() })
-	this.AddNonDisplayTag("Local", func(tp *TimePrinter) { tp.UseLocalTimezone() })
+	this.AddNonDisplayTag("UTC", func(tp *FormatPrinterParsingAbstract) { tp.UseUTC() })
+	this.AddNonDisplayTag("Local", func(tp *FormatPrinterParsingAbstract) { tp.UseLocalTimezone() })
 	this.AddElementClass("year", func() TimeElement { return tfelem.NewYearElement(false) })
 	this.AddElementClass("shortYear", func() TimeElement { return tfelem.NewYearElement(true) })
 	this.AddElementClass("month", func() TimeElement { return tfelem.NewNumbericMonthElement(true) })

+ 62 - 0
yagtf/timefmt/timefmt.go

@@ -0,0 +1,62 @@
+package timefmt
+
+import (
+	"strings"
+	"time"
+)
+
+type TimeFormatter struct {
+	Parser    *FormatParser
+	Printer   *TimePrinter
+	Multiline bool
+}
+
+func (this *TimeFormatter) Format(t time.Time) string {
+	fs := this.Printer.PrintTime(t)
+	if this.Multiline {
+		return fs
+	} else {
+		fs = strings.Replace(fs, "\r", "", -1)
+		fs = strings.Replace(fs, "\n", "", -1)
+		return fs
+	}
+}
+
+func (this *TimeFormatter) ForceTimezone(tz *time.Location) {
+	this.Printer.UseTimezone(tz)
+}
+
+func (this *TimeFormatter) ForceLocalTimezone() {
+	this.Printer.UseLocalTimezone()
+}
+
+func (this *TimeFormatter) ForceUTC() {
+	this.Printer.UseUTC()
+}
+
+func (this *TimeFormatter) ParseFormat(fmtstr string) {
+	this.Parser.ParseFormatString(&FormatPrinterParsingAbstract{
+		isEx: false,
+		tp:   this.Printer,
+		tpe:  nil,
+	}, fmtstr)
+}
+
+func NewDefaultTimeFormatter(fmtstr string, multiline bool) *TimeFormatter {
+	tf := &TimeFormatter{
+		Printer:   NewTimePrinter(),
+		Multiline: multiline,
+		Parser:    NewFormatParser(false),
+	}
+	tf.ParseFormat(fmtstr)
+	return tf
+}
+
+func NewTimeFormatter(printer *TimePrinter, parser *FormatParser, multiline bool) *TimeFormatter {
+	tf := &TimeFormatter{
+		Printer:   printer,
+		Multiline: multiline,
+		Parser:    parser,
+	}
+	return tf
+}

+ 62 - 0
yagtf/timefmt/timefmtex.go

@@ -0,0 +1,62 @@
+package timefmt
+
+import (
+	"strings"
+	"time"
+)
+
+type TimeFormatterEx struct {
+	Parser    *FormatParser
+	Printer   *TimePrinterEx
+	Multiline bool
+}
+
+func (this *TimeFormatterEx) Format(t time.Time, exdata map[string]string) string {
+	fs := this.Printer.PrintTimeEx(t, exdata)
+	if this.Multiline {
+		return fs
+	} else {
+		fs = strings.Replace(fs, "\r", "", -1)
+		fs = strings.Replace(fs, "\n", "", -1)
+		return fs
+	}
+}
+
+func (this *TimeFormatterEx) ForceTimezone(tz *time.Location) {
+	this.Printer.UseTimezone(tz)
+}
+
+func (this *TimeFormatterEx) ForceLocalTimezone() {
+	this.Printer.UseLocalTimezone()
+}
+
+func (this *TimeFormatterEx) ForceUTC() {
+	this.Printer.UseUTC()
+}
+
+func (this *TimeFormatterEx) ParseFormat(fmtstr string) {
+	this.Parser.ParseFormatString(&FormatPrinterParsingAbstract{
+		isEx: true,
+		tp:   nil,
+		tpe:  this.Printer,
+	}, fmtstr)
+}
+
+func NewDefaultTimeFormatterEx(fmtstr string, multiline bool) *TimeFormatterEx {
+	tf := &TimeFormatterEx{
+		Printer:   NewTimePrinterEx(),
+		Multiline: multiline,
+		Parser:    NewFormatParser(true),
+	}
+	tf.ParseFormat(fmtstr)
+	return tf
+}
+
+func NewTimeFormatterEx(printer *TimePrinterEx, parser *FormatParser, multiline bool) *TimeFormatterEx {
+	tf := &TimeFormatterEx{
+		Printer:   printer,
+		Multiline: multiline,
+		Parser:    parser,
+	}
+	return tf
+}

+ 0 - 45
yagtf/timefmt/yagtf.go

@@ -1,45 +0,0 @@
-package timefmt
-
-import (
-	"strings"
-	"time"
-)
-
-type TimeFormatter struct {
-	printer   *TimePrinter
-	multiline bool
-}
-
-func (this *TimeFormatter) Format(t time.Time) string {
-	fs := this.printer.PrintTime(t)
-	if this.multiline {
-		return fs
-	} else {
-		fs = strings.Replace(fs, "\r", "", -1)
-		fs = strings.Replace(fs, "\n", "", -1)
-		return fs
-	}
-	return this.printer.PrintTime(t)
-}
-
-func (this *TimeFormatter) ForceTimezone(tz *time.Location) {
-	this.printer.UseTimezone(tz)
-}
-
-func (this *TimeFormatter) ForceLocalTimezone() {
-	this.printer.UseLocalTimezone()
-}
-
-func (this *TimeFormatter) ForceUTC() {
-	this.printer.UseUTC()
-}
-
-func NewTimeFormatter(fmtstr string, multiline bool) *TimeFormatter {
-	tf := &TimeFormatter{
-		printer:   NewTimePrinter(),
-		multiline: multiline,
-	}
-	parser := NewFormatParser()
-	parser.ParseFormatString(tf.printer, fmtstr)
-	return tf
-}