darvaza-proxy / x

extra helpers for darvaza projects
MIT License
1 stars 0 forks source link

web/forms: typed field parsers using generics #51

Closed amery closed 2 months ago

amery commented 2 months ago

PR Type

Enhancement, Tests


Description


Changes walkthrough πŸ“

Relevant files
Enhancement
strconv.go
Add generic parsers and formatters for various types         

web/forms/strconv.go
  • Introduced generic parsers for signed, unsigned, float, and boolean
    types.
  • Added formatters for signed, unsigned, and float types.
  • Implemented utility functions for bit size calculation and range
    errors.
  • +76/-0   
    strconv_gen.go
    Add generated code for range-based parsing                             

    web/forms/strconv_gen.go
  • Added generated code for parsing signed, unsigned, and float types
    within specified ranges.
  • +45/-0   
    value.go
    Add functions to read and trim form values                             

    web/forms/value.go
  • Introduced functions to read and trim form values and post form
    values.
  • Added support for reading multiple values and omitting empty ones.
  • +74/-0   
    value_gen.go
    Add generated code for form value parsing                               

    web/forms/value_gen.go
  • Added generated code for reading and parsing form and post form values
    for various types.
  • Included range-based parsing for ordered types.
  • +431/-0 
    Tests
    strconv_gen.sh
    Add script for generating range-based parsing code             

    web/forms/strconv_gen.sh
  • Script to generate code for parsing signed, unsigned, and float types
    within specified ranges.
  • +69/-0   
    value_gen.sh
    Add script for generating form value parsing code               

    web/forms/value_gen.sh
  • Script to generate code for reading and parsing form and post form
    values for various types.
  • Included range-based parsing for ordered types.
  • +141/-0 

    πŸ’‘ PR-Agent usage: Comment /help on the PR to get a list of all available PR-Agent tools and their descriptions

    deepsource-io[bot] commented 2 months ago

    Here's the code health analysis summary for commits 74ab486..9eceb39. View details on DeepSource β†—.

    Analysis Summary

    AnalyzerStatusSummaryLink
    DeepSource Shell LogoShellβœ… SuccessView Check β†—
    DeepSource Go LogoGoβœ… SuccessView Check β†—

    πŸ’‘ If you’re a repository administrator, you can configure the quality gates from the settings.
    amery commented 2 months ago

    on hold waiting for https://github.com/darvaza-proxy/core/pull/63

    codiumai-pr-agent-pro[bot] commented 2 months ago

    PR-Agent was enabled for this repository. To continue using it, please link your git user with your CodiumAI identity here.

    PR Reviewer Guide πŸ”

    ⏱️ Estimated effort to review: 4 πŸ”΅πŸ”΅πŸ”΅πŸ”΅βšͺ
    πŸ§ͺ No relevant tests
    πŸ”’ No security concerns identified
    ⚑ Key issues to review

    Error Handling
    The function `ParseBool` does not handle the case where `strconv.ParseBool` might return an error other than `strconv.ErrSyntax`. This could lead to incorrect error propagation where an error is expected but not handled correctly. Type Conversion
    The conversion from `int64` to generic type `T` in `ParseSigned` and from `uint64` to `T` in `ParseUnsigned` might not always be safe or expected. This could lead to runtime panics if `T` cannot hold the converted value. Reflection Usage
    The use of reflection in `bitSize` function to determine the size of types could be inefficient. Consider using a more direct approach if the type sizes are known and fixed.
    codiumai-pr-agent-pro[bot] commented 2 months ago

    PR-Agent was enabled for this repository. To continue using it, please link your git user with your CodiumAI identity here.

    PR Code Suggestions ✨

    CategorySuggestion                                                                                                                                    Score
    Maintainability
    Refactor repeated form value parsing logic into a generic helper function to reduce code duplication ___ **Refactor the repeated pattern of parsing form values into a separate helper function
    to reduce code duplication and improve maintainability.** [web/forms/value_gen.go [132-142]](https://github.com/darvaza-proxy/x/pull/51/files#diff-b0859517eb6e2dec2d6277095939368106155989e832c9519aba056962c84593R132-R142) ```diff func FormValueFloat[T core.Float](req *http.Request, field string) (value T, found bool, err error) { + value, found, err = parseFormValue[T, core.Float](req, field, ParseFloat[T]) + return value, found, err +} + +func parseFormValue[T any, P core.Parser[T]](req *http.Request, field string, parser func(string) (T, error)) (value T, found bool, err error) { s, found, err := FormValue[string](req, field) if err == nil && found { - value, err = ParseFloat[T](s) + value, err = parser(s) if err != nil { err = core.Wrap(err, field) } } return value, found, err } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 9 Why: This refactoring reduces code duplication and improves maintainability by centralizing the parsing logic into a helper function.
    9
    Possible bug
    Add a precondition check to ensure min is less than max before range checking ___ **Add a check to ensure that the min value is less than the max value before
    performing the range check to prevent logical errors.** [web/forms/strconv_gen.sh [54-55]](https://github.com/darvaza-proxy/x/pull/51/files#diff-feaa1f3baa038d9a1c9b07e676e8db6bd8906539b932cdb10ec4a56179771803R54-R55) ```diff -if value < min || value > max { +if min > max { + err = errors.New("min should not be greater than max") +} else if value < min || value > max { err = errRange("$fn", $format_v) } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 9 Why: Adding a check to ensure `min` is less than `max` prevents logical errors and potential bugs, making this a crucial improvement for code correctness.
    9
    Possible issue
    Add validation for empty or null field parameter to prevent potential runtime errors ___ **Consider handling the case where the field parameter is empty or null to prevent
    runtime errors or unexpected behavior when accessing the form values.** [web/forms/value_gen.go [18-28]](https://github.com/darvaza-proxy/x/pull/51/files#diff-b0859517eb6e2dec2d6277095939368106155989e832c9519aba056962c84593R18-R28) ```diff func FormValueSigned[T core.Signed](req *http.Request, field string) (value T, found bool, err error) { + if field == "" { + return value, false, fmt.Errorf("field name is empty") + } s, found, err := FormValue[string](req, field) if err == nil && found { value, err = ParseSigned[T](s) if err != nil { err = core.Wrap(err, field) } } return value, found, err } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 8 Why: This suggestion adds a check for an empty `field` parameter, which can prevent potential runtime errors and improve the robustness of the function.
    8
    Enhancement
    Enhance error messages with more context to aid in debugging ___ **Ensure that the error message includes more context about the value that caused the
    range error, improving the error's usefulness for debugging.** [web/forms/value_gen.sh [123]](https://github.com/darvaza-proxy/x/pull/51/files#diff-c045caeee6897b247668a7c0081fdbd359aaa0e6266601f7a2e86e709f6e47d1R123-R123) ```diff -err = errRange("$fn", $format_v) +err = errRange("$fn", $format_v, "Value out of range: " + $format_v) ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 8 Why: Adding more context to error messages significantly aids in debugging, making the code more maintainable and user-friendly. This is a valuable enhancement.
    8
    Enhance error handling by providing specific error messages for different failure scenarios ___ **To improve error handling, consider adding specific error messages for each type of
    failure within the function to aid in debugging and provide clearer context to the
    caller.** [web/forms/value_gen.go [75-85]](https://github.com/darvaza-proxy/x/pull/51/files#diff-b0859517eb6e2dec2d6277095939368106155989e832c9519aba056962c84593R75-R85) ```diff func FormValueUnsigned[T core.Unsigned](req *http.Request, field string) (value T, found bool, err error) { + if field == "" { + return value, false, fmt.Errorf("field name is empty") + } s, found, err := FormValue[string](req, field) - if err == nil && found { + if err != nil { + return value, found, fmt.Errorf("failed to retrieve form value: %w", err) + } + if found { value, err = ParseUnsigned[T](s) if err != nil { - err = core.Wrap(err, field) + return value, found, fmt.Errorf("failed to parse unsigned value: %w", err) } } return value, found, err } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 7 Why: The suggestion improves error handling by providing more specific error messages, which can aid in debugging and provide clearer context to the caller.
    7
    Add logging for errors to improve traceability and debugging capabilities ___ **Implement a more robust error handling strategy that includes logging of errors for
    better traceability and debugging.** [web/forms/value_gen.go [411-431]](https://github.com/darvaza-proxy/x/pull/51/files#diff-b0859517eb6e2dec2d6277095939368106155989e832c9519aba056962c84593R411-R431) ```diff func FormValuesBool[T core.Bool](req *http.Request, field string) (values []T, found bool, err error) { ss, found, err := FormValues[string](req, field) - if err == nil && found { + if err != nil { + log.Printf("Error retrieving form values: %v", err) + return nil, false, err + } + if found { values = make([]T, 0, len(ss)) for _, s := range ss { v, err := ParseBool[T](s) if err != nil { + log.Printf("Error parsing boolean from form values: %v", err) return values, true, core.Wrap(err, field) } values = append(values, v) } } return values, found, err } ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 6 Why: Adding logging for errors can improve traceability and debugging, but it may not be necessary for all use cases and could introduce performance overhead.
    6
    Performance
    Improve performance and compatibility by replacing tr with awk for case conversion ___ **Replace the use of tr for case conversion with awk for better performance and
    compatibility across different Unix-like systems.** [web/forms/value_gen.sh [27-28]](https://github.com/darvaza-proxy/x/pull/51/files#diff-c045caeee6897b247668a7c0081fdbd359aaa0e6266601f7a2e86e709f6e47d1R27-R28) ```diff -cat | tr '[:upper:]' '[:lower:]' +awk '{print tolower($0)}' ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 7 Why: The suggestion to use `awk` for case conversion can improve performance and compatibility, but the existing `tr` command is already widely compatible and performant. The improvement is minor but valid.
    7
    Best practice
    Improve error handling by checking the result of error wrapping ___ **Use a more robust error handling strategy by checking if core.Wrap returns an error
    and handling it appropriately.** [web/forms/value_gen.sh [78]](https://github.com/darvaza-proxy/x/pull/51/files#diff-c045caeee6897b247668a7c0081fdbd359aaa0e6266601f7a2e86e709f6e47d1R78-R78) ```diff -err = core.Wrap(err, field) +wrappedErr := core.Wrap(err, field) +if wrappedErr != nil { + return value, found, wrappedErr +} ``` - [ ] **Apply this suggestion**
    Suggestion importance[1-10]: 6 Why: Checking the result of `core.Wrap` improves error handling robustness, but the existing code already handles errors reasonably well. This suggestion is a good practice but not critical.
    6
    amery commented 2 months ago

    darvaza.org/x/web@v0.6.5 tagged