From fd060b6f4b620e2e10c3734eb6a524024fa8fefb Mon Sep 17 00:00:00 2001 From: Daniel Pieper Date: Tue, 29 Nov 2022 18:03:47 +0100 Subject: [PATCH 1/3] Add RichTextList support --- block_rich_text.go | 77 ++++++++++++++++++++++++++++++++++++++++- block_rich_text_test.go | 75 ++++++++++++++++++++++++++++++++++++++- 2 files changed, 150 insertions(+), 2 deletions(-) diff --git a/block_rich_text.go b/block_rich_text.go index 01e5cdb96..ad5835440 100644 --- a/block_rich_text.go +++ b/block_rich_text.go @@ -40,6 +40,9 @@ func (e *RichTextBlock) UnmarshalJSON(b []byte) error { switch s.Type { case RTESection: elem = &RichTextSection{} + case RTEList: + elem = &RichTextList{} + default: elems = append(elems, &RichTextUnknown{ Type: s.Type, @@ -92,12 +95,84 @@ func (u RichTextUnknown) RichTextElementType() RichTextElementType { return u.Type } +type RichTextListElementType string + +const ( + RTEListOrdered RichTextListElementType = "ordered" + RTEListBullet RichTextListElementType = "bullet" +) + +type RichTextList struct { + Type RichTextElementType `json:"type"` + Elements []RichTextElement `json:"elements"` + Style RichTextListElementType `json:"style"` +} + +// NewRichTextList returns a new rich text list element. +func NewRichTextList(style RichTextListElementType, elements ...RichTextElement) *RichTextList { + return &RichTextList{ + Type: RTEList, + Elements: elements, + Style: style, + } +} + +// ElementType returns the type of the Element +func (s RichTextList) RichTextElementType() RichTextElementType { + return s.Type +} + +func (e *RichTextList) UnmarshalJSON(b []byte) error { + var raw struct { + RawElements []json.RawMessage `json:"elements"` + Style RichTextListElementType `json:"style"` + } + if string(b) == "{}" { + return nil + } + if err := json.Unmarshal(b, &raw); err != nil { + return err + } + elems := make([]RichTextElement, 0, len(raw.RawElements)) + for _, r := range raw.RawElements { + var s struct { + Type RichTextElementType `json:"type"` + } + if err := json.Unmarshal(r, &s); err != nil { + return err + } + var elem RichTextElement + switch s.Type { + case RTESection: + elem = &RichTextSection{} + case RTEList: + elem = &RichTextList{} + default: + elems = append(elems, &RichTextUnknown{ + Type: s.Type, + Raw: string(r), + }) + continue + } + if err := json.Unmarshal(r, elem); err != nil { + return err + } + elems = append(elems, elem) + } + *e = RichTextList{ + Type: RTEList, + Elements: elems, + Style: raw.Style, + } + return nil +} + type RichTextSection struct { Type RichTextElementType `json:"type"` Elements []RichTextSectionElement `json:"elements"` } -// ElementType returns the type of the Element +// RichTextElementType returns the type of the Element func (s RichTextSection) RichTextElementType() RichTextElementType { return s.Type } diff --git a/block_rich_text_test.go b/block_rich_text_test.go index 270dde94c..69a917886 100644 --- a/block_rich_text_test.go +++ b/block_rich_text_test.go @@ -36,11 +36,12 @@ func TestRichTextBlock_UnmarshalJSON(t *testing.T) { err error }{ { - []byte(`{"elements":[{"type":"rich_text_unknown"},{"type":"rich_text_section"}]}`), + []byte(`{"elements":[{"type":"rich_text_unknown"},{"type":"rich_text_section"},{"type":"rich_text_list"}]}`), RichTextBlock{ Elements: []RichTextElement{ &RichTextUnknown{Type: RTEUnknown, Raw: `{"type":"rich_text_unknown"}`}, &RichTextSection{Type: RTESection, Elements: []RichTextSectionElement{}}, + &RichTextList{Type: RTEList, Elements: []RichTextElement{}}, }, }, nil, @@ -117,3 +118,75 @@ func TestRichTextSection_UnmarshalJSON(t *testing.T) { } } } + +func TestRichTextList_UnmarshalJSON(t *testing.T) { + cases := []struct { + raw []byte + expected RichTextList + err error + }{ + { + []byte(`{"style":"ordered","elements":[{"type":"rich_text_unknown","value":10},{"type":"rich_text_section","elements":[{"type":"text","text":"hi"}]}]}`), + RichTextList{ + Type: RTEList, + Style: RTEListOrdered, + Elements: []RichTextElement{ + &RichTextUnknown{Type: RTEUnknown, Raw: `{"type":"rich_text_unknown","value":10}`}, + &RichTextSection{ + Type: RTESection, + Elements: []RichTextSectionElement{ + &RichTextSectionTextElement{Type: RTSEText, Text: "hi"}, + }, + }, + }, + }, + nil, + }, + { + []byte(`{"style":"ordered","elements":[{"type":"rich_text_list","style":"bullet","elements":[{"type":"rich_text_section","elements":[{"type":"text","text":"hi"}]}]}]}`), + RichTextList{ + Type: RTEList, + Style: RTEListOrdered, + Elements: []RichTextElement{ + &RichTextList{ + Type: RTEList, + Style: RTEListBullet, + Elements: []RichTextElement{ + &RichTextSection{ + Type: RTESection, + Elements: []RichTextSectionElement{ + &RichTextSectionTextElement{Type: RTSEText, Text: "hi"}, + }, + }, + }, + }, + }, + }, + nil, + }, + { + []byte(`{"type": "rich_text_list","elements":[]}`), + RichTextList{ + Type: RTEList, + Elements: []RichTextElement{}, + }, + nil, + }, + } + for _, tc := range cases { + var actual RichTextList + err := json.Unmarshal(tc.raw, &actual) + if err != nil { + if tc.err == nil { + t.Errorf("unexpected error: %s", err) + } + t.Errorf("expected error is %s, but got %s", tc.err, err) + } + if tc.err != nil { + t.Errorf("expected to raise an error %s", tc.err) + } + if diff := deep.Equal(actual, tc.expected); diff != nil { + t.Errorf("actual value does not match expected one\n%s", diff) + } + } +} From 0f23d87de22ba7c23ff90b995c028b4074db25c4 Mon Sep 17 00:00:00 2001 From: Daniel Pieper <40295712+daniel-pieper-personio@users.noreply.github.com> Date: Wed, 8 Nov 2023 10:32:38 +0100 Subject: [PATCH 2/3] Add support for Indent field Co-authored-by: SimonLiuRoblox <84740141+SimonLiuRoblox@users.noreply.github.com> --- block_rich_text.go | 6 +++++- block_rich_text_test.go | 9 +++++++++ 2 files changed, 14 insertions(+), 1 deletion(-) diff --git a/block_rich_text.go b/block_rich_text.go index ad5835440..aea15974e 100644 --- a/block_rich_text.go +++ b/block_rich_text.go @@ -106,14 +106,16 @@ type RichTextList struct { Type RichTextElementType `json:"type"` Elements []RichTextElement `json:"elements"` Style RichTextListElementType `json:"style"` + Indent int `json:"indent"` } // NewRichTextList returns a new rich text list element. -func NewRichTextList(style RichTextListElementType, elements ...RichTextElement) *RichTextList { +func NewRichTextList(style RichTextListElementType, indent int, elements ...RichTextElement) *RichTextList { return &RichTextList{ Type: RTEList, Elements: elements, Style: style, + Indent: indent, } } @@ -126,6 +128,7 @@ func (e *RichTextList) UnmarshalJSON(b []byte) error { var raw struct { RawElements []json.RawMessage `json:"elements"` Style RichTextListElementType `json:"style"` + Indent int `json:"indent"` } if string(b) == "{}" { return nil @@ -163,6 +166,7 @@ func (e *RichTextList) UnmarshalJSON(b []byte) error { Type: RTEList, Elements: elems, Style: raw.Style, + Indent: raw.Indent, } return nil } diff --git a/block_rich_text_test.go b/block_rich_text_test.go index 69a917886..a6fa06216 100644 --- a/block_rich_text_test.go +++ b/block_rich_text_test.go @@ -172,6 +172,15 @@ func TestRichTextList_UnmarshalJSON(t *testing.T) { }, nil, }, + { + []byte(`{"type": "rich_text_list","elements":[],"indent":2}`), + RichTextList{ + Type: RTEList, + Indent: 2, + Elements: []RichTextElement{}, + }, + nil, + }, } for _, tc := range cases { var actual RichTextList From bc6223be6b96e349b6e0e32699c7589cd9fdca20 Mon Sep 17 00:00:00 2001 From: Daniel Pieper Date: Fri, 2 Feb 2024 08:34:34 +0100 Subject: [PATCH 3/3] Fix linter --- block_rich_text_test.go | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/block_rich_text_test.go b/block_rich_text_test.go index a6fa06216..2788c9735 100644 --- a/block_rich_text_test.go +++ b/block_rich_text_test.go @@ -176,7 +176,7 @@ func TestRichTextList_UnmarshalJSON(t *testing.T) { []byte(`{"type": "rich_text_list","elements":[],"indent":2}`), RichTextList{ Type: RTEList, - Indent: 2, + Indent: 2, Elements: []RichTextElement{}, }, nil,