67 lines
1.4 KiB
Go
67 lines
1.4 KiB
Go
package compress
|
|
|
|
import (
|
|
"bytes"
|
|
"compress/flate"
|
|
"encoding/base64"
|
|
"io"
|
|
"strings"
|
|
|
|
"oss.terrastruct.com/d2/d2graph"
|
|
)
|
|
|
|
var compressionDict = "->" +
|
|
"<-" +
|
|
"--" +
|
|
"<->"
|
|
|
|
var compressionDictBytes []byte
|
|
|
|
// Compress takes a D2 script and compresses it to a URL-encoded string
|
|
func Compress(raw string) (string, error) {
|
|
var b bytes.Buffer
|
|
|
|
zw, err := flate.NewWriterDict(&b, flate.DefaultCompression, []byte(compressionDict))
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
if _, err := io.Copy(zw, strings.NewReader(raw)); err != nil {
|
|
return "", err
|
|
}
|
|
if err := zw.Close(); err != nil {
|
|
return "", err
|
|
}
|
|
|
|
encoded := base64.URLEncoding.EncodeToString(b.Bytes())
|
|
return encoded, nil
|
|
}
|
|
|
|
// Decompress takes a compressed, URL-encoded string and returns the decompressed D2 script
|
|
func Decompress(encoded string) (string, error) {
|
|
b64Decoded, err := base64.URLEncoding.DecodeString(encoded)
|
|
if err != nil {
|
|
return "", err
|
|
}
|
|
|
|
zr := flate.NewReaderDict(bytes.NewReader(b64Decoded), []byte(compressionDict))
|
|
var b bytes.Buffer
|
|
if _, err := io.Copy(&b, zr); err != nil {
|
|
return "", err
|
|
}
|
|
if err := zr.Close(); err != nil {
|
|
return "", nil
|
|
}
|
|
return b.String(), nil
|
|
}
|
|
|
|
func init() {
|
|
for k := range d2graph.StyleKeywords {
|
|
compressionDict += k
|
|
}
|
|
for k := range d2graph.ReservedKeywords {
|
|
compressionDict += k
|
|
}
|
|
for k := range d2graph.ReservedKeywordHolders {
|
|
compressionDict += k
|
|
}
|
|
}
|