Skip to content

Conversation

@aThorp96
Copy link
Contributor

@aThorp96 aThorp96 commented Aug 3, 2021

Hello! I implemented these features when using your library but I think they might serve better purpose as part of the library.

The two features are

  1. A DocumentBuilder which allows you to pragmatically construct gemini files line-by line with additional support for headers and footers
    2. A RequireInputHandler which allows the user to provide a custom prompt (META) on the response. Moving to a separate PR per request

Copy link
Owner

@a-h a-h left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks so much for your contribution, and I'm really happy you're using the project!

Good idea to create a text/gemini builder, I've suggested a few changes to the design that would reduce allocations.

DocumentBuilder uses the builder pattern and Gemini's line-type specification
to pragmatically build gemini files line-by-line.
@aThorp96 aThorp96 changed the title Add Document Builder type and RequireInputHandler function Add Document Builder type Aug 8, 2021
document.go Outdated
Comment on lines 20 to 21
builder := new(strings.Builder)
return DocumentBuilder{"", builder, ""}
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This may look a bit weird but this was my solution to avoid copying the builder. If there is an easier-to-read solution I'd be happy to integrate it.

"bytes"
"strings"

"github.com/pkg/errors"
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

See commit message for dependency discussion

Comment on lines 140 to 169
// Build builds the document into a serialized byte slice.
func (doc *DocumentBuilder) Build() ([]byte, error) {
buf := bytes.Buffer{}

// Write header
_, err := buf.WriteString(doc.header)
if err != nil {
return nil, errors.Wrap(err, "Error building document header")
}
if !strings.HasSuffix(doc.header, "\n") {
_, err = buf.WriteString("\n")
if err != nil {
return nil, errors.Wrap(err, "Error building document header")
}
}

// Write body
_, err = buf.WriteString(doc.body.String())
if err != nil {
return nil, errors.Wrap(err, "Error building document body")
}

// Write footer
_, err = buf.WriteString(doc.footer)
if err != nil {
return nil, errors.Wrap(err, "Error building document footer")
}

return buf.Bytes(), nil
}
Copy link
Contributor Author

@aThorp96 aThorp96 Aug 8, 2021

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

There is a lot going on here, compared to the previous iteration, but not as much as it looks. I believe we need to ensure there are newlines in between the header and body, which makes this a bit longer than it otherwise would. Also, this error handling feels a bit more verbose than normal. I'm a bit rusty with my Go though so perhaps there is a more concise way to handle these.

- Use a string builder instead of string to minimize allocations
- Use proper doc-comment format

With the use of stringBuilder, errors have been introduced into the package.
I added the dependency `github.com/pkg/errors` to help handle them, but if
we'd prefer to stick with the standard library I think that'd be fair. My
thinking was the circumstances that caused strings.Builder.WriteString() to
error would warrent a stack trace and metadata, something which is more
pragmatically done using `github.com/pkg/errors`.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants