AlecAivazis / survey

A golang library for building interactive and accessible prompts with full support for windows and posix terminals.
MIT License
4.07k stars 349 forks source link

type assertion for integer is failing for AskOne method #451

Closed halshar closed 1 year ago

halshar commented 1 year ago

What operating system and terminal are you using? linux mint 20.2 uma, zsh

An example that showcases the bug.

package main

import (
    "errors"
    "fmt"

    "github.com/AlecAivazis/survey/v2"
)

func intValidtor(ans interface{}) error {
    intVal, ok := ans.(int)
    fmt.Println(ok)
    fmt.Printf("%T\n", intVal)
    if !ok {
        return errors.New("the response must be an integer")
    }
    return nil
}

func main() {
    var number int

    nprompt := &survey.Input{
        Message: "enter number",
    }
    survey.AskOne(nprompt, &number, survey.WithValidator(survey.Required), survey.WithValidator(intValidtor))

    fmt.Println(number)
}

What did you expect to see? the ok variable to be true

What did you see instead? the ok variable is false

// when the input is blank, only the required validator works
X Sorry, your reply was invalid: Value is required

// when the input is 1
falseer number 1
X Sorry, your reply was invalid: the response must be an integer

// when the input is asdf
falseer number asdf
X Sorry, your reply was invalid: the response must be an integer

instead of ans.(int) i've tried all other integer types(signed and unsigned) but the value is still false negating the value works for integers but when I input any string the value becomes 0(default)

mod file:

go 1.18

require github.com/AlecAivazis/survey/v2 v2.3.6

require (
        github.com/kballard/go-shellquote v0.0.0-20180428030007-95032a82bc51 // indirect
        github.com/mattn/go-colorable v0.1.13 // indirect
        github.com/mattn/go-isatty v0.0.16 // indirect
        github.com/mgutz/ansi v0.0.0-20200706080929-d51e80ef957d // indirect
        golang.org/x/sys v0.0.0-20220915200043-7b5979e65e41 // indirect
        golang.org/x/term v0.0.0-20220722155259-a9ba230a4035 // indirect
        golang.org/x/text v0.3.7 // indirect
)
halshar commented 1 year ago

instead of type conversion i've switched to converting the input to int and checking, the below validator works without issues

func intValidtor(ans interface{}) error {
    inpVal, _ := ans.(string)

    if _, err := strconv.Atoi(inpVal); err != nil {
        return errors.New("input must be an integer")
    }
    return nil
}
mislav commented 1 year ago

Hi, all user's inputs in a terminal are technically strings (even if they consists only of digits), and Survey will always store the result as a string, even if you applied a number validator to the result. Like you've discovered, it's the responsibility of your app to convert a Go string into another type that is more suitable for your purposes.

Ref. https://github.com/AlecAivazis/survey/issues/388