Initialize module and dependencies

This commit is contained in:
dwrz
2026-01-04 20:57:40 +00:00
commit a3b390c008
514 changed files with 310495 additions and 0 deletions

View File

@@ -0,0 +1,44 @@
package openai
import (
"bytes"
"fmt"
"io"
)
type ErrorAccumulator interface {
Write(p []byte) error
Bytes() []byte
}
type errorBuffer interface {
io.Writer
Len() int
Bytes() []byte
}
type DefaultErrorAccumulator struct {
Buffer errorBuffer
}
func NewErrorAccumulator() ErrorAccumulator {
return &DefaultErrorAccumulator{
Buffer: &bytes.Buffer{},
}
}
func (e *DefaultErrorAccumulator) Write(p []byte) error {
_, err := e.Buffer.Write(p)
if err != nil {
return fmt.Errorf("error accumulator write error, %w", err)
}
return nil
}
func (e *DefaultErrorAccumulator) Bytes() (errBytes []byte) {
if e.Buffer.Len() == 0 {
return
}
errBytes = e.Buffer.Bytes()
return
}

View File

@@ -0,0 +1,112 @@
package openai
import (
"fmt"
"io"
"mime/multipart"
"net/textproto"
"os"
"path/filepath"
"strings"
)
type FormBuilder interface {
CreateFormFile(fieldname string, file *os.File) error
CreateFormFileReader(fieldname string, r io.Reader, filename string) error
WriteField(fieldname, value string) error
Close() error
FormDataContentType() string
}
type DefaultFormBuilder struct {
writer *multipart.Writer
}
func NewFormBuilder(body io.Writer) *DefaultFormBuilder {
return &DefaultFormBuilder{
writer: multipart.NewWriter(body),
}
}
func (fb *DefaultFormBuilder) CreateFormFile(fieldname string, file *os.File) error {
return fb.createFormFile(fieldname, file, file.Name())
}
var quoteEscaper = strings.NewReplacer("\\", "\\\\", `"`, "\\\"")
func escapeQuotes(s string) string {
return quoteEscaper.Replace(s)
}
// CreateFormFileReader creates a form field with a file reader.
// The filename in Content-Disposition is required.
func (fb *DefaultFormBuilder) CreateFormFileReader(fieldname string, r io.Reader, filename string) error {
if filename == "" {
if f, ok := r.(interface{ Name() string }); ok {
filename = f.Name()
}
}
var contentType string
if f, ok := r.(interface{ ContentType() string }); ok {
contentType = f.ContentType()
}
h := make(textproto.MIMEHeader)
h.Set(
"Content-Disposition",
fmt.Sprintf(
`form-data; name="%s"; filename="%s"`,
escapeQuotes(fieldname),
escapeQuotes(filepath.Base(filename)),
),
)
// content type is optional, but it can be set
if contentType != "" {
h.Set("Content-Type", contentType)
}
fieldWriter, err := fb.writer.CreatePart(h)
if err != nil {
return err
}
_, err = io.Copy(fieldWriter, r)
if err != nil {
return err
}
return nil
}
func (fb *DefaultFormBuilder) createFormFile(fieldname string, r io.Reader, filename string) error {
if filename == "" {
return fmt.Errorf("filename cannot be empty")
}
fieldWriter, err := fb.writer.CreateFormFile(fieldname, filename)
if err != nil {
return err
}
_, err = io.Copy(fieldWriter, r)
if err != nil {
return err
}
return nil
}
func (fb *DefaultFormBuilder) WriteField(fieldname, value string) error {
if fieldname == "" {
return fmt.Errorf("fieldname cannot be empty")
}
return fb.writer.WriteField(fieldname, value)
}
func (fb *DefaultFormBuilder) Close() error {
return fb.writer.Close()
}
func (fb *DefaultFormBuilder) FormDataContentType() string {
return fb.writer.FormDataContentType()
}

View File

@@ -0,0 +1,15 @@
package openai
import (
"encoding/json"
)
type Marshaller interface {
Marshal(value any) ([]byte, error)
}
type JSONMarshaller struct{}
func (jm *JSONMarshaller) Marshal(value any) ([]byte, error) {
return json.Marshal(value)
}

View File

@@ -0,0 +1,52 @@
package openai
import (
"bytes"
"context"
"io"
"net/http"
)
type RequestBuilder interface {
Build(ctx context.Context, method, url string, body any, header http.Header) (*http.Request, error)
}
type HTTPRequestBuilder struct {
marshaller Marshaller
}
func NewRequestBuilder() *HTTPRequestBuilder {
return &HTTPRequestBuilder{
marshaller: &JSONMarshaller{},
}
}
func (b *HTTPRequestBuilder) Build(
ctx context.Context,
method string,
url string,
body any,
header http.Header,
) (req *http.Request, err error) {
var bodyReader io.Reader
if body != nil {
if v, ok := body.(io.Reader); ok {
bodyReader = v
} else {
var reqBytes []byte
reqBytes, err = b.marshaller.Marshal(body)
if err != nil {
return
}
bodyReader = bytes.NewBuffer(reqBytes)
}
}
req, err = http.NewRequestWithContext(ctx, method, url, bodyReader)
if err != nil {
return
}
if header != nil {
req.Header = header
}
return
}

View File

@@ -0,0 +1,15 @@
package openai
import (
"encoding/json"
)
type Unmarshaler interface {
Unmarshal(data []byte, v any) error
}
type JSONUnmarshaler struct{}
func (jm *JSONUnmarshaler) Unmarshal(data []byte, v any) error {
return json.Unmarshal(data, v)
}