Skip to content

Instantly share code, notes, and snippets.

@karrick
Last active February 15, 2018 08:31
Show Gist options
  • Save karrick/bb5ea3da3fa690ce9e95950bccf2931b to your computer and use it in GitHub Desktop.
Save karrick/bb5ea3da3fa690ce9e95950bccf2931b to your computer and use it in GitHub Desktop.
Go function that prompts user but has a timeout on standard input
package main
import (
"bufio"
"fmt"
"io"
"os"
"time"
"github.com/karrick/gorill"
)
func readStdinWithTimeout(prompt, defaultValue string, timeout time.Duration) (string, error) {
var ior io.Reader = os.Stdin
if timeout == 0 {
fmt.Fprintf(os.Stderr, "%s (defaults to %q)? ", prompt, defaultValue)
} else {
fmt.Fprintf(os.Stderr, "%s (defaults to %q after %v)? ", prompt, defaultValue, timeout)
ior = gorill.NewTimedReadCloser(gorill.NopCloseReader(ior), timeout)
}
scanner := bufio.NewScanner(ior)
if !scanner.Scan() {
fmt.Fprintln(os.Stderr) // user did not add newline so we must
err := scanner.Err()
if _, ok := err.(gorill.ErrTimeout); ok {
return defaultValue, nil // return default value when timeout
}
return "", err
}
if line := scanner.Text(); line != "" {
return strings.ToLower(line), nil
}
return defaultValue, nil
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment