commit
b13629fe8f
2 changed files with 94 additions and 0 deletions
67
lib/compress/compress.go
Normal file
67
lib/compress/compress.go
Normal file
|
|
@ -0,0 +1,67 @@
|
|||
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
|
||||
}
|
||||
}
|
||||
27
lib/compress/compress_test.go
Normal file
27
lib/compress/compress_test.go
Normal file
|
|
@ -0,0 +1,27 @@
|
|||
package compress
|
||||
|
||||
import (
|
||||
"testing"
|
||||
|
||||
"oss.terrastruct.com/diff"
|
||||
)
|
||||
|
||||
func TestCompression(t *testing.T) {
|
||||
script := `x -> y
|
||||
I just forgot my whole philosophy of life!!!: {
|
||||
s: TV is chewing gum for the eyes
|
||||
}
|
||||
`
|
||||
|
||||
encoded, err := Compress(script)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
decoded, err := Decompress(encoded)
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
|
||||
diff.AssertStringEq(t, script, decoded)
|
||||
}
|
||||
Loading…
Reference in a new issue