diff --git a/go.mod b/go.mod index 9ec776efd..cb6f09819 100644 --- a/go.mod +++ b/go.mod @@ -25,6 +25,7 @@ require ( nhooyr.io/websocket v1.8.7 oss.terrastruct.com/cmdlog v0.0.0-20221201100934-012c01b3431c oss.terrastruct.com/diff v1.0.2-0.20221116222035-8bf4dd3ab541 + oss.terrastruct.com/util-go v0.0.0-20221201174206-77c68780d6f0 oss.terrastruct.com/xcontext v0.0.0-20221018000442-50fdafb12f4f oss.terrastruct.com/xdefer v0.0.0-20221017222355-6f3b6e4d1557 oss.terrastruct.com/xjson v0.0.0-20221018000420-4986731c4c4a diff --git a/go.sum b/go.sum index 05aad4030..86dbaf55c 100644 --- a/go.sum +++ b/go.sum @@ -802,6 +802,8 @@ oss.terrastruct.com/cmdlog v0.0.0-20221201100934-012c01b3431c h1:C1DDLzj2NrVi1YJ oss.terrastruct.com/cmdlog v0.0.0-20221201100934-012c01b3431c/go.mod h1:C8u/lYTvQWc1xC7rHpgFfpScfQC4NMeGGMmlKVZZUXM= oss.terrastruct.com/diff v1.0.2-0.20221116222035-8bf4dd3ab541 h1:I9B1O1IJ6spivIQxbFRZmbhAwVeLwrcQRR1JbYUOvrI= oss.terrastruct.com/diff v1.0.2-0.20221116222035-8bf4dd3ab541/go.mod h1:ags2QDy/T6jr69hT6bpmAmhr2H98n9o8Atf3QlUJPiU= +oss.terrastruct.com/util-go v0.0.0-20221201174206-77c68780d6f0 h1:zaSiaG+BkHysYOs7M/flh1FEOlJzqA+wwQvCplMBhxA= +oss.terrastruct.com/util-go v0.0.0-20221201174206-77c68780d6f0/go.mod h1:AN5T0bJ89/Q6ZebXIdPGpwAqVhK9PkDpgygWJaT2JzQ= oss.terrastruct.com/xcontext v0.0.0-20221018000442-50fdafb12f4f h1:7voRCwKM7TZkTo9u7hj+uV/zXoVB8czWrTq6MVIh3dg= oss.terrastruct.com/xcontext v0.0.0-20221018000442-50fdafb12f4f/go.mod h1:Y0coTLsWwX0q3a+/Ndq797t+vWyxm42T49Ik3bzaDKY= oss.terrastruct.com/xdefer v0.0.0-20221017222355-6f3b6e4d1557 h1:rPbhJbN1q7B4tnppSPoAMwq0t6Pk5SrQDQ5S6uoNNHg= diff --git a/lib/compress/compress_test.go b/lib/compress/compress_test.go deleted file mode 100644 index b1fe82e12..000000000 --- a/lib/compress/compress_test.go +++ /dev/null @@ -1,27 +0,0 @@ -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) -} diff --git a/lib/compress/compress.go b/lib/urlenc/urlenc.go similarity index 65% rename from lib/compress/compress.go rename to lib/urlenc/urlenc.go index 513afef67..64e08db11 100644 --- a/lib/compress/compress.go +++ b/lib/urlenc/urlenc.go @@ -1,4 +1,4 @@ -package compress +package urlenc import ( "bytes" @@ -7,6 +7,8 @@ import ( "io" "strings" + "oss.terrastruct.com/util-go/xdefer" + "oss.terrastruct.com/d2/d2graph" ) @@ -15,13 +17,25 @@ var compressionDict = "->" + "--" + "<->" -var compressionDictBytes []byte +func init() { + for k := range d2graph.StyleKeywords { + compressionDict += k + } + for k := range d2graph.ReservedKeywords { + compressionDict += k + } + for k := range d2graph.ReservedKeywordHolders { + compressionDict += k + } +} -// Compress takes a D2 script and compresses it to a URL-encoded string -func Compress(raw string) (string, error) { - var b bytes.Buffer +// Encode takes a D2 script and encodes it as a compressed base64 string for embedding in URLs. +func Encode(raw string) (_ string, err error) { + defer xdefer.Errorf(&err, "failed to encode d2 script") - zw, err := flate.NewWriterDict(&b, flate.DefaultCompression, []byte(compressionDict)) + b := &bytes.Buffer{} + + zw, err := flate.NewWriterDict(b, flate.DefaultCompression, []byte(compressionDict)) if err != nil { return "", err } @@ -36,8 +50,10 @@ func Compress(raw string) (string, error) { return encoded, nil } -// Decompress takes a compressed, URL-encoded string and returns the decompressed D2 script -func Decompress(encoded string) (string, error) { +// Decode decodes a compressed base64 D2 string. +func Decode(encoded string) (_ string, err error) { + defer xdefer.Errorf(&err, "failed to decode d2 script") + b64Decoded, err := base64.URLEncoding.DecodeString(encoded) if err != nil { return "", err @@ -53,15 +69,3 @@ func Decompress(encoded string) (string, error) { } 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 - } -} diff --git a/lib/urlenc/urlenc_test.go b/lib/urlenc/urlenc_test.go new file mode 100644 index 000000000..c5b9a4866 --- /dev/null +++ b/lib/urlenc/urlenc_test.go @@ -0,0 +1,23 @@ +package urlenc + +import ( + "testing" + + "oss.terrastruct.com/util-go/assert" +) + +func TestBasic(t *testing.T) { + const script = `x -> y +I just forgot my whole philosophy of life!!!: { + s: TV is chewing gum for the eyes +} +` + + encoded, err := Encode(script) + assert.Success(t, err) + + decoded, err := Decode(encoded) + assert.Success(t, err) + + assert.String(t, script, decoded) +}