github.com/servernoj/jade@v0.0.0-20231225191405-efec98d19db1/cmd/jade/jade.go (about)

     1  package main
     2  
     3  import (
     4  	"log"
     5  	"os"
     6  	"text/template"
     7  )
     8  
     9  const (
    10  	jade_go = `// Code generated by "jade.go"; DO NOT EDIT.
    11  
    12  package {{.Pkg}}
    13  
    14  import (
    15  	"bytes"
    16  	"io"
    17  	"strconv"
    18  
    19  	{{- if eq .Buf "*pool.ByteBuffer"}}
    20  	pool "github.com/valyala/bytebufferpool"
    21  	{{- end }}
    22  )
    23  
    24  var (
    25  	escaped   = []byte{'<', '>', '"', '\'', '&'}
    26  	replacing = []string{"&lt;", "&gt;", "&#34;", "&#39;", "&amp;"}
    27  )
    28  
    29  func WriteEscString(st string, buffer {{.Buf}}) {
    30  	for i := 0; i < len(st); i++ {
    31  		if n := bytes.IndexByte(escaped, st[i]); n >= 0 {
    32  			buffer.WriteString(replacing[n])
    33  		} else {
    34  			buffer.WriteByte(st[i])
    35  		}
    36  	}
    37  }
    38  
    39  type WriterAsBuffer struct {
    40  	io.Writer
    41  }
    42  
    43  func (w *WriterAsBuffer) WriteString(s string) (n int, err error) {
    44  	n, err = w.Write([]byte(s))
    45  	return
    46  }
    47  
    48  func (w *WriterAsBuffer) WriteByte(b byte) (err error) {
    49  	_, err = w.Write([]byte{b})
    50  	return
    51  }
    52  
    53  type stringer interface {
    54  	String() string
    55  }
    56  
    57  func WriteAll(a interface{}, escape bool, buffer {{.Buf}}) {
    58  	switch v := a.(type) {
    59  	case string:
    60  		if escape {
    61  			WriteEscString(v, buffer)
    62  		} else {
    63  			buffer.WriteString(v)
    64  		}
    65  	case int:
    66  		WriteInt(int64(v), buffer)
    67  	case int8:
    68  		WriteInt(int64(v), buffer)
    69  	case int16:
    70  		WriteInt(int64(v), buffer)
    71  	case int32:
    72  		WriteInt(int64(v), buffer)
    73  	case int64:
    74  		WriteInt(v, buffer)
    75  	case uint:
    76  		WriteUint(uint64(v), buffer)
    77  	case uint8:
    78  		WriteUint(uint64(v), buffer)
    79  	case uint16:
    80  		WriteUint(uint64(v), buffer)
    81  	case uint32:
    82  		WriteUint(uint64(v), buffer)
    83  	case uint64:
    84  		WriteUint(v, buffer)
    85  	case float32:
    86  		buffer.WriteString(strconv.FormatFloat(float64(v), 'f', -1, 64))
    87  	case float64:
    88  		buffer.WriteString(strconv.FormatFloat(v, 'f', -1, 64))
    89  	case bool:
    90  		WriteBool(v, buffer)
    91  	case stringer:
    92  		if escape {
    93  			WriteEscString(v.String(), buffer)
    94  		} else {
    95  			buffer.WriteString(v.String())
    96  		}
    97  	default:
    98  		buffer.WriteString("\n<<< unprinted type, fmt.Stringer implementation needed >>>\n")
    99  	}
   100  }
   101  
   102  func ternary(condition bool, iftrue, iffalse interface{}) interface{} {
   103  	if condition {
   104  		return iftrue
   105  	} else {
   106  		return iffalse
   107  	}
   108  }
   109  
   110  // Used part of go source:
   111  // https://github.com/golang/go/blob/master/src/strconv/itoa.go
   112  func WriteUint(u uint64, buffer {{.Buf}}) {
   113  	var a [64 + 1]byte
   114  	i := len(a)
   115  
   116  	if ^uintptr(0)>>32 == 0 {
   117  		for u > uint64(^uintptr(0)) {
   118  			q := u / 1e9
   119  			us := uintptr(u - q*1e9)
   120  			for j := 9; j > 0; j-- {
   121  				i--
   122  				qs := us / 10
   123  				a[i] = byte(us - qs*10 + '0')
   124  				us = qs
   125  			}
   126  			u = q
   127  		}
   128  	}
   129  
   130  	us := uintptr(u)
   131  	for us >= 10 {
   132  		i--
   133  		q := us / 10
   134  		a[i] = byte(us - q*10 + '0')
   135  		us = q
   136  	}
   137  
   138  	i--
   139  	a[i] = byte(us + '0')
   140  	buffer.Write(a[i:])
   141  }
   142  func WriteInt(i int64, buffer {{.Buf}}) {
   143  	if i < 0 {
   144  		buffer.WriteByte('-')
   145  		i = -i
   146  	}
   147  	WriteUint(uint64(i), buffer)
   148  }
   149  func WriteBool(b bool, buffer {{.Buf}}) {
   150  	if b {
   151  		buffer.WriteString("true")
   152  		return
   153  	}
   154  	buffer.WriteString("false")
   155  }
   156  `
   157  )
   158  
   159  func makeJfile(std bool) {
   160  	wr, err := os.Create(outdir + "/jade.go")
   161  	defer wr.Close()
   162  	if err != nil {
   163  		log.Fatalln("cmd/jade: makeJfile(): ", err)
   164  	}
   165  
   166  	tp := template.Must(template.New("jlayout").Parse(jade_go))
   167  
   168  	if writer {
   169  		err = tp.Execute(wr, struct {
   170  			Pkg string
   171  			Buf string
   172  		}{pkg_name, "*WriterAsBuffer"})
   173  	} else if std {
   174  		err = tp.Execute(wr, struct {
   175  			Pkg string
   176  			Buf string
   177  		}{pkg_name, "*bytes.Buffer"})
   178  	} else {
   179  		err = tp.Execute(wr, struct {
   180  			Pkg string
   181  			Buf string
   182  		}{pkg_name, "*pool.ByteBuffer"})
   183  	}
   184  	if err != nil {
   185  		log.Fatalln("cmd/jade: makeJfile(): ", err)
   186  	}
   187  }