text.go
1package ygo
2
3/*
4#include "libyrs.h"
5#include <stdlib.h>
6*/
7import "C"
8import (
9 "encoding/json"
10 "fmt"
11 "unsafe"
12)
13
14// Text represents a collaborative text type.
15type Text struct {
16 branch *C.Branch
17}
18
19// GetText retrieves or creates a root-level YText with the given name.
20func (d *Doc) GetText(name string) (*Text, error) {
21 if d.ptr == nil {
22 return nil, ErrNilDocument
23 }
24 cName := C.CString(name)
25 defer C.free(unsafe.Pointer(cName))
26
27 branch := C.ytext(d.ptr, cName)
28 if branch == nil {
29 return nil, fmt.Errorf("failed to get or create text field %q", name)
30 }
31
32 t := &Text{branch: branch}
33 return t, nil
34}
35
36// Destroy releases resources (does not delete the text from document).
37func (t *Text) Destroy() {
38 // Text is managed by document, no explicit destroy needed
39}
40
41// Len returns the length of the text in UTF code units (based on doc encoding).
42// Panics if the Text is nil or if txn is nil.
43func (t *Text) Len(txn *Transaction) uint32 {
44 if t.branch == nil {
45 panic("ygo: Text.Len called on nil Text")
46 }
47 if txn == nil || txn.ptr == nil {
48 panic("ygo: Text.Len called with nil transaction")
49 }
50 return uint32(C.ytext_len(t.branch, txn.ptr))
51}
52
53// String returns the text content as a Go string.
54func (t *Text) String(txn *Transaction) (string, error) {
55 if t.branch == nil {
56 return "", ErrNilBranch
57 }
58 if txn == nil || txn.ptr == nil {
59 return "", ErrNilTransaction
60 }
61 return cStringToGoAndFree(C.ytext_string(t.branch, txn.ptr)), nil
62}
63
64// Insert inserts text at the given index.
65func (t *Text) Insert(txn *Transaction, index uint32, text string) error {
66 if t.branch == nil {
67 return ErrNilBranch
68 }
69 if txn == nil || txn.ptr == nil {
70 return ErrNilTransaction
71 }
72 if !txn.IsWriteable() {
73 return ErrNotWriteable
74 }
75 cText := C.CString(text)
76 defer C.free(unsafe.Pointer(cText))
77 C.ytext_insert(t.branch, txn.ptr, C.uint32_t(index), cText, nil)
78 return nil
79}
80
81// InsertWithAttributes inserts text with formatting attributes.
82func (t *Text) InsertWithAttributes(txn *Transaction, index uint32, text string, attrs Input) error {
83 if t.branch == nil {
84 return ErrNilBranch
85 }
86 if txn == nil || txn.ptr == nil {
87 return ErrNilTransaction
88 }
89 if !txn.IsWriteable() {
90 return ErrNotWriteable
91 }
92 cText := C.CString(text)
93 defer C.free(unsafe.Pointer(cText))
94 C.ytext_insert(t.branch, txn.ptr, C.uint32_t(index), cText, &attrs.cInput)
95 return nil
96}
97
98// RemoveRange removes a range of text starting at index.
99func (t *Text) RemoveRange(txn *Transaction, index, length uint32) error {
100 if t.branch == nil {
101 return ErrNilBranch
102 }
103 if txn == nil || txn.ptr == nil {
104 return ErrNilTransaction
105 }
106 if !txn.IsWriteable() {
107 return ErrNotWriteable
108 }
109 C.ytext_remove_range(t.branch, txn.ptr, C.uint32_t(index), C.uint32_t(length))
110 return nil
111}
112
113// Format applies formatting attributes to a text range.
114func (t *Text) Format(txn *Transaction, index, length uint32, attrs Input) error {
115 if t.branch == nil {
116 return ErrNilBranch
117 }
118 if txn == nil || txn.ptr == nil {
119 return ErrNilTransaction
120 }
121 if !txn.IsWriteable() {
122 return ErrNotWriteable
123 }
124 C.ytext_format(t.branch, txn.ptr, C.uint32_t(index), C.uint32_t(length), &attrs.cInput)
125 return nil
126}
127
128// Push appends text to the end.
129func (t *Text) Push(txn *Transaction, text string) error {
130 return t.Insert(txn, t.Len(txn), text)
131}
132
133// Branch returns the underlying branch pointer (for advanced use).
134func (t *Text) Branch() unsafe.Pointer {
135 return unsafe.Pointer(t.branch)
136}
137
138// MarshalJSONWithTxn implements JSON marshaling for Text.
139// Returns the text content as a JSON string.
140func (t *Text) MarshalJSONWithTxn(txn *Transaction) ([]byte, error) {
141 if t.branch == nil {
142 return nil, ErrNilBranch
143 }
144 if txn == nil || txn.ptr == nil {
145 return nil, ErrNilTransaction
146 }
147
148 content, err := t.String(txn)
149 if err != nil {
150 return nil, err
151 }
152
153 return json.Marshal(content)
154}