1
0
Fork 0

🏷️ Created HTML domain

This commit is contained in:
Maxim Lebedev 2023-11-26 01:03:14 +06:00
parent 2428c890e7
commit 8d3ef5c7fc
Signed by: toby3d
GPG Key ID: 1F14E25B7C119FC5
4 changed files with 129 additions and 0 deletions

2
go.mod
View File

@ -1,3 +1,5 @@
module source.toby3d.me/toby3d/jf2
go 1.21.4
require golang.org/x/net v0.18.0 // indirect

2
go.sum Normal file
View File

@ -0,0 +1,2 @@
golang.org/x/net v0.18.0 h1:mIYleuAkSbHh0tCv7RvjL3F6ZVbLjq4+R7zbOn3Kokg=
golang.org/x/net v0.18.0/go.mod h1:/czyP5RqHAH4odGYxBJ1qz0+CE5WZ+2j1YgoEo8F2jQ=

71
html.go Normal file
View File

@ -0,0 +1,71 @@
package jf2
import (
"bytes"
"fmt"
"html"
"io"
"strconv"
"strings"
nethtml "golang.org/x/net/html"
)
// HTML is the text/html version of the containing object.
type HTML struct {
node *nethtml.Node
value string
}
func NewHTML(r io.Reader) (*HTML, error) {
value, err := io.ReadAll(r)
if err != nil {
return nil, fmt.Errorf("cannot read r HTML value as string: %w", err)
}
node, err := nethtml.Parse(bytes.NewReader(value))
if err != nil {
return nil, fmt.Errorf("cannot parse r as HTML: %w", err)
}
return &HTML{
node: node,
value: string(value),
}, nil
}
func (h *HTML) UnmarshalJSON(v []byte) error {
unquoted, err := strconv.Unquote(string(v))
if err != nil {
return fmt.Errorf("JF2: HTML: cannot unquote value: %w", err)
}
parsed, err := NewHTML(strings.NewReader(html.UnescapeString(unquoted)))
if err != nil {
return fmt.Errorf("JF2: HTML: cannot parse value as HTML node: %w", err)
}
*h = *parsed
return nil
}
func (h HTML) MarshalJSON() ([]byte, error) {
if h.value != "" {
return []byte(strconv.Quote(h.value)), nil
}
return nil, nil
}
func (h HTML) GoString() string {
return "jf2.HTML(" + h.String() + ")"
}
func (h HTML) String() string {
if h.value != "" {
return h.value
}
return "und"
}

54
html_test.go Normal file
View File

@ -0,0 +1,54 @@
package jf2_test
import (
"encoding/json"
"strings"
"testing"
"source.toby3d.me/toby3d/jf2"
)
func TestHTML_UnmarshalJSON(t *testing.T) {
t.Parallel()
v := new(struct {
Content struct {
HTML jf2.HTML `json:"html"`
} `json:"content"`
})
if err := json.Unmarshal([]byte(`{"content":{"html":"<p>Hello World</p>"}}`), v); err != nil {
t.Fatal(err)
}
expect, err := jf2.NewHTML(strings.NewReader(`<p>Hello World</p>`))
if err != nil {
t.Fatal(err)
}
if v.Content.HTML.String() != expect.String() {
t.Errorf("got '%s', want '%s'", v.Content.HTML, *expect)
}
}
func TestHTML_MarshalJSON(t *testing.T) {
t.Parallel()
v, err := jf2.NewHTML(strings.NewReader(`<p>Hello World</p>`))
if err != nil {
t.Fatal(err)
}
body, err := json.Marshal(struct {
Content *jf2.HTML `json:"content"`
}{
Content: v,
})
if err != nil {
t.Fatal(err)
}
const expect string = `{"content":"\u003cp\u003eHello World\u003c/p\u003e"}`
if actual := string(body); actual != expect {
t.Errorf("got '%s', want '%s'", actual, expect)
}
}