mirror of
				https://github.com/Dadido3/go-typst.git
				synced 2025-11-03 20:59:35 +00:00 
			
		
		
		
	Rename Variable* to Value*
- Rename MarshalVariable to MarshalValue - Rename NewVariableEncoder to NewValueEncoder - Rename VariableEncoder to ValueEncoder - Rename VariableMarshaler to ValueMarshaler - Rename MarshalTypstVariable to MarshalTypstValue There are now wrappers which ensure compatibility with code that still uses some of the old functions/types. - Improve image_test.go by adding an assertion - Rename all occurrences of Variable to Value - Remove "TODO: Handle images..." as that's already working with the image wrapper - Update README.md
This commit is contained in:
		
							parent
							
								
									7c87e3fee8
								
							
						
					
					
						commit
						c3876b340b
					
				@ -20,7 +20,7 @@ Use at your own discretion for production systems.
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
- PDF, SVG and PNG generation.
 | 
					- PDF, SVG and PNG generation.
 | 
				
			||||||
- All Typst parameters are discoverable and documented in [cli-options.go](cli-options.go).
 | 
					- All Typst parameters are discoverable and documented in [cli-options.go](cli-options.go).
 | 
				
			||||||
- Go-to-Typst Object Encoder: Seamlessly inject any Go values (Including `image.Image` with a [wrapper](image.go)) into Typst documents via the provided encoder.
 | 
					- Go-to-Typst Value Encoder: Seamlessly inject any Go values (Including `image.Image` with a [wrapper](image.go)) into Typst documents via the provided encoder.
 | 
				
			||||||
- Errors from Typst CLI are returned as structured Go error objects with detailed information, such as line numbers and file paths.
 | 
					- Errors from Typst CLI are returned as structured Go error objects with detailed information, such as line numbers and file paths.
 | 
				
			||||||
- Uses stdio; No temporary files will be created.
 | 
					- Uses stdio; No temporary files will be created.
 | 
				
			||||||
- Good unit test coverage.
 | 
					- Good unit test coverage.
 | 
				
			||||||
 | 
				
			|||||||
@ -12,7 +12,7 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
func main() {
 | 
					func main() {
 | 
				
			||||||
	// Convert a time.Time value into Typst markup.
 | 
						// Convert a time.Time value into Typst markup.
 | 
				
			||||||
	date, err := typst.MarshalVariable(time.Now())
 | 
						date, err := typst.MarshalValue(time.Now())
 | 
				
			||||||
	if err != nil {
 | 
						if err != nil {
 | 
				
			||||||
		log.Panicf("Failed to marshal date into Typst markup: %v", err)
 | 
							log.Panicf("Failed to marshal date into Typst markup: %v", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										4
									
								
								image.go
									
									
									
									
									
								
							
							
						
						
									
										4
									
								
								image.go
									
									
									
									
									
								
							@ -15,10 +15,10 @@ import (
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
// Image can be used to encode any image.Image into a typst image.
 | 
					// Image can be used to encode any image.Image into a typst image.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// For this, just wrap any image.Image with this type before passing it to MarshalVariable or a VariableEncoder.
 | 
					// For this, just wrap any image.Image with this type before passing it to MarshalValue or a ValueEncoder.
 | 
				
			||||||
type Image struct{ image.Image }
 | 
					type Image struct{ image.Image }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (i Image) MarshalTypstVariable() ([]byte, error) {
 | 
					func (i Image) MarshalTypstValue() ([]byte, error) {
 | 
				
			||||||
	var buffer bytes.Buffer
 | 
						var buffer bytes.Buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := png.Encode(&buffer, i); err != nil {
 | 
						if err := png.Encode(&buffer, i); err != nil {
 | 
				
			||||||
 | 
				
			|||||||
@ -48,7 +48,9 @@ func TestImage(t *testing.T) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
	r.WriteString(`= Image test
 | 
						r.WriteString(`= Image test
 | 
				
			||||||
 | 
					
 | 
				
			||||||
#TestImage`) // TODO: Add assertion for the image width and height as soon as it's possible to query that
 | 
					#TestImage
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#assert(type(TestImage) == content, message: "TestImage is not of expected type: got " + str(type(TestImage)) + ", want content")`) // TODO: Add another assertion for the image width and height as soon as it's possible to query that
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	if err := cli.Compile(&r, io.Discard, nil); err != nil {
 | 
						if err := cli.Compile(&r, io.Discard, nil); err != nil {
 | 
				
			||||||
		t.Fatalf("Failed to compile document: %v.", err)
 | 
							t.Fatalf("Failed to compile document: %v.", err)
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										6
									
								
								util.go
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								util.go
									
									
									
									
									
								
							@ -16,14 +16,14 @@ import (
 | 
				
			|||||||
// This can be used to inject Go values into typst documents.
 | 
					// This can be used to inject Go values into typst documents.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Every key in values needs to be a valid identifier, otherwise this function will return an error.
 | 
					// Every key in values needs to be a valid identifier, otherwise this function will return an error.
 | 
				
			||||||
// Every value in values will be marshaled according to VariableEncoder into equivalent Typst markup.
 | 
					// Every value in values will be marshaled according to ValueEncoder into equivalent Typst markup.
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// Passing {"foo": 1, "bar": 60 * time.Second} as values will produce the following output:
 | 
					// Passing {"foo": 1, "bar": 60 * time.Second} as values will produce the following output:
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
//	#let foo = 1
 | 
					//	#let foo = 1
 | 
				
			||||||
//	#let bar = duration(seconds: 60)
 | 
					//	#let bar = duration(seconds: 60)
 | 
				
			||||||
func InjectValues(output io.Writer, values map[string]any) error {
 | 
					func InjectValues(output io.Writer, values map[string]any) error {
 | 
				
			||||||
	enc := NewVariableEncoder(output)
 | 
						enc := NewValueEncoder(output)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// We will have to iterate over the sorted list of map keys.
 | 
						// We will have to iterate over the sorted list of map keys.
 | 
				
			||||||
	// Otherwise the output is not deterministic, and tests will fail randomly.
 | 
						// Otherwise the output is not deterministic, and tests will fail randomly.
 | 
				
			||||||
@ -36,7 +36,7 @@ func InjectValues(output io.Writer, values map[string]any) error {
 | 
				
			|||||||
			return err
 | 
								return err
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if err := enc.Encode(v); err != nil {
 | 
							if err := enc.Encode(v); err != nil {
 | 
				
			||||||
			return fmt.Errorf("failed to encode variables with key %q: %w", k, err)
 | 
								return fmt.Errorf("failed to encode values with key %q: %w", k, err)
 | 
				
			||||||
		}
 | 
							}
 | 
				
			||||||
		if _, err := output.Write([]byte("\n")); err != nil {
 | 
							if _, err := output.Write([]byte("\n")); err != nil {
 | 
				
			||||||
			return err
 | 
								return err
 | 
				
			||||||
 | 
				
			|||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
// Copyright (c) 2024 David Vogel
 | 
					// Copyright (c) 2024-2025 David Vogel
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// This software is released under the MIT License.
 | 
					// This software is released under the MIT License.
 | 
				
			||||||
// https://opensource.org/licenses/MIT
 | 
					// https://opensource.org/licenses/MIT
 | 
				
			||||||
@ -18,11 +18,11 @@ import (
 | 
				
			|||||||
	"time"
 | 
						"time"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// MarshalVariable takes any go type and returns a typst markup representation as a byte slice.
 | 
					// MarshalValue takes any go type and returns a typst markup representation as a byte slice.
 | 
				
			||||||
func MarshalVariable(v any) ([]byte, error) {
 | 
					func MarshalValue(v any) ([]byte, error) {
 | 
				
			||||||
	var buf bytes.Buffer
 | 
						var buf bytes.Buffer
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	enc := NewVariableEncoder(&buf)
 | 
						enc := NewValueEncoder(&buf)
 | 
				
			||||||
	if err := enc.Encode(v); err != nil {
 | 
						if err := enc.Encode(v); err != nil {
 | 
				
			||||||
		return nil, err
 | 
							return nil, err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -30,37 +30,37 @@ func MarshalVariable(v any) ([]byte, error) {
 | 
				
			|||||||
	return buf.Bytes(), nil
 | 
						return buf.Bytes(), nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// VariableMarshaler can be implemented by types to support custom typst marshaling.
 | 
					// ValueMarshaler can be implemented by types to support custom Typst marshaling.
 | 
				
			||||||
type VariableMarshaler interface {
 | 
					type ValueMarshaler interface {
 | 
				
			||||||
	MarshalTypstVariable() ([]byte, error)
 | 
						MarshalTypstValue() ([]byte, error)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type VariableEncoder struct {
 | 
					type ValueEncoder struct {
 | 
				
			||||||
	indentLevel int
 | 
						indentLevel int
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	writer io.Writer
 | 
						writer io.Writer
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
// NewVariableEncoder returns a new encoder that writes into w.
 | 
					// NewValueEncoder returns a new encoder that writes into w.
 | 
				
			||||||
func NewVariableEncoder(w io.Writer) *VariableEncoder {
 | 
					func NewValueEncoder(w io.Writer) *ValueEncoder {
 | 
				
			||||||
	return &VariableEncoder{
 | 
						return &ValueEncoder{
 | 
				
			||||||
		writer: w,
 | 
							writer: w,
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) Encode(v any) error {
 | 
					func (e *ValueEncoder) Encode(v any) error {
 | 
				
			||||||
	return e.marshal(reflect.ValueOf(v))
 | 
						return e.marshal(reflect.ValueOf(v))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) writeString(s string) error {
 | 
					func (e *ValueEncoder) writeString(s string) error {
 | 
				
			||||||
	return e.writeBytes([]byte(s))
 | 
						return e.writeBytes([]byte(s))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) writeRune(r rune) error {
 | 
					func (e *ValueEncoder) writeRune(r rune) error {
 | 
				
			||||||
	return e.writeBytes([]byte{byte(r)})
 | 
						return e.writeBytes([]byte{byte(r)})
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) writeStringLiteral(s []byte) error {
 | 
					func (e *ValueEncoder) writeStringLiteral(s []byte) error {
 | 
				
			||||||
	dst := make([]byte, 0, len(s)+5)
 | 
						dst := make([]byte, 0, len(s)+5)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	dst = append(dst, '"')
 | 
						dst = append(dst, '"')
 | 
				
			||||||
@ -85,7 +85,7 @@ func (e *VariableEncoder) writeStringLiteral(s []byte) error {
 | 
				
			|||||||
	return e.writeBytes(dst)
 | 
						return e.writeBytes(dst)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) writeBytes(b []byte) error {
 | 
					func (e *ValueEncoder) writeBytes(b []byte) error {
 | 
				
			||||||
	if _, err := e.writer.Write(b); err != nil {
 | 
						if _, err := e.writer.Write(b); err != nil {
 | 
				
			||||||
		return fmt.Errorf("failed to write into writer: %w", err)
 | 
							return fmt.Errorf("failed to write into writer: %w", err)
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -93,11 +93,11 @@ func (e *VariableEncoder) writeBytes(b []byte) error {
 | 
				
			|||||||
	return nil
 | 
						return nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) writeIndentationCharacters() error {
 | 
					func (e *ValueEncoder) writeIndentationCharacters() error {
 | 
				
			||||||
	return e.writeBytes(slices.Repeat([]byte{' ', ' '}, e.indentLevel))
 | 
						return e.writeBytes(slices.Repeat([]byte{' ', ' '}, e.indentLevel))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) marshal(v reflect.Value) error {
 | 
					func (e *ValueEncoder) marshal(v reflect.Value) error {
 | 
				
			||||||
	if !v.IsValid() {
 | 
						if !v.IsValid() {
 | 
				
			||||||
		return e.writeString("none")
 | 
							return e.writeString("none")
 | 
				
			||||||
		//return fmt.Errorf("invalid reflect.Value %v", v)
 | 
							//return fmt.Errorf("invalid reflect.Value %v", v)
 | 
				
			||||||
@ -134,8 +134,18 @@ func (e *VariableEncoder) marshal(v reflect.Value) error {
 | 
				
			|||||||
		return nil
 | 
							return nil
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// TODO: Handle images, maybe create a wrapper type that does this
 | 
						if t.Implements(reflect.TypeFor[ValueMarshaler]()) {
 | 
				
			||||||
 | 
							if m, ok := v.Interface().(ValueMarshaler); ok {
 | 
				
			||||||
 | 
								bytes, err := m.MarshalTypstValue()
 | 
				
			||||||
 | 
								if err != nil {
 | 
				
			||||||
 | 
									return fmt.Errorf("error calling MarshalTypstValue for type %s: %w", t.String(), err)
 | 
				
			||||||
 | 
								}
 | 
				
			||||||
 | 
								return e.writeBytes(bytes)
 | 
				
			||||||
 | 
							}
 | 
				
			||||||
 | 
							return e.writeString("none")
 | 
				
			||||||
 | 
						}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
						// TODO: Remove this in a future update, it's only here for compatibility reasons
 | 
				
			||||||
	if t.Implements(reflect.TypeFor[VariableMarshaler]()) {
 | 
						if t.Implements(reflect.TypeFor[VariableMarshaler]()) {
 | 
				
			||||||
		if m, ok := v.Interface().(VariableMarshaler); ok {
 | 
							if m, ok := v.Interface().(VariableMarshaler); ok {
 | 
				
			||||||
			bytes, err := m.MarshalTypstVariable()
 | 
								bytes, err := m.MarshalTypstVariable()
 | 
				
			||||||
@ -222,11 +232,11 @@ func (e *VariableEncoder) marshal(v reflect.Value) error {
 | 
				
			|||||||
	return err
 | 
						return err
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) encodeString(v reflect.Value) error {
 | 
					func (e *ValueEncoder) encodeString(v reflect.Value) error {
 | 
				
			||||||
	return e.writeStringLiteral([]byte(v.String()))
 | 
						return e.writeStringLiteral([]byte(v.String()))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) encodeStruct(v reflect.Value, t reflect.Type) error {
 | 
					func (e *ValueEncoder) encodeStruct(v reflect.Value, t reflect.Type) error {
 | 
				
			||||||
	if v.NumField() == 0 {
 | 
						if v.NumField() == 0 {
 | 
				
			||||||
		return e.writeString("()")
 | 
							return e.writeString("()")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -276,7 +286,7 @@ func (e *VariableEncoder) encodeStruct(v reflect.Value, t reflect.Type) error {
 | 
				
			|||||||
	return e.writeRune(')')
 | 
						return e.writeRune(')')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) resolveKeyName(v reflect.Value) (string, error) {
 | 
					func (e *ValueEncoder) resolveKeyName(v reflect.Value) (string, error) {
 | 
				
			||||||
	// From encoding/json/encode.go.
 | 
						// From encoding/json/encode.go.
 | 
				
			||||||
	if v.Kind() == reflect.String {
 | 
						if v.Kind() == reflect.String {
 | 
				
			||||||
		return v.String(), nil
 | 
							return v.String(), nil
 | 
				
			||||||
@ -297,7 +307,7 @@ func (e *VariableEncoder) resolveKeyName(v reflect.Value) (string, error) {
 | 
				
			|||||||
	return "", fmt.Errorf("unsupported map key type %q", v.Type().String())
 | 
						return "", fmt.Errorf("unsupported map key type %q", v.Type().String())
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) encodeMap(v reflect.Value) error {
 | 
					func (e *ValueEncoder) encodeMap(v reflect.Value) error {
 | 
				
			||||||
	if v.Len() == 0 {
 | 
						if v.Len() == 0 {
 | 
				
			||||||
		return e.writeString("()")
 | 
							return e.writeString("()")
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -357,7 +367,7 @@ func (e *VariableEncoder) encodeMap(v reflect.Value) error {
 | 
				
			|||||||
	return e.writeRune(')')
 | 
						return e.writeRune(')')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) EncodeByteSlice(bb []byte) error {
 | 
					func (e *ValueEncoder) EncodeByteSlice(bb []byte) error {
 | 
				
			||||||
	if err := e.writeString("bytes(("); err != nil {
 | 
						if err := e.writeString("bytes(("); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -385,7 +395,7 @@ func (e *VariableEncoder) EncodeByteSlice(bb []byte) error {
 | 
				
			|||||||
	return e.writeString("))")
 | 
						return e.writeString("))")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) encodeSlice(v reflect.Value, t reflect.Type) error {
 | 
					func (e *ValueEncoder) encodeSlice(v reflect.Value, t reflect.Type) error {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	// Special case for byte slices.
 | 
						// Special case for byte slices.
 | 
				
			||||||
	if t.Elem().Kind() == reflect.Uint8 {
 | 
						if t.Elem().Kind() == reflect.Uint8 {
 | 
				
			||||||
@ -417,7 +427,7 @@ func (e *VariableEncoder) encodeSlice(v reflect.Value, t reflect.Type) error {
 | 
				
			|||||||
	return e.writeRune(')')
 | 
						return e.writeRune(')')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) encodeArray(v reflect.Value) error {
 | 
					func (e *ValueEncoder) encodeArray(v reflect.Value) error {
 | 
				
			||||||
	if err := e.writeRune('('); err != nil {
 | 
						if err := e.writeRune('('); err != nil {
 | 
				
			||||||
		return err
 | 
							return err
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
@ -443,7 +453,7 @@ func (e *VariableEncoder) encodeArray(v reflect.Value) error {
 | 
				
			|||||||
	return e.writeRune(')')
 | 
						return e.writeRune(')')
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) encodeTime(t time.Time) error {
 | 
					func (e *ValueEncoder) encodeTime(t time.Time) error {
 | 
				
			||||||
	return e.writeString(fmt.Sprintf("datetime(year: %d, month: %d, day: %d, hour: %d, minute: %d, second: %d)",
 | 
						return e.writeString(fmt.Sprintf("datetime(year: %d, month: %d, day: %d, hour: %d, minute: %d, second: %d)",
 | 
				
			||||||
		t.Year(),
 | 
							t.Year(),
 | 
				
			||||||
		t.Month(),
 | 
							t.Month(),
 | 
				
			||||||
@ -454,6 +464,6 @@ func (e *VariableEncoder) encodeTime(t time.Time) error {
 | 
				
			|||||||
	))
 | 
						))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (e *VariableEncoder) encodeDuration(d time.Duration) error {
 | 
					func (e *ValueEncoder) encodeDuration(d time.Duration) error {
 | 
				
			||||||
	return e.writeString(fmt.Sprintf("duration(seconds: %d)", int(math.Round(d.Seconds()))))
 | 
						return e.writeString(fmt.Sprintf("duration(seconds: %d)", int(math.Round(d.Seconds()))))
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1,4 +1,4 @@
 | 
				
			|||||||
// Copyright (c) 2024 David Vogel
 | 
					// Copyright (c) 2024-2025 David Vogel
 | 
				
			||||||
//
 | 
					//
 | 
				
			||||||
// This software is released under the MIT License.
 | 
					// This software is released under the MIT License.
 | 
				
			||||||
// https://opensource.org/licenses/MIT
 | 
					// https://opensource.org/licenses/MIT
 | 
				
			||||||
@ -18,7 +18,7 @@ import (
 | 
				
			|||||||
	"github.com/google/go-cmp/cmp"
 | 
						"github.com/google/go-cmp/cmp"
 | 
				
			||||||
)
 | 
					)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestMarshalVariable(t *testing.T) {
 | 
					func TestMarshalValue(t *testing.T) {
 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		name    string
 | 
							name    string
 | 
				
			||||||
		arg     any
 | 
							arg     any
 | 
				
			||||||
@ -31,33 +31,33 @@ func TestMarshalVariable(t *testing.T) {
 | 
				
			|||||||
	}
 | 
						}
 | 
				
			||||||
	for _, tt := range tests {
 | 
						for _, tt := range tests {
 | 
				
			||||||
		t.Run(tt.name, func(t *testing.T) {
 | 
							t.Run(tt.name, func(t *testing.T) {
 | 
				
			||||||
			got, err := typst.MarshalVariable(tt.arg)
 | 
								got, err := typst.MarshalValue(tt.arg)
 | 
				
			||||||
			if (err != nil) != tt.wantErr {
 | 
								if (err != nil) != tt.wantErr {
 | 
				
			||||||
				t.Errorf("MarshalVariable() error = %v, wantErr %v", err, tt.wantErr)
 | 
									t.Errorf("MarshalValue() error = %v, wantErr %v", err, tt.wantErr)
 | 
				
			||||||
				return
 | 
									return
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
			if !reflect.DeepEqual(got, tt.want) {
 | 
								if !reflect.DeepEqual(got, tt.want) {
 | 
				
			||||||
				t.Errorf("MarshalVariable() = %v, want %v", got, tt.want)
 | 
									t.Errorf("MarshalValue() = %v, want %v", got, tt.want)
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
		})
 | 
							})
 | 
				
			||||||
	}
 | 
						}
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type VariableMarshalerType []byte
 | 
					type ValueMarshalerType []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (v VariableMarshalerType) MarshalTypstVariable() ([]byte, error) {
 | 
					func (v ValueMarshalerType) MarshalTypstValue() ([]byte, error) {
 | 
				
			||||||
	result := append([]byte{'"'}, v...)
 | 
						result := append([]byte{'"'}, v...)
 | 
				
			||||||
	result = append(result, '"')
 | 
						result = append(result, '"')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	return result, nil
 | 
						return result, nil
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
type VariableMarshalerTypePointer []byte
 | 
					type ValueMarshalerTypePointer []byte
 | 
				
			||||||
 | 
					
 | 
				
			||||||
var variableMarshalerTypePointer = VariableMarshalerTypePointer("test")
 | 
					var valueMarshalerTypePointer = ValueMarshalerTypePointer("test")
 | 
				
			||||||
var variableMarshalerTypePointerNil = VariableMarshalerTypePointer(nil)
 | 
					var valueMarshalerTypePointerNil = ValueMarshalerTypePointer(nil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func (v *VariableMarshalerTypePointer) MarshalTypstVariable() ([]byte, error) {
 | 
					func (v *ValueMarshalerTypePointer) MarshalTypstValue() ([]byte, error) {
 | 
				
			||||||
	if v != nil {
 | 
						if v != nil {
 | 
				
			||||||
		result := append([]byte{'"'}, *v...)
 | 
							result := append([]byte{'"'}, *v...)
 | 
				
			||||||
		result = append(result, '"')
 | 
							result = append(result, '"')
 | 
				
			||||||
@ -87,7 +87,7 @@ func (v *TextMarshalerTypePointer) MarshalText() ([]byte, error) {
 | 
				
			|||||||
	return nil, fmt.Errorf("no data")
 | 
						return nil, fmt.Errorf("no data")
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
func TestVariableEncoder(t *testing.T) {
 | 
					func TestValueEncoder(t *testing.T) {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
	tests := []struct {
 | 
						tests := []struct {
 | 
				
			||||||
		name    string
 | 
							name    string
 | 
				
			||||||
@ -156,11 +156,11 @@ func TestVariableEncoder(t *testing.T) {
 | 
				
			|||||||
		{"byte slice 1", []byte{1}, false, `bytes((1,))`},
 | 
							{"byte slice 1", []byte{1}, false, `bytes((1,))`},
 | 
				
			||||||
		{"byte slice empty", []byte{}, false, `bytes(())`},
 | 
							{"byte slice empty", []byte{}, false, `bytes(())`},
 | 
				
			||||||
		{"byte slice nil", []byte(nil), false, `bytes(())`},
 | 
							{"byte slice nil", []byte(nil), false, `bytes(())`},
 | 
				
			||||||
		{"MarshalTypstVariable value", VariableMarshalerType("test"), false, `"test"`},
 | 
							{"MarshalTypstValue value", ValueMarshalerType("test"), false, `"test"`},
 | 
				
			||||||
		{"MarshalTypstVariable value nil", VariableMarshalerType(nil), false, `""`},
 | 
							{"MarshalTypstValue value nil", ValueMarshalerType(nil), false, `""`},
 | 
				
			||||||
		{"MarshalTypstVariable pointer", &variableMarshalerTypePointer, false, `"test"`},
 | 
							{"MarshalTypstValue pointer", &valueMarshalerTypePointer, false, `"test"`},
 | 
				
			||||||
		{"MarshalTypstVariable pointer nil", &variableMarshalerTypePointerNil, false, `""`},
 | 
							{"MarshalTypstValue pointer nil", &valueMarshalerTypePointerNil, false, `""`},
 | 
				
			||||||
		{"MarshalTypstVariable nil pointer", struct{ A *VariableMarshalerTypePointer }{nil}, true, ``},
 | 
							{"MarshalTypstValue nil pointer", struct{ A *ValueMarshalerTypePointer }{nil}, true, ``},
 | 
				
			||||||
		{"MarshalText value", TextMarshalerType("test"), false, `"test"`},
 | 
							{"MarshalText value", TextMarshalerType("test"), false, `"test"`},
 | 
				
			||||||
		{"MarshalText value nil", TextMarshalerType(nil), false, `""`},
 | 
							{"MarshalText value nil", TextMarshalerType(nil), false, `""`},
 | 
				
			||||||
		{"MarshalText pointer", &textMarshalerTypePointer, false, `"test"`},
 | 
							{"MarshalText pointer", &textMarshalerTypePointer, false, `"test"`},
 | 
				
			||||||
@ -179,12 +179,12 @@ func TestVariableEncoder(t *testing.T) {
 | 
				
			|||||||
			t.Parallel()
 | 
								t.Parallel()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			var result bytes.Buffer
 | 
								var result bytes.Buffer
 | 
				
			||||||
			vEnc := typst.NewVariableEncoder(&result)
 | 
								vEnc := typst.NewValueEncoder(&result)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
			err := vEnc.Encode(tt.params)
 | 
								err := vEnc.Encode(tt.params)
 | 
				
			||||||
			switch {
 | 
								switch {
 | 
				
			||||||
			case err != nil && !tt.wantErr:
 | 
								case err != nil && !tt.wantErr:
 | 
				
			||||||
				t.Fatalf("Failed to encode typst variables: %v", err)
 | 
									t.Fatalf("Failed to encode typst values: %v", err)
 | 
				
			||||||
			case err == nil && tt.wantErr:
 | 
								case err == nil && tt.wantErr:
 | 
				
			||||||
				t.Fatalf("Expected error, but got none")
 | 
									t.Fatalf("Expected error, but got none")
 | 
				
			||||||
			}
 | 
								}
 | 
				
			||||||
							
								
								
									
										21
									
								
								variable-encoder-compat.go
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										21
									
								
								variable-encoder-compat.go
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,21 @@
 | 
				
			|||||||
 | 
					// Copyright (c) 2025 David Vogel
 | 
				
			||||||
 | 
					//
 | 
				
			||||||
 | 
					// This software is released under the MIT License.
 | 
				
			||||||
 | 
					// https://opensource.org/licenses/MIT
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					package typst
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					import "io"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// This exists for compatibility reasons.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Deprecated: Use NewValueEncoder instead, as this will be removed in a future version.
 | 
				
			||||||
 | 
					func NewVariableEncoder(w io.Writer) *ValueEncoder { return NewValueEncoder(w) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Deprecated: Use MarshalValue instead, as this will be removed in a future version.
 | 
				
			||||||
 | 
					func MarshalVariable(v any) ([]byte, error) { return MarshalValue(v) }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Deprecated: Use ValueMarshaler interface instead, as this will be removed in a future version.
 | 
				
			||||||
 | 
					type VariableMarshaler interface {
 | 
				
			||||||
 | 
						MarshalTypstVariable() ([]byte, error)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user