├── media ├── demo.gif ├── logo.png └── banner.png ├── .goreleaser.Dockerfile ├── hugo ├── content │ ├── cli │ │ └── _index.md │ └── install │ │ └── _index.md ├── .gitmodules └── archetypes │ └── default.md ├── .gitmodules ├── main.go ├── cmd ├── version.go ├── interactive.go ├── root.go ├── generate-docs.go ├── processor_slug.go ├── processor_camel.go ├── processor_kebab.go ├── processor_lower.go ├── processor_md5.go ├── processor_snake.go ├── processor_title.go ├── processor_upper.go ├── processor_hex-rgb.go ├── processor_pascal.go ├── processor_reverse.go ├── processor_sha1.go ├── completion.go ├── processor_unique-lines.go ├── processor_json-escape.go ├── processor_reverse-lines.go ├── processor_sort-lines.go ├── processor_url-decode.go ├── processor_url-encode.go ├── processor_json-yaml.go ├── processor_sha224.go ├── processor_sha256.go ├── processor_sha384.go ├── processor_sha512.go ├── processor_shuffle-lines.go ├── processor_count-lines.go ├── processor_count-words.go ├── processor_json-msgpack.go ├── processor_markdown-html.go ├── processor_msgpack-json.go ├── processor_html-encode.go ├── processor_xxh-32.go ├── processor_xxh-64.go ├── processor_blake2s.go ├── processor_hex-encode.go ├── processor_html-decode.go ├── processor_adler32.go ├── processor_count-chars.go ├── processor_xxh-128.go ├── processor_base32-decode.go ├── processor_base62-decode.go ├── processor_extract-url.go ├── processor_hex-decode.go ├── processor_rot13.go ├── processor_base32-encode.go ├── processor_extract-ip.go ├── processor_ascii85-encode.go ├── processor_ascii85-decode.go ├── processor_morse-encode.go ├── processor_number-lines.go ├── processor_json.go ├── processor_bcrypt.go ├── processor_blake2b.go ├── processor_yaml-json.go ├── processor_crc32.go ├── processor_json-unescape.go ├── processor_base64-decode.go ├── processor_base64-encode.go ├── processor_base62-encode.go ├── processor_base58-encode.go ├── processor_base58-decode.go ├── processor_remove-spaces.go ├── processor_base64url-decode.go ├── processor_base64url-encode.go ├── processor_extract-emails.go ├── processor_remove-newlines.go ├── processor_crockford-base32-decode.go ├── processor_crockford-base32-encode.go ├── processor_morse-decode.go ├── processor_zeropad.go └── processor_escape-quotes.go ├── .gitignore ├── .github └── workflows │ └── go.yml ├── processors ├── markdown.go ├── rgb.go ├── rot13.go ├── emails.go ├── streaming.go ├── html.go ├── base32.go ├── numberlines.go ├── ip.go ├── base64url.go ├── ascii85.go ├── hex.go ├── rgb_test.go ├── markdown_test.go ├── checksums.go ├── ip_test.go ├── base64.go ├── rot13_test.go ├── url.go ├── spaces.go ├── xxhash.go └── emails_test.go ├── utils └── text.go ├── .golangci.yml ├── LICENSE └── go.mod /media/demo.gif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhimanyu003/sttr/HEAD/media/demo.gif -------------------------------------------------------------------------------- /media/logo.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhimanyu003/sttr/HEAD/media/logo.png -------------------------------------------------------------------------------- /media/banner.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/abhimanyu003/sttr/HEAD/media/banner.png -------------------------------------------------------------------------------- /.goreleaser.Dockerfile: -------------------------------------------------------------------------------- 1 | FROM scratch 2 | COPY sttr /usr/bin/sttr 3 | ENTRYPOINT ["/usr/bin/sttr"] -------------------------------------------------------------------------------- /hugo/content/cli/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 100 3 | title: CLI Reference 4 | bookCollapseSection: true 5 | --- -------------------------------------------------------------------------------- /hugo/.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "themes/book"] 2 | path = themes/book 3 | url = https://github.com/alex-shpak/hugo-book 4 | -------------------------------------------------------------------------------- /.gitmodules: -------------------------------------------------------------------------------- 1 | [submodule "hugo/themes/book"] 2 | path = hugo/themes/book 3 | url = https://github.com/alex-shpak/hugo-book 4 | -------------------------------------------------------------------------------- /hugo/archetypes/default.md: -------------------------------------------------------------------------------- 1 | --- 2 | title: "{{ replace .Name "-" " " | title }}" 3 | date: {{ .Date }} 4 | draft: true 5 | --- 6 | 7 | -------------------------------------------------------------------------------- /main.go: -------------------------------------------------------------------------------- 1 | package main 2 | 3 | import ( 4 | "github.com/abhimanyu003/sttr/cmd" 5 | ) 6 | 7 | // version specify version of application using ldflags 8 | var version = "dev" 9 | 10 | // generate the individual processor commands 11 | //go:generate go run cmd/generate.go 12 | func main() { 13 | cmd.Version = version 14 | cmd.Execute() 15 | } 16 | -------------------------------------------------------------------------------- /cmd/version.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | var Version = "unknown" 10 | 11 | func init() { 12 | rootCmd.AddCommand(versionCmd) 13 | } 14 | 15 | var versionCmd = &cobra.Command{ 16 | Use: "version", 17 | Short: "Print the version of sttr", 18 | Long: `All software has a version (semantic at best). This is sttr's'`, 19 | Run: func(cmd *cobra.Command, args []string) { 20 | fmt.Println(Version) 21 | }, 22 | } 23 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | # Binaries for programs and plugins 2 | sttr 3 | *.exe 4 | *.exe~ 5 | *.dll 6 | *.so 7 | *.dylib 8 | 9 | # Test binary, built with `go hugo -c` 10 | *.test 11 | 12 | # Output of the go coverage tool, specifically when used with LiteIDE 13 | *.out 14 | 15 | # Dependency directories (remove the comment below to include it) 16 | vendor/ 17 | 18 | # VsCode 19 | 20 | .vsscode/* 21 | .vscode/ 22 | 23 | # goreleaser dist folder 24 | dist/ 25 | 26 | # IntelliJ 27 | .idea 28 | *.iml 29 | .idea/workspace.xml 30 | .idea/tasks.xml 31 | .idea/gradle.xml 32 | .idea/assetWizardSettings.xml 33 | .idea/dictionaries 34 | .idea/libraries 35 | .idea/caches 36 | -------------------------------------------------------------------------------- /cmd/interactive.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "github.com/abhimanyu003/sttr/ui" 5 | "github.com/spf13/cobra" 6 | "io" 7 | ) 8 | 9 | func init() { 10 | rootCmd.AddCommand(interactiveCmd) 11 | } 12 | 13 | var interactiveCmd = &cobra.Command{ 14 | Use: "interactive", 15 | Short: "Use sttr in interactive mode", 16 | Long: `Launches a nice terminal UI where you 17 | can explore the available processors interactively`, 18 | RunE: func(cmd *cobra.Command, args []string) error { 19 | var err error 20 | in := "" 21 | 22 | if len(args) == 0 { 23 | all, err := io.ReadAll(cmd.InOrStdin()) 24 | if err != nil { 25 | return err 26 | } 27 | in = string(all) 28 | } else { 29 | in = args[0] 30 | } 31 | 32 | x := ui.New(in) 33 | x.Render() 34 | return err 35 | }, 36 | } 37 | -------------------------------------------------------------------------------- /cmd/root.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "os" 6 | 7 | "github.com/abhimanyu003/sttr/ui" 8 | 9 | "github.com/spf13/cobra" 10 | ) 11 | 12 | var rootCmd = &cobra.Command{ 13 | Use: "sttr", 14 | Short: "sttr is a fast and flexible string/text converter", 15 | Long: `sttr is a command line tool that allows you to quickly apply various 16 | transformation operations on the input text. 17 | 18 | Complete documentation is available at https://github.com/abhimanyu003/sttr`, 19 | RunE: func(cmd *cobra.Command, args []string) error { 20 | if len(args) == 0 { 21 | x := ui.New("") 22 | x.Render() 23 | } 24 | return nil 25 | }, 26 | } 27 | 28 | func init() { 29 | } 30 | 31 | func Execute() { 32 | if err := rootCmd.Execute(); err != nil { 33 | fmt.Println(err) 34 | os.Exit(1) 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /hugo/content/install/_index.md: -------------------------------------------------------------------------------- 1 | --- 2 | weight: 1 3 | title: Install 4 | --- 5 | 6 | # Installing sttr 7 | 8 | #### Quick install 9 | 10 | You can run the below `curl` to install it somewhere in your PATH for easy use. 11 | Ideally it will be installed at `./bin` folder 12 | 13 | ``` 14 | curl -sfL https://raw.githubusercontent.com/abhimanyu003/sttr/main/install.sh | sh 15 | ``` 16 | 17 | #### Homebrew 18 | 19 | If you are on macOS and using Homebrew, you can install `sttr` with the following: 20 | 21 | ``` 22 | brew tap abhimanyu003/sttr 23 | brew install sttr 24 | ``` 25 | 26 | #### Go 27 | 28 | ``` 29 | go install github.com/abhimanyu003/sttr@latest 30 | ``` 31 | 32 | #### Manually 33 | 34 | Download the pre-compiled binaries from the [Release!](https://github.com/abhimanyu003/sttr/releases) page and copy them to the desired location. -------------------------------------------------------------------------------- /.github/workflows/go.yml: -------------------------------------------------------------------------------- 1 | name: Build 2 | on: 3 | push: 4 | branches: 5 | - "*" 6 | pull_request: 7 | branches: 8 | - "*" 9 | 10 | jobs: 11 | build: 12 | runs-on: ubuntu-latest 13 | steps: 14 | - name: Checkout 15 | uses: actions/checkout@1af3b93b6815bc44a9784bd300feb67ff0d1eeb3 # v6.0.0 16 | with: 17 | fetch-depth: 1 18 | 19 | - name: Setup Go 20 | uses: actions/setup-go@4dc6199c7b1a012772edbd06daecab0f50c9053c # v6.1.0 21 | with: 22 | go-version: '1.24' 23 | go-version-file: 'go.mod' 24 | cache-dependency-path: 'go.sum' 25 | 26 | - name: Generate 27 | run: go generate -v ./... 28 | 29 | - name: Build Test 30 | run: go build -v ./... 31 | 32 | - name: Unit Test 33 | run: go test -v ./... -------------------------------------------------------------------------------- /processors/markdown.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "bytes" 5 | "fmt" 6 | 7 | "github.com/yuin/goldmark" 8 | ) 9 | 10 | // Markdown converts Markdown to HTML. 11 | type Markdown struct{} 12 | 13 | func (p Markdown) Name() string { 14 | return "markdown-html" 15 | } 16 | 17 | func (p Markdown) Alias() []string { 18 | return []string{"md-html"} 19 | } 20 | 21 | func (p Markdown) Transform(data []byte, _ ...Flag) (string, error) { 22 | var buf bytes.Buffer 23 | if err := goldmark.Convert(data, &buf); err != nil { 24 | return "", err 25 | } 26 | return buf.String(), nil 27 | } 28 | 29 | func (p Markdown) Flags() []Flag { 30 | return nil 31 | } 32 | 33 | func (p Markdown) Title() string { 34 | title := "Markdown to HTML" 35 | return fmt.Sprintf("%s (%s)", title, p.Name()) 36 | } 37 | 38 | func (p Markdown) Description() string { 39 | return "Convert Markdown to HTML" 40 | } 41 | 42 | func (p Markdown) FilterValue() string { 43 | return p.Title() 44 | } 45 | -------------------------------------------------------------------------------- /processors/rgb.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/lucasb-eyer/go-colorful" 7 | ) 8 | 9 | // HexToRGB converts hex color code to R, G, B codes 10 | // here we are using data library helper. 11 | type HexToRGB struct{} 12 | 13 | func (p HexToRGB) Name() string { 14 | return "hex-rgb" 15 | } 16 | 17 | func (p HexToRGB) Alias() []string { 18 | return nil 19 | } 20 | 21 | func (p HexToRGB) Transform(data []byte, _ ...Flag) (string, error) { 22 | c, err := colorful.Hex(string(data)) 23 | return fmt.Sprintf("%d, %d, %d", int(c.R*255), int(c.G*255), int(c.B*255)), err 24 | } 25 | 26 | func (p HexToRGB) Flags() []Flag { 27 | return nil 28 | } 29 | 30 | func (p HexToRGB) Title() string { 31 | title := "Hex To RGB" 32 | return fmt.Sprintf("%s (%s)", title, p.Name()) 33 | } 34 | 35 | func (p HexToRGB) Description() string { 36 | return "Convert a #hex-color code to RGB" 37 | } 38 | 39 | func (p HexToRGB) FilterValue() string { 40 | return p.Title() 41 | } 42 | -------------------------------------------------------------------------------- /utils/text.go: -------------------------------------------------------------------------------- 1 | package utils 2 | 3 | import ( 4 | "bufio" 5 | "os" 6 | "regexp" 7 | "strings" 8 | 9 | "github.com/iancoleman/strcase" 10 | ) 11 | 12 | // ReadMultilineInput read multiple lines from stdin, 13 | // to return the input, two empty line are expected 14 | func ReadMultilineInput() string { 15 | str := make([]string, 0) 16 | scanner := bufio.NewScanner(os.Stdin) 17 | empty := 0 18 | for { 19 | scanner.Scan() 20 | text := scanner.Text() 21 | str = append(str, text) 22 | if len(text) != 0 { 23 | empty = 0 24 | } else { 25 | empty++ 26 | if empty == 2 { 27 | break 28 | } 29 | } 30 | } 31 | // Use collected inputs 32 | return strings.Join(str[:len(str)-2], "\n") 33 | } 34 | 35 | func ToKebabCase(input []byte) string { 36 | str := regexp.MustCompile(`\s+`).ReplaceAllString(string(input), " ") 37 | return strcase.ToKebab(str) 38 | } 39 | 40 | func ToLowerCamelCase(input []byte) string { 41 | str := regexp.MustCompile(`\s+`).ReplaceAllString(string(input), " ") 42 | return strcase.ToLowerCamel(str) 43 | } 44 | -------------------------------------------------------------------------------- /.golangci.yml: -------------------------------------------------------------------------------- 1 | run: 2 | timeout: 5m 3 | 4 | linters: 5 | disable-all: true 6 | enable: 7 | - bodyclose 8 | - deadcode 9 | - depguard 10 | - dogsled 11 | - errcheck 12 | - exportloopref 13 | - exhaustive 14 | - funlen 15 | - gochecknoinits 16 | - goconst 17 | - gocritic 18 | - gocyclo 19 | - gofmt 20 | - goprintffuncname 21 | - gosimple 22 | - govet 23 | - ineffassign 24 | - misspell 25 | - nakedret 26 | - noctx 27 | - nolintlint 28 | - rowserrcheck 29 | - staticcheck 30 | - structcheck 31 | - stylecheck 32 | - typecheck 33 | - unconvert 34 | - unparam 35 | - unused 36 | - varcheck 37 | - whitespace 38 | - wastedassign 39 | - nilerr 40 | 41 | # don't enable: 42 | # - dupl 43 | # - asciicheck 44 | # - scopelint 45 | # - gochecknoglobals 46 | # - gocognit 47 | # - godot 48 | # - godox 49 | # - goerr113 50 | # - interfacer 51 | # - maligned 52 | # - prealloc 53 | # - testpackage 54 | # - revive 55 | # - wsl -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2021 Abhimanyu Sharma 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /cmd/generate-docs.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "fmt" 5 | "github.com/spf13/cobra" 6 | "github.com/spf13/cobra/doc" 7 | "os" 8 | "path/filepath" 9 | "strings" 10 | ) 11 | 12 | func init() { 13 | rootCmd.AddCommand(docsCmd) 14 | } 15 | 16 | var docsCmd = &cobra.Command{ 17 | Use: "generate-docs", 18 | Short: "Generate markdown docs for sttr", 19 | Hidden: true, 20 | Long: `Generate markdown docs for all the commands of sttr`, 21 | Args: cobra.ExactArgs(1), 22 | RunE: func(cmd *cobra.Command, args []string) error { 23 | linkHandler := func(name string) string { 24 | return fmt.Sprintf(`{{< relref "%s" >}}`, name) 25 | } 26 | 27 | filePrepender := func(filename string) string { 28 | name := filepath.Base(filename) 29 | base := strings.TrimSuffix(name, filepath.Ext(name)) 30 | title := strings.ReplaceAll(base, "_", " ") 31 | 32 | return fmt.Sprintf("---\ntitle: %s\n---\n", title) 33 | } 34 | 35 | dir := args[0] 36 | if err := os.MkdirAll(dir, 0o755); err != nil { 37 | return err 38 | } 39 | rootCmd.DisableAutoGenTag = true 40 | return doc.GenMarkdownTreeCustom(rootCmd, dir, filePrepender, linkHandler) 41 | }, 42 | } 43 | -------------------------------------------------------------------------------- /processors/rot13.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "fmt" 5 | "strings" 6 | ) 7 | 8 | // ROT13 converts string with ROT13 cypher. 9 | // https://en.wikipedia.org/wiki/ROT13 10 | type ROT13 struct{} 11 | 12 | func (p ROT13) Name() string { 13 | return "rot13" 14 | } 15 | 16 | func (p ROT13) Alias() []string { 17 | return []string{"rot13-encode", "rot13-enc"} 18 | } 19 | 20 | func (p ROT13) Transform(data []byte, _ ...Flag) (string, error) { 21 | return strings.Map(rot13, string(data)), nil 22 | } 23 | 24 | func (p ROT13) Flags() []Flag { 25 | return nil 26 | } 27 | 28 | func (p ROT13) Title() string { 29 | title := "ROT13 Letter Substitution" 30 | return fmt.Sprintf("%s (%s)", title, p.Name()) 31 | } 32 | 33 | func (p ROT13) Description() string { 34 | return "Cipher/Decipher your text with ROT13 letter substitution" 35 | } 36 | 37 | func (p ROT13) FilterValue() string { 38 | return p.Title() 39 | } 40 | 41 | // rot13 private helper function for converting rune into rot13. 42 | func rot13(r rune) rune { 43 | if r >= 'a' && r <= 'z' { 44 | // Rotate lowercase letters 13 places. 45 | if r >= 'm' { 46 | return r - 13 47 | } 48 | 49 | return r + 13 50 | } else if r >= 'A' && r <= 'Z' { 51 | // Rotate uppercase letters 13 places. 52 | if r >= 'M' { 53 | return r - 13 54 | } 55 | 56 | return r + 13 57 | } 58 | // Do nothing. 59 | return r 60 | } 61 | -------------------------------------------------------------------------------- /processors/emails.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "fmt" 5 | "github.com/mcnijman/go-emailaddress" 6 | "strings" 7 | ) 8 | 9 | // ExtractEmails will pluck all the valid emails from a given text. 10 | type ExtractEmails struct{} 11 | 12 | func (p ExtractEmails) Name() string { 13 | return "extract-emails" 14 | } 15 | 16 | func (p ExtractEmails) Alias() []string { 17 | return []string{"find-emails", "find-email", "extract-email"} 18 | } 19 | 20 | func (p ExtractEmails) Transform(data []byte, f ...Flag) (string, error) { 21 | var emails []string 22 | extracted := emailaddress.FindWithIcannSuffix(data, false) 23 | for _, e := range extracted { 24 | emails = append(emails, e.String()) 25 | } 26 | 27 | separator := "\n" 28 | for _, flag := range f { 29 | if flag.Short == "s" { 30 | x, ok := flag.Value.(string) 31 | if ok { 32 | separator = x 33 | } 34 | } 35 | } 36 | return strings.Join(emails, separator), nil 37 | } 38 | 39 | func (p ExtractEmails) Flags() []Flag { 40 | return []Flag{ 41 | { 42 | Name: "separator", 43 | Short: "s", 44 | Desc: "Separator to split multiple emails", 45 | Value: "", 46 | Type: FlagString, 47 | }, 48 | } 49 | } 50 | 51 | func (p ExtractEmails) Title() string { 52 | title := "Extract Emails" 53 | return fmt.Sprintf("%s (%s)", title, p.Name()) 54 | } 55 | 56 | func (p ExtractEmails) Description() string { 57 | return "Extract emails from given text" 58 | } 59 | 60 | func (p ExtractEmails) FilterValue() string { 61 | return p.Title() 62 | } 63 | -------------------------------------------------------------------------------- /processors/streaming.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "io" 5 | ) 6 | 7 | type StreamingProcessor interface { 8 | Processor 9 | 10 | TransformStream(reader io.Reader, writer io.Writer, opts ...Flag) error 11 | 12 | CanStream() bool 13 | 14 | PreferStream() bool 15 | } 16 | 17 | type StreamingCapable interface { 18 | CanStream() bool 19 | } 20 | 21 | type DefaultStreamingProcessor struct{} 22 | 23 | func (d DefaultStreamingProcessor) CanStream() bool { 24 | return false 25 | } 26 | 27 | func (d DefaultStreamingProcessor) PreferStream() bool { 28 | return false 29 | } 30 | 31 | func (d DefaultStreamingProcessor) TransformStream(reader io.Reader, writer io.Writer, opts ...Flag) error { 32 | data, err := io.ReadAll(reader) 33 | if err != nil { 34 | return err 35 | } 36 | 37 | result, err := d.Transform(data, opts...) 38 | if err != nil { 39 | return err 40 | } 41 | 42 | _, err = writer.Write([]byte(result)) 43 | return err 44 | } 45 | func (d DefaultStreamingProcessor) Transform(data []byte, opts ...Flag) (string, error) { 46 | return string(data), nil 47 | } 48 | 49 | func (d DefaultStreamingProcessor) Name() string { return "default" } 50 | func (d DefaultStreamingProcessor) Alias() []string { return nil } 51 | func (d DefaultStreamingProcessor) Flags() []Flag { return nil } 52 | func (d DefaultStreamingProcessor) Title() string { return "Default" } 53 | func (d DefaultStreamingProcessor) Description() string { return "Default processor" } 54 | func (d DefaultStreamingProcessor) FilterValue() string { return "Default" } 55 | -------------------------------------------------------------------------------- /processors/html.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "fmt" 5 | "html" 6 | ) 7 | 8 | // HTMLEncode escapes string to HTML 9 | type HTMLEncode struct{} 10 | 11 | func (p HTMLEncode) Name() string { 12 | return "html-encode" 13 | } 14 | 15 | func (p HTMLEncode) Alias() []string { 16 | return []string{"html-enc", "html-escape"} 17 | } 18 | 19 | func (p HTMLEncode) Transform(data []byte, _ ...Flag) (string, error) { 20 | return html.EscapeString(string(data)), nil 21 | } 22 | 23 | func (p HTMLEncode) Flags() []Flag { 24 | return nil 25 | } 26 | 27 | func (p HTMLEncode) Title() string { 28 | title := "HTML Encode" 29 | return fmt.Sprintf("%s (%s)", title, p.Name()) 30 | } 31 | 32 | func (p HTMLEncode) Description() string { 33 | return "Escape your HTML" 34 | } 35 | 36 | func (p HTMLEncode) FilterValue() string { 37 | return p.Title() 38 | } 39 | 40 | // HTMLDecode unescapes HTML to string 41 | type HTMLDecode struct{} 42 | 43 | func (p HTMLDecode) Name() string { 44 | return "html-decode" 45 | } 46 | 47 | func (p HTMLDecode) Alias() []string { 48 | return []string{"html-dec", "html-unescape"} 49 | } 50 | 51 | func (p HTMLDecode) Transform(data []byte, _ ...Flag) (string, error) { 52 | return html.UnescapeString(string(data)), nil 53 | } 54 | 55 | func (p HTMLDecode) Flags() []Flag { 56 | return nil 57 | } 58 | 59 | func (p HTMLDecode) Title() string { 60 | title := "HTML Decode" 61 | return fmt.Sprintf("%s (%s)", title, p.Name()) 62 | } 63 | 64 | func (p HTMLDecode) Description() string { 65 | return "Unescape your HTML" 66 | } 67 | 68 | func (p HTMLDecode) FilterValue() string { 69 | return p.Title() 70 | } 71 | -------------------------------------------------------------------------------- /processors/base32.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "encoding/base32" 5 | "fmt" 6 | ) 7 | 8 | // Base32Encoding encodes plain text to Base32 string. 9 | type Base32Encoding struct{} 10 | 11 | func (p Base32Encoding) Name() string { 12 | return "base32-encode" 13 | } 14 | 15 | func (p Base32Encoding) Alias() []string { 16 | return []string{"b32-enc", "b32-encode"} 17 | } 18 | 19 | func (p Base32Encoding) Transform(data []byte, _ ...Flag) (string, error) { 20 | return base32.StdEncoding.EncodeToString(data), nil 21 | } 22 | 23 | func (p Base32Encoding) Flags() []Flag { 24 | return nil 25 | } 26 | 27 | func (p Base32Encoding) Title() string { 28 | title := "Base32 Encoding" 29 | return fmt.Sprintf("%s (%s)", title, p.Name()) 30 | } 31 | 32 | func (p Base32Encoding) Description() string { 33 | return "Encode your text to Base32" 34 | } 35 | 36 | func (p Base32Encoding) FilterValue() string { 37 | return p.Title() 38 | } 39 | 40 | // Base32Decode decodes string from Base32 string to plain text. 41 | type Base32Decode struct{} 42 | 43 | func (p Base32Decode) Name() string { 44 | return "base32-decode" 45 | } 46 | 47 | func (p Base32Decode) Alias() []string { 48 | return []string{"b32-dec", "b32-decode"} 49 | } 50 | 51 | func (p Base32Decode) Transform(data []byte, _ ...Flag) (string, error) { 52 | decodedString, err := base32.StdEncoding.DecodeString(string(data)) 53 | return string(decodedString), err 54 | } 55 | 56 | func (p Base32Decode) Flags() []Flag { 57 | return nil 58 | } 59 | 60 | func (p Base32Decode) Title() string { 61 | title := "Base32 Decode" 62 | return fmt.Sprintf("%s (%s)", title, p.Name()) 63 | } 64 | 65 | func (p Base32Decode) Description() string { 66 | return "Decode your base32 text" 67 | } 68 | 69 | func (p Base32Decode) FilterValue() string { 70 | return p.Title() 71 | } 72 | -------------------------------------------------------------------------------- /processors/numberlines.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "fmt" 5 | "strconv" 6 | "strings" 7 | ) 8 | 9 | // NumberLines Prepends consecutive number to each line of input 10 | type NumberLines struct{} 11 | 12 | // Implement ConfigurableStreamingProcessor interface for line-by-line processing 13 | func (p NumberLines) GetStreamingConfig() StreamingConfig { 14 | return StreamingConfig{ 15 | ChunkSize: 64 * 1024, // 64KB chunks 16 | BufferOutput: true, // Need to count lines first 17 | LineByLine: false, // Need full input to calculate max digits 18 | } 19 | } 20 | 21 | func (p NumberLines) Name() string { 22 | return "number-lines" 23 | } 24 | 25 | func (p NumberLines) Alias() []string { 26 | return []string{"nl", "line-numbers", "line-number", "number-line", "numberlines", "numberline"} 27 | } 28 | 29 | func nonEmptyCount(strs []string) int { 30 | var count = 0 31 | for _, s := range strs { 32 | if s != "" { 33 | count++ 34 | } 35 | } 36 | return count 37 | } 38 | func (p NumberLines) Transform(data []byte, _ ...Flag) (string, error) { 39 | var s = string(data) 40 | var counter = 1 41 | var result = "" 42 | var lines = strings.Split(s, "\n") 43 | var nec = nonEmptyCount(lines) 44 | var maxDigits = len(strconv.Itoa(nec)) 45 | for _, line := range lines { 46 | if line != "" { 47 | line = fmt.Sprintf("%*d. %s", maxDigits, counter, line) 48 | counter++ 49 | } 50 | result += line + "\n" 51 | } 52 | result = strings.TrimSuffix(result, "\n") 53 | return result, nil 54 | } 55 | 56 | func (p NumberLines) Flags() []Flag { 57 | return nil 58 | } 59 | 60 | func (p NumberLines) Title() string { 61 | return "Line numberer" 62 | } 63 | 64 | func (p NumberLines) Description() string { 65 | return "Prepends consecutive number to each input line" 66 | } 67 | 68 | func (p NumberLines) FilterValue() string { 69 | return p.Title() 70 | } 71 | -------------------------------------------------------------------------------- /cmd/processor_slug.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(slugCmd) 16 | } 17 | 18 | var slugCmd = &cobra.Command{ 19 | Use: "slug [string]", 20 | Short: "Transform your text to slug-case", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Slug{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_camel.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(camelCmd) 16 | } 17 | 18 | var camelCmd = &cobra.Command{ 19 | Use: "camel [string]", 20 | Short: "Transform your text to camelCase", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Camel{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_kebab.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(kebabCmd) 16 | } 17 | 18 | var kebabCmd = &cobra.Command{ 19 | Use: "kebab [string]", 20 | Short: "Transform your text to kebab-case", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Kebab{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_lower.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(lowerCmd) 16 | } 17 | 18 | var lowerCmd = &cobra.Command{ 19 | Use: "lower [string]", 20 | Short: "Transform your text to lower case", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Lower{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_md5.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(md5Cmd) 16 | } 17 | 18 | var md5Cmd = &cobra.Command{ 19 | Use: "md5 [string]", 20 | Short: "Get the MD5 checksum of your text", 21 | Aliases: []string{"md5-sum"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.MD5{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_snake.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(snakeCmd) 16 | } 17 | 18 | var snakeCmd = &cobra.Command{ 19 | Use: "snake [string]", 20 | Short: "Transform your text to snake_case", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Snake{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_title.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(titleCmd) 16 | } 17 | 18 | var titleCmd = &cobra.Command{ 19 | Use: "title [string]", 20 | Short: "Transform your text to Title Case", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Title{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_upper.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(upperCmd) 16 | } 17 | 18 | var upperCmd = &cobra.Command{ 19 | Use: "upper [string]", 20 | Short: "Transform your text to UPPER CASE", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Upper{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_hex-rgb.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(hexRgbCmd) 16 | } 17 | 18 | var hexRgbCmd = &cobra.Command{ 19 | Use: "hex-rgb [string]", 20 | Short: "Convert a #hex-color code to RGB", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.HexToRGB{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_pascal.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(pascalCmd) 16 | } 17 | 18 | var pascalCmd = &cobra.Command{ 19 | Use: "pascal [string]", 20 | Short: "Transform your text to PascalCase", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Pascal{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_reverse.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(reverseCmd) 16 | } 17 | 18 | var reverseCmd = &cobra.Command{ 19 | Use: "reverse [string]", 20 | Short: "Reverse Text ( txeT esreveR )", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Reverse{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_sha1.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(sha1Cmd) 16 | } 17 | 18 | var sha1Cmd = &cobra.Command{ 19 | Use: "sha1 [string]", 20 | Short: "Get the SHA-1 checksum of your text", 21 | Aliases: []string{"sha1-sum"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.SHA1{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/completion.go: -------------------------------------------------------------------------------- 1 | package cmd 2 | 3 | import ( 4 | "os" 5 | 6 | "github.com/spf13/cobra" 7 | ) 8 | 9 | func init() { 10 | rootCmd.AddCommand(completionCmd) 11 | } 12 | 13 | var completionCmd = &cobra.Command{ 14 | Use: "completion [bash|zsh|fish|powershell]", 15 | Short: "Generate completion script", 16 | Long: `To load completions: 17 | 18 | Bash: 19 | 20 | $ source <(sttr completion bash) 21 | 22 | # To load completions for each session, execute once: 23 | # Linux: 24 | $ sttr completion bash > /etc/bash_completion.d/sttr 25 | # macOS: 26 | $ sttr completion bash > /usr/local/etc/bash_completion.d/sttr 27 | 28 | Zsh: 29 | 30 | # If shell completion is not already enabled in your environment, 31 | # you will need to enable it. You can execute the following once: 32 | 33 | $ echo "autoload -U compinit; compinit" >> ~/.zshrc 34 | 35 | # To load completions for each session, execute once: 36 | # Generate a _sttr completion script and put it somewhere in your $fpath 37 | $ sttr completion zsh > /usr/local/share/zsh/site-functions/_sttr 38 | 39 | # You will need to start a new shell for this setup to take effect. 40 | 41 | fish: 42 | 43 | $ sttr completion fish | source 44 | 45 | # To load completions for each session, execute once: 46 | $ sttr completion fish > ~/.config/fish/completions/sttr.fish 47 | 48 | PowerShell: 49 | 50 | PS> sttr completion powershell | Out-String | Invoke-Expression 51 | 52 | # To load completions for every new session, run: 53 | PS> sttr completion powershell > sttr.ps1 54 | # and source this file from your PowerShell profile. 55 | `, 56 | DisableFlagsInUseLine: true, 57 | ValidArgs: []string{"bash", "zsh", "fish", "powershell"}, 58 | Args: cobra.ExactValidArgs(1), 59 | Run: func(cmd *cobra.Command, args []string) { 60 | switch args[0] { 61 | case "bash": 62 | cmd.Root().GenBashCompletion(os.Stdout) 63 | case "zsh": 64 | cmd.Root().GenZshCompletion(os.Stdout) 65 | case "fish": 66 | cmd.Root().GenFishCompletion(os.Stdout, true) 67 | case "powershell": 68 | cmd.Root().GenPowerShellCompletionWithDesc(os.Stdout) 69 | } 70 | }, 71 | } 72 | -------------------------------------------------------------------------------- /cmd/processor_unique-lines.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(uniqueLinesCmd) 16 | } 17 | 18 | var uniqueLinesCmd = &cobra.Command{ 19 | Use: "unique-lines [string]", 20 | Short: "Unique Lines", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.UniqueLines{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_json-escape.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(jsonEscapeCmd) 16 | } 17 | 18 | var jsonEscapeCmd = &cobra.Command{ 19 | Use: "json-escape [string]", 20 | Short: "JSON Escape", 21 | Aliases: []string{"json-esc"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.JSONEscape{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_reverse-lines.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(reverseLinesCmd) 16 | } 17 | 18 | var reverseLinesCmd = &cobra.Command{ 19 | Use: "reverse-lines [string]", 20 | Short: "Reverse Lines", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.ReverseLines{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_sort-lines.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(sortLinesCmd) 16 | } 17 | 18 | var sortLinesCmd = &cobra.Command{ 19 | Use: "sort-lines [string]", 20 | Short: "Sort lines alphabetically", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.SortLines{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_url-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(urlDecodeCmd) 16 | } 17 | 18 | var urlDecodeCmd = &cobra.Command{ 19 | Use: "url-decode [string]", 20 | Short: "Decode URL entities", 21 | Aliases: []string{"url-dec"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.URLDecode{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_url-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(urlEncodeCmd) 16 | } 17 | 18 | var urlEncodeCmd = &cobra.Command{ 19 | Use: "url-encode [string]", 20 | Short: "Encode URL entities", 21 | Aliases: []string{"url-enc"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.URLEncode{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /processors/ip.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "fmt" 5 | "net" 6 | "regexp" 7 | "strings" 8 | ) 9 | 10 | // ExtractIPs extracts ipv4 and ipv6 from string. 11 | type ExtractIPs struct{} 12 | 13 | func (p ExtractIPs) FilterValue() string { 14 | return p.Title() 15 | } 16 | 17 | func (p ExtractIPs) Name() string { 18 | return "extract-ip" 19 | } 20 | 21 | func (p ExtractIPs) Alias() []string { 22 | return []string{"find-ips", "find-ip", "extract-ips"} 23 | } 24 | 25 | func (p ExtractIPs) Transform(data []byte, _ ...Flag) (string, error) { 26 | var tempIps []string 27 | var validIps []string 28 | 29 | // Find all IPv4 30 | ipv4RegexString := regexp.MustCompile(`([0-9]{0,3}\.){3}[0-9]{0,3}`) 31 | ipv4 := ipv4RegexString.FindAllString(string(data), -1) 32 | 33 | // Find all IPv6 34 | ipv6RegexString := regexp.MustCompile(`(fe80:(:[0-9a-fA-F]{0,4}){0,4}%[0-9a-zA-Z]{1,}|([0-9a-fA-F]{1,4}:){1,2}(:[0-9a-fA-F]{1,4}){1,5}|([0-9a-fA-F]{1,4}:){1,3}(:[0-9a-fA-F]{1,4}){1,4}|[0-9a-fA-F]{1,4}:((:[0-9a-fA-F]{1,4}){1,6})|([0-9a-fA-F]{1,4}:){1,4}(:[0-9a-fA-F]{1,4}){1,3}|([0-9a-fA-F]{1,4}:){1,5}(:[0-9a-fA-F]{1,4}){1,2}|([0-9a-fA-F]{1,4}:){1,6}:[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,7}:|([0-9a-fA-F]{1,4}:){7,7}[0-9a-fA-F]{1,4}|([0-9a-fA-F]{1,4}:){1,4}:((25[0-5]|2[0-4][0-9]|1{0,1}[0-9]{0,1}[0-9])\.{3,3})(25[0-5]|2[0-4][0-9]|1{0,1}[0-9]{0,1}[0-9])|::(ffff(:0{1,4}){0,1}:){0,1}((25[0-5]|2[0-4][0-9]|1{0,1}[0-9]{0,1}[0-9])\.{3,3})(25[0-5]|2[0-4][0-9]|1{0,1}[0-9]{0,1}[0-9])|:((:[0-9a-fA-F]{1,4}){1,7}|:))`) 35 | ipv6 := ipv6RegexString.FindAllString(string(data), -1) 36 | 37 | tempIps = append(tempIps, ipv4...) 38 | tempIps = append(tempIps, ipv6...) 39 | 40 | for _, v := range tempIps { 41 | if ip := net.ParseIP(v); ip != nil { 42 | validIps = append(validIps, ip.String()) 43 | } 44 | } 45 | 46 | return strings.Join(validIps, "\n"), nil 47 | } 48 | 49 | func (p ExtractIPs) Flags() []Flag { 50 | return nil 51 | } 52 | 53 | func (p ExtractIPs) Title() string { 54 | title := "Extract IPs" 55 | return fmt.Sprintf("%s (%s)", title, p.Name()) 56 | } 57 | 58 | func (p ExtractIPs) Description() string { 59 | return "Extract IPv4 and IPv6 from your text" 60 | } 61 | -------------------------------------------------------------------------------- /cmd/processor_json-yaml.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(jsonYamlCmd) 16 | } 17 | 18 | var jsonYamlCmd = &cobra.Command{ 19 | Use: "json-yaml [string]", 20 | Short: "Convert JSON to YAML text", 21 | Aliases: []string{"json-yml"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.JSONToYAML{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_sha224.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(sha224Cmd) 16 | } 17 | 18 | var sha224Cmd = &cobra.Command{ 19 | Use: "sha224 [string]", 20 | Short: "Get the SHA-224 checksum of your text", 21 | Aliases: []string{"sha224-sum"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.SHA224{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_sha256.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(sha256Cmd) 16 | } 17 | 18 | var sha256Cmd = &cobra.Command{ 19 | Use: "sha256 [string]", 20 | Short: "Get the SHA-256 checksum of your text", 21 | Aliases: []string{"sha256-sum"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.SHA256{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_sha384.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(sha384Cmd) 16 | } 17 | 18 | var sha384Cmd = &cobra.Command{ 19 | Use: "sha384 [string]", 20 | Short: "Get the SHA-384 checksum of your text", 21 | Aliases: []string{"sha384-sum"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.SHA384{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_sha512.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(sha512Cmd) 16 | } 17 | 18 | var sha512Cmd = &cobra.Command{ 19 | Use: "sha512 [string]", 20 | Short: "Get the SHA-512 checksum of your text", 21 | Aliases: []string{"sha512-sum"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.SHA512{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_shuffle-lines.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(shuffleLinesCmd) 16 | } 17 | 18 | var shuffleLinesCmd = &cobra.Command{ 19 | Use: "shuffle-lines [string]", 20 | Short: "Shuffle lines randomly", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.ShuffleLines{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_count-lines.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(countLinesCmd) 16 | } 17 | 18 | var countLinesCmd = &cobra.Command{ 19 | Use: "count-lines [string]", 20 | Short: "Count the number of lines in your text", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.CountLines{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_count-words.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(countWordsCmd) 16 | } 17 | 18 | var countWordsCmd = &cobra.Command{ 19 | Use: "count-words [string]", 20 | Short: "Count the number of words in your text", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.CountWords{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_json-msgpack.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(jsonMsgpackCmd) 16 | } 17 | 18 | var jsonMsgpackCmd = &cobra.Command{ 19 | Use: "json-msgpack [string]", 20 | Short: "Convert JSON to MSGPACK text", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.JSONToMSGPACK{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_markdown-html.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(markdownHtmlCmd) 16 | } 17 | 18 | var markdownHtmlCmd = &cobra.Command{ 19 | Use: "markdown-html [string]", 20 | Short: "Convert Markdown to HTML", 21 | Aliases: []string{"md-html"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Markdown{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_msgpack-json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(msgpackJsonCmd) 16 | } 17 | 18 | var msgpackJsonCmd = &cobra.Command{ 19 | Use: "msgpack-json [string]", 20 | Short: "Convert MSGPACK to JSON text", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.MSGPACKToJSON{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_html-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(htmlEncodeCmd) 16 | } 17 | 18 | var htmlEncodeCmd = &cobra.Command{ 19 | Use: "html-encode [string]", 20 | Short: "Escape your HTML", 21 | Aliases: []string{"html-enc", "html-escape"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.HTMLEncode{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_xxh-32.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(xxh32Cmd) 16 | } 17 | 18 | var xxh32Cmd = &cobra.Command{ 19 | Use: "xxh-32 [string]", 20 | Short: "Get the XXH32 checksum of your text", 21 | Aliases: []string{"xxh32", "xxhash32", "xxhash-32"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.XXH32{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_xxh-64.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(xxh64Cmd) 16 | } 17 | 18 | var xxh64Cmd = &cobra.Command{ 19 | Use: "xxh-64 [string]", 20 | Short: "Get the XXH64 checksum of your text", 21 | Aliases: []string{"xxh64", "xxhash64", "xxhash-64"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.XXH64{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_blake2s.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(blake2SCmd) 16 | } 17 | 18 | var blake2SCmd = &cobra.Command{ 19 | Use: "blake2s [string]", 20 | Short: "Get the BLAKE2s hash of your text", 21 | Aliases: []string{"blake2s-hash", "blake2s-sum"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.BLAKE2s{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_hex-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(hexEncodeCmd) 16 | } 17 | 18 | var hexEncodeCmd = &cobra.Command{ 19 | Use: "hex-encode [string]", 20 | Short: "Encode your text Hex", 21 | Aliases: []string{"hex-enc", "hexadecimal-encode"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.HexEncode{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_html-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(htmlDecodeCmd) 16 | } 17 | 18 | var htmlDecodeCmd = &cobra.Command{ 19 | Use: "html-decode [string]", 20 | Short: "Unescape your HTML", 21 | Aliases: []string{"html-dec", "html-unescape"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.HTMLDecode{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_adler32.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(adler32Cmd) 16 | } 17 | 18 | var adler32Cmd = &cobra.Command{ 19 | Use: "adler32 [string]", 20 | Short: "Get the Adler32 checksum of your text", 21 | Aliases: []string{"adler32-sum", "adler32-checksum"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Adler32{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_count-chars.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(countCharsCmd) 16 | } 17 | 18 | var countCharsCmd = &cobra.Command{ 19 | Use: "count-chars [string]", 20 | Short: "Find the length of your text (including spaces)", 21 | Aliases: []string{}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.CountCharacters{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_xxh-128.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(xxh128Cmd) 16 | } 17 | 18 | var xxh128Cmd = &cobra.Command{ 19 | Use: "xxh-128 [string]", 20 | Short: "Get the XXH128 checksum of your text", 21 | Aliases: []string{"xxh128", "xxhash128", "xxhash-128"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.XXH128{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_base32-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(base32DecodeCmd) 16 | } 17 | 18 | var base32DecodeCmd = &cobra.Command{ 19 | Use: "base32-decode [string]", 20 | Short: "Decode your base32 text", 21 | Aliases: []string{"b32-dec", "b32-decode"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Base32Decode{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_base62-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(base62DecodeCmd) 16 | } 17 | 18 | var base62DecodeCmd = &cobra.Command{ 19 | Use: "base62-decode [string]", 20 | Short: "Decode your Base62 text", 21 | Aliases: []string{"b62-dec", "b62-decode"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Base62Decode{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_extract-url.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(extractUrlCmd) 16 | } 17 | 18 | var extractUrlCmd = &cobra.Command{ 19 | Use: "extract-url [string]", 20 | Short: "Extract URLs from text", 21 | Aliases: []string{"url-ext", "extract-urls", "ext-url"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.ExtractURLs{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_hex-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(hexDecodeCmd) 16 | } 17 | 18 | var hexDecodeCmd = &cobra.Command{ 19 | Use: "hex-decode [string]", 20 | Short: "Convert Hexadecimal to String", 21 | Aliases: []string{"hex-dec", "hexadecimal-decode"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.HexDecode{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_rot13.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(rot13Cmd) 16 | } 17 | 18 | var rot13Cmd = &cobra.Command{ 19 | Use: "rot13 [string]", 20 | Short: "Cipher/Decipher your text with ROT13 letter substitution", 21 | Aliases: []string{"rot13-encode", "rot13-enc"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.ROT13{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_base32-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(base32EncodeCmd) 16 | } 17 | 18 | var base32EncodeCmd = &cobra.Command{ 19 | Use: "base32-encode [string]", 20 | Short: "Encode your text to Base32", 21 | Aliases: []string{"b32-enc", "b32-encode"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.Base32Encoding{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_extract-ip.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(extractIpCmd) 16 | } 17 | 18 | var extractIpCmd = &cobra.Command{ 19 | Use: "extract-ip [string]", 20 | Short: "Extract IPv4 and IPv6 from your text", 21 | Aliases: []string{"find-ips", "find-ip", "extract-ips"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.ExtractIPs{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /processors/base64url.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | ) 7 | 8 | // Base64URLEncode encodes plain text to Base64 URL string. 9 | type Base64URLEncode struct{} 10 | 11 | func (p Base64URLEncode) Name() string { 12 | return "base64url-encode" 13 | } 14 | 15 | func (p Base64URLEncode) Alias() []string { 16 | return []string{"b64url-enc", "b64url-encode"} 17 | } 18 | 19 | func (p Base64URLEncode) Transform(data []byte, f ...Flag) (string, error) { 20 | if checkBase64RawFlag(f) { 21 | return base64.RawURLEncoding.EncodeToString(data), nil 22 | } 23 | return base64.URLEncoding.EncodeToString(data), nil 24 | } 25 | 26 | func (p Base64URLEncode) Flags() []Flag { 27 | return []Flag{base64RawFlag} 28 | } 29 | 30 | func (p Base64URLEncode) Title() string { 31 | title := "Base64URL Encoding" 32 | return fmt.Sprintf("%s (%s)", title, p.Name()) 33 | } 34 | 35 | func (p Base64URLEncode) Description() string { 36 | return "Encode your text to Base64 with URL Safe" 37 | } 38 | 39 | func (p Base64URLEncode) FilterValue() string { 40 | return p.Title() 41 | } 42 | 43 | // Base64URLDecode decodes Base64 URL string to plain text. 44 | type Base64URLDecode struct{} 45 | 46 | func (p Base64URLDecode) Name() string { 47 | return "base64url-decode" 48 | } 49 | 50 | func (p Base64URLDecode) Alias() []string { 51 | return []string{"b64url-dec", "b64url-decode"} 52 | } 53 | 54 | func (p Base64URLDecode) Transform(data []byte, f ...Flag) (string, error) { 55 | var decodedString []byte 56 | var err error 57 | if checkBase64RawFlag(f) { 58 | decodedString, err = base64.RawURLEncoding.DecodeString(string(data)) 59 | } else { 60 | decodedString, err = base64.URLEncoding.DecodeString(string(data)) 61 | } 62 | return string(decodedString), err 63 | } 64 | 65 | func (p Base64URLDecode) Flags() []Flag { 66 | return []Flag{base64RawFlag} 67 | } 68 | 69 | func (p Base64URLDecode) Title() string { 70 | title := "Base64URL Decode" 71 | return fmt.Sprintf("%s (%s)", title, p.Name()) 72 | } 73 | 74 | func (p Base64URLDecode) Description() string { 75 | return "Decode your Base64 text with URL Safe" 76 | } 77 | 78 | func (p Base64URLDecode) FilterValue() string { 79 | return p.Title() 80 | } 81 | -------------------------------------------------------------------------------- /cmd/processor_ascii85-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(ascii85EncodeCmd) 16 | } 17 | 18 | var ascii85EncodeCmd = &cobra.Command{ 19 | Use: "ascii85-encode [string]", 20 | Short: "Encode your text to Ascii85 ( Base85 )", 21 | Aliases: []string{"ascii85-encoding", "base85-encode", "b85-encode"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.ASCII85Encoding{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_ascii85-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(ascii85DecodeCmd) 16 | } 17 | 18 | var ascii85DecodeCmd = &cobra.Command{ 19 | Use: "ascii85-decode [string]", 20 | Short: "Decode your text to Ascii85 ( Base85 ) text", 21 | Aliases: []string{"ascii85-decoding", "base85-decode", "b85-decode"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.ASCII85Decoding{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_morse-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(morseEncodeCmd) 16 | } 17 | 18 | var morseEncodeCmd = &cobra.Command{ 19 | Use: "morse-encode [string]", 20 | Short: "Encode your text to Morse Code", 21 | Aliases: []string{"morse-enc", "morse-encode", "morse-code-encode", "morse-code-enc"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.MorseCodeEncode{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /processors/ascii85.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "bytes" 5 | "encoding/ascii85" 6 | "fmt" 7 | "io" 8 | ) 9 | 10 | // ASCII85Encoding encodes plain text to Ascii85 (aka Base85) 11 | type ASCII85Encoding struct{} 12 | 13 | func (p ASCII85Encoding) Name() string { 14 | return "ascii85-encode" 15 | } 16 | 17 | func (p ASCII85Encoding) Alias() []string { 18 | return []string{"ascii85-encoding", "base85-encode", "b85-encode"} 19 | } 20 | 21 | func (p ASCII85Encoding) Transform(data []byte, _ ...Flag) (string, error) { 22 | buf := &bytes.Buffer{} 23 | encoder := ascii85.NewEncoder(buf) 24 | _, err := encoder.Write(data) 25 | if err != nil { 26 | return "", err 27 | } 28 | if err := encoder.Close(); err != nil { 29 | return "", err 30 | } 31 | 32 | return buf.String(), nil 33 | } 34 | 35 | func (p ASCII85Encoding) Flags() []Flag { 36 | return nil 37 | } 38 | 39 | func (p ASCII85Encoding) Title() string { 40 | title := "Ascii85 / Base85 Encoding" 41 | return fmt.Sprintf("%s (%s)", title, p.Name()) 42 | } 43 | 44 | func (p ASCII85Encoding) Description() string { 45 | return "Encode your text to Ascii85 ( Base85 )" 46 | } 47 | 48 | func (p ASCII85Encoding) FilterValue() string { 49 | return p.Title() 50 | } 51 | 52 | // ASCII85Decoding decodes Ascii85 (aka Base85) to plain text. 53 | type ASCII85Decoding struct{} 54 | 55 | func (p ASCII85Decoding) Name() string { 56 | return "ascii85-decode" 57 | } 58 | 59 | func (p ASCII85Decoding) Alias() []string { 60 | return []string{"ascii85-decoding", "base85-decode", "b85-decode"} 61 | } 62 | 63 | func (p ASCII85Decoding) Transform(data []byte, _ ...Flag) (string, error) { 64 | decoder := ascii85.NewDecoder(bytes.NewReader(data)) 65 | buf, err := io.ReadAll(decoder) 66 | if err != nil { 67 | return "", err 68 | } 69 | 70 | return string(buf), nil 71 | } 72 | 73 | func (p ASCII85Decoding) Flags() []Flag { 74 | return nil 75 | } 76 | 77 | func (p ASCII85Decoding) Title() string { 78 | title := "Ascii85 / Base85 Decoding" 79 | return fmt.Sprintf("%s (%s)", title, p.Name()) 80 | } 81 | 82 | func (p ASCII85Decoding) Description() string { 83 | return "Decode your text to Ascii85 ( Base85 ) text" 84 | } 85 | 86 | func (p ASCII85Decoding) FilterValue() string { 87 | return p.Title() 88 | } 89 | -------------------------------------------------------------------------------- /cmd/processor_number-lines.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | func init() { 15 | rootCmd.AddCommand(numberLinesCmd) 16 | } 17 | 18 | var numberLinesCmd = &cobra.Command{ 19 | Use: "number-lines [string]", 20 | Short: "Prepends consecutive number to each input line", 21 | Aliases: []string{"nl", "line-numbers", "line-number", "number-line", "numberlines", "numberline"}, 22 | Args: cobra.MaximumNArgs(1), 23 | RunE: func(cmd *cobra.Command, args []string) error { 24 | var err error 25 | var out string 26 | 27 | flags := make([]processors.Flag, 0) 28 | p := processors.NumberLines{} 29 | 30 | if len(args) == 0 { 31 | // Handle stdin/interactive input 32 | in := []byte(utils.ReadMultilineInput()) 33 | out, err = p.Transform(in, flags...) 34 | if err != nil { 35 | return err 36 | } 37 | } else { 38 | // Check if it's a file 39 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 40 | // It's a file - check if we should use streaming 41 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 42 | 43 | // Use central streaming function for all processors 44 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 45 | // Use streaming 46 | file, err := os.Open(args[0]) 47 | if err != nil { 48 | return err 49 | } 50 | defer file.Close() 51 | 52 | err = processors.TransformStream(p, file, os.Stdout, flags...) 53 | return err 54 | } else { 55 | // Use traditional method for small files 56 | d, err := os.ReadFile(args[0]) 57 | if err != nil { 58 | return err 59 | } 60 | out, err = p.Transform(d, flags...) 61 | if err != nil { 62 | return err 63 | } 64 | } 65 | } else { 66 | // Not a file, treat as string input 67 | out, err = p.Transform([]byte(args[0]), flags...) 68 | if err != nil { 69 | return err 70 | } 71 | } 72 | } 73 | 74 | _, err = fmt.Fprint(os.Stdout, out) 75 | return err 76 | }, 77 | } 78 | -------------------------------------------------------------------------------- /cmd/processor_json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var json_flag_i bool 15 | 16 | func init() { 17 | jsonCmd.Flags().BoolVarP(&json_flag_i, "indent", "i", false, "Indent the output (prettyprint)") 18 | rootCmd.AddCommand(jsonCmd) 19 | } 20 | 21 | var jsonCmd = &cobra.Command{ 22 | Use: "json [string]", 23 | Short: "Format your text as JSON ( json decode )", 24 | Aliases: []string{}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.FormatJSON{} 32 | flags = append(flags, processors.Flag{Short: "i", Value: json_flag_i}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_bcrypt.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var bcrypt_flag_r uint 15 | 16 | func init() { 17 | bcryptCmd.Flags().UintVarP(&bcrypt_flag_r, "number-of-rounds", "r", 10, "Number of rounds") 18 | rootCmd.AddCommand(bcryptCmd) 19 | } 20 | 21 | var bcryptCmd = &cobra.Command{ 22 | Use: "bcrypt [string]", 23 | Short: "Get the bcrypt hash of your text", 24 | Aliases: []string{"bcrypt-hash"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.Bcrypt{} 32 | flags = append(flags, processors.Flag{Short: "r", Value: bcrypt_flag_r}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_blake2b.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var blake2B_flag_s uint 15 | 16 | func init() { 17 | blake2BCmd.Flags().UintVarP(&blake2B_flag_s, "size", "s", 64, "Hash size in bytes (1-64)") 18 | rootCmd.AddCommand(blake2BCmd) 19 | } 20 | 21 | var blake2BCmd = &cobra.Command{ 22 | Use: "blake2b [string]", 23 | Short: "Get the BLAKE2b hash of your text", 24 | Aliases: []string{"blake2b-hash", "blake2b-sum"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.BLAKE2b{} 32 | flags = append(flags, processors.Flag{Short: "s", Value: blake2B_flag_s}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_yaml-json.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var yamlJson_flag_i bool 15 | 16 | func init() { 17 | yamlJsonCmd.Flags().BoolVarP(&yamlJson_flag_i, "indent", "i", false, "Indent the output (prettyprint)") 18 | rootCmd.AddCommand(yamlJsonCmd) 19 | } 20 | 21 | var yamlJsonCmd = &cobra.Command{ 22 | Use: "yaml-json [string]", 23 | Short: "Convert YAML to JSON text", 24 | Aliases: []string{"yml-json"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.YAMLToJSON{} 32 | flags = append(flags, processors.Flag{Short: "i", Value: yamlJson_flag_i}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /go.mod: -------------------------------------------------------------------------------- 1 | module github.com/abhimanyu003/sttr 2 | 3 | go 1.24.5 4 | 5 | require ( 6 | github.com/cespare/xxhash/v2 v2.3.0 7 | github.com/charmbracelet/bubbles v0.21.0 8 | github.com/charmbracelet/bubbletea v1.3.9 9 | github.com/charmbracelet/lipgloss v1.1.0 10 | github.com/ghodss/yaml v1.0.0 11 | github.com/iancoleman/strcase v0.3.0 12 | github.com/lucasb-eyer/go-colorful v1.3.0 13 | github.com/mcnijman/go-emailaddress v1.1.1 14 | github.com/spf13/cobra v1.9.1 15 | github.com/vmihailenco/msgpack/v5 v5.4.1 16 | github.com/yuin/goldmark v1.7.13 17 | gitlab.com/abhimanyusharma003/go-ordered-json v0.0.0-20200508150302-7ef32eef8ead 18 | golang.org/x/crypto v0.42.0 19 | golang.org/x/term v0.35.0 20 | mvdan.cc/xurls/v2 v2.6.0 21 | ) 22 | 23 | require ( 24 | github.com/atotto/clipboard v0.1.4 // indirect 25 | github.com/aymanbagabas/go-osc52/v2 v2.0.1 // indirect 26 | github.com/charmbracelet/colorprofile v0.3.2 // indirect 27 | github.com/charmbracelet/x/ansi v0.10.1 // indirect 28 | github.com/charmbracelet/x/cellbuf v0.0.13 // indirect 29 | github.com/charmbracelet/x/term v0.2.1 // indirect 30 | github.com/cpuguy83/go-md2man/v2 v2.0.7 // indirect 31 | github.com/erikgeiser/coninput v0.0.0-20211004153227-1c3628e74d0f // indirect 32 | github.com/harsh16coder/xxhash v1.0.1 // indirect 33 | github.com/inconshreveable/mousetrap v1.1.0 // indirect 34 | github.com/klauspost/cpuid/v2 v2.0.9 // indirect 35 | github.com/mattn/go-isatty v0.0.20 // indirect 36 | github.com/mattn/go-localereader v0.0.1 // indirect 37 | github.com/mattn/go-runewidth v0.0.16 // indirect 38 | github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect 39 | github.com/muesli/cancelreader v0.2.2 // indirect 40 | github.com/muesli/termenv v0.16.0 // indirect 41 | github.com/rivo/uniseg v0.4.7 // indirect 42 | github.com/russross/blackfriday/v2 v2.1.0 // indirect 43 | github.com/sahilm/fuzzy v0.1.1 // indirect 44 | github.com/spf13/pflag v1.0.7 // indirect 45 | github.com/stretchr/testify v1.11.0 // indirect 46 | github.com/vmihailenco/tagparser/v2 v2.0.0 // indirect 47 | github.com/xo/terminfo v0.0.0-20220910002029-abceb7e1c41e // indirect 48 | github.com/zeebo/xxh3 v1.0.2 // indirect 49 | golang.org/x/net v0.43.0 // indirect 50 | golang.org/x/sys v0.36.0 // indirect 51 | golang.org/x/text v0.29.0 // indirect 52 | gopkg.in/yaml.v2 v2.4.0 // indirect 53 | gopkg.in/yaml.v3 v3.0.1 // indirect 54 | ) 55 | -------------------------------------------------------------------------------- /processors/hex.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "encoding/hex" 5 | "fmt" 6 | ) 7 | 8 | // HexEncode encodes string to hexadecimal 9 | type HexEncode struct{} 10 | 11 | // Implement ConfigurableStreamingProcessor interface for chunked processing 12 | func (p HexEncode) GetStreamingConfig() StreamingConfig { 13 | return StreamingConfig{ 14 | ChunkSize: 64 * 1024, // 64KB chunks 15 | BufferOutput: false, // Can encode chunks directly 16 | LineByLine: false, 17 | } 18 | } 19 | 20 | func (p HexEncode) Name() string { 21 | return "hex-encode" 22 | } 23 | 24 | func (p HexEncode) Alias() []string { 25 | return []string{"hex-enc", "hexadecimal-encode"} 26 | } 27 | 28 | func (p HexEncode) Transform(data []byte, _ ...Flag) (string, error) { 29 | return hex.EncodeToString(data), nil 30 | } 31 | 32 | func (p HexEncode) Flags() []Flag { 33 | return nil 34 | } 35 | 36 | func (p HexEncode) Title() string { 37 | title := "Hex Encode" 38 | return fmt.Sprintf("%s (%s)", title, p.Name()) 39 | } 40 | 41 | func (p HexEncode) Description() string { 42 | return "Encode your text Hex" 43 | } 44 | 45 | func (p HexEncode) FilterValue() string { 46 | return p.Title() 47 | } 48 | 49 | // HexDecode decodes hexadecimal to string 50 | type HexDecode struct{} 51 | 52 | // Implement ConfigurableStreamingProcessor interface for buffered processing 53 | func (p HexDecode) GetStreamingConfig() StreamingConfig { 54 | return StreamingConfig{ 55 | ChunkSize: 64 * 1024, // 64KB chunks 56 | BufferOutput: true, // Hex decoding needs complete input 57 | LineByLine: false, 58 | } 59 | } 60 | 61 | func (p HexDecode) Name() string { 62 | return "hex-decode" 63 | } 64 | 65 | func (p HexDecode) Alias() []string { 66 | return []string{"hex-dec", "hexadecimal-decode"} 67 | } 68 | 69 | func (p HexDecode) Transform(data []byte, _ ...Flag) (string, error) { 70 | output, err := hex.DecodeString(string(data)) 71 | 72 | if err != nil { 73 | return "", err 74 | } 75 | return string(output), nil 76 | } 77 | 78 | func (p HexDecode) Flags() []Flag { 79 | return nil 80 | } 81 | 82 | func (p HexDecode) Title() string { 83 | title := "Hex Decode" 84 | return fmt.Sprintf("%s (%s)", title, p.Name()) 85 | } 86 | 87 | func (p HexDecode) Description() string { 88 | return "Convert Hexadecimal to String" 89 | } 90 | 91 | func (p HexDecode) FilterValue() string { 92 | return p.Title() 93 | } 94 | -------------------------------------------------------------------------------- /cmd/processor_crc32.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var crc32_flag_p string 15 | 16 | func init() { 17 | crc32Cmd.Flags().StringVarP(&crc32_flag_p, "polynomial", "p", "ieee", "CRC32 polynomial (ieee, castagnoli, koopman)") 18 | rootCmd.AddCommand(crc32Cmd) 19 | } 20 | 21 | var crc32Cmd = &cobra.Command{ 22 | Use: "crc32 [string]", 23 | Short: "Get the CRC32 checksum of your text", 24 | Aliases: []string{"crc32-sum", "crc32-checksum"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.CRC32{} 32 | flags = append(flags, processors.Flag{Short: "p", Value: crc32_flag_p}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_json-unescape.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var jsonUnescape_flag_i bool 15 | 16 | func init() { 17 | jsonUnescapeCmd.Flags().BoolVarP(&jsonUnescape_flag_i, "indent", "i", false, "Indent the output (prettyprint)") 18 | rootCmd.AddCommand(jsonUnescapeCmd) 19 | } 20 | 21 | var jsonUnescapeCmd = &cobra.Command{ 22 | Use: "json-unescape [string]", 23 | Short: "JSON Unescape", 24 | Aliases: []string{"json-unesc"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.JSONUnescape{} 32 | flags = append(flags, processors.Flag{Short: "i", Value: jsonUnescape_flag_i}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_base64-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var base64Decode_flag_r bool 15 | 16 | func init() { 17 | base64DecodeCmd.Flags().BoolVarP(&base64Decode_flag_r, "raw", "r", false, "unpadded base64 encoding") 18 | rootCmd.AddCommand(base64DecodeCmd) 19 | } 20 | 21 | var base64DecodeCmd = &cobra.Command{ 22 | Use: "base64-decode [string]", 23 | Short: "Decode your Base64 text", 24 | Aliases: []string{"b64-dec", "b64-decode"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.Base64Decode{} 32 | flags = append(flags, processors.Flag{Short: "r", Value: base64Decode_flag_r}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_base64-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var base64Encode_flag_r bool 15 | 16 | func init() { 17 | base64EncodeCmd.Flags().BoolVarP(&base64Encode_flag_r, "raw", "r", false, "unpadded base64 encoding") 18 | rootCmd.AddCommand(base64EncodeCmd) 19 | } 20 | 21 | var base64EncodeCmd = &cobra.Command{ 22 | Use: "base64-encode [string]", 23 | Short: "Encode your text to Base64", 24 | Aliases: []string{"b64-enc", "b64-encode"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.Base64Encode{} 32 | flags = append(flags, processors.Flag{Short: "r", Value: base64Encode_flag_r}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_base62-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var base62Encode_flag_p string 15 | 16 | func init() { 17 | base62EncodeCmd.Flags().StringVarP(&base62Encode_flag_p, "prefix", "p", "", "Add prefix to encoded string") 18 | rootCmd.AddCommand(base62EncodeCmd) 19 | } 20 | 21 | var base62EncodeCmd = &cobra.Command{ 22 | Use: "base62-encode [string]", 23 | Short: "Encode your text to Base62", 24 | Aliases: []string{"b62-enc", "b62-encode"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.Base62Encode{} 32 | flags = append(flags, processors.Flag{Short: "p", Value: base62Encode_flag_p}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /processors/rgb_test.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestRGB_Command(t *testing.T) { 9 | test := struct { 10 | alias []string 11 | description string 12 | filterValue string 13 | flags []Flag 14 | name string 15 | title string 16 | }{ 17 | //alias: []string{}, 18 | description: "Convert a #hex-color code to RGB", 19 | filterValue: "Hex To RGB (hex-rgb)", 20 | flags: nil, 21 | name: "hex-rgb", 22 | title: "Hex To RGB (hex-rgb)", 23 | } 24 | p := HexToRGB{} 25 | if got := p.Alias(); !reflect.DeepEqual(got, test.alias) { 26 | t.Errorf("Alias() = %v, want %v", got, test.alias) 27 | } 28 | if got := p.Description(); got != test.description { 29 | t.Errorf("Description() = %v, want %v", got, test.description) 30 | } 31 | if got := p.FilterValue(); got != test.filterValue { 32 | t.Errorf("FilterValue() = %v, want %v", got, test.filterValue) 33 | } 34 | if got := p.Flags(); !reflect.DeepEqual(got, test.flags) { 35 | t.Errorf("Flags() = %v, want %v", got, test.flags) 36 | } 37 | if got := p.Name(); got != test.name { 38 | t.Errorf("Name() = %v, want %v", got, test.name) 39 | } 40 | if got := p.Title(); got != test.title { 41 | t.Errorf("Title() = %v, want %v", got, test.title) 42 | } 43 | } 44 | 45 | func TestHexToRGB_Transform(t *testing.T) { 46 | type args struct { 47 | data []byte 48 | in1 []Flag 49 | } 50 | tests := []struct { 51 | name string 52 | args args 53 | want string 54 | wantErr bool 55 | }{ 56 | { 57 | name: "Hex with # string", 58 | args: args{data: []byte("#FF5733")}, 59 | want: "255, 87, 51", 60 | }, 61 | { 62 | name: "HEX string with wrong string", 63 | args: args{data: []byte("#PPPPP")}, 64 | want: "0, 0, 0", 65 | wantErr: true, 66 | }, 67 | { 68 | name: "HEX string with wrong string", 69 | args: args{data: []byte("FF5733")}, 70 | want: "0, 0, 0", 71 | wantErr: true, 72 | }, 73 | } 74 | for _, tt := range tests { 75 | t.Run(tt.name, func(t *testing.T) { 76 | p := HexToRGB{} 77 | got, err := p.Transform(tt.args.data, tt.args.in1...) 78 | if (err != nil) != tt.wantErr { 79 | t.Errorf("Transform() error = %v, wantErr %v", err, tt.wantErr) 80 | return 81 | } 82 | if got != tt.want { 83 | t.Errorf("Transform() got = %v, want %v", got, tt.want) 84 | } 85 | }) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /cmd/processor_base58-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var base58Encode_flag_c bool 15 | 16 | func init() { 17 | base58EncodeCmd.Flags().BoolVarP(&base58Encode_flag_c, "check", "c", false, "Use Base58Check encoding (with checksum)") 18 | rootCmd.AddCommand(base58EncodeCmd) 19 | } 20 | 21 | var base58EncodeCmd = &cobra.Command{ 22 | Use: "base58-encode [string]", 23 | Short: "Encode your text to Base58", 24 | Aliases: []string{"b58-enc", "b58-encode"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.Base58Encode{} 32 | flags = append(flags, processors.Flag{Short: "c", Value: base58Encode_flag_c}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_base58-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var base58Decode_flag_c bool 15 | 16 | func init() { 17 | base58DecodeCmd.Flags().BoolVarP(&base58Decode_flag_c, "check", "c", false, "Use Base58Check decoding (with checksum verification)") 18 | rootCmd.AddCommand(base58DecodeCmd) 19 | } 20 | 21 | var base58DecodeCmd = &cobra.Command{ 22 | Use: "base58-decode [string]", 23 | Short: "Decode your Base58 text", 24 | Aliases: []string{"b58-dec", "b58-decode"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.Base58Decode{} 32 | flags = append(flags, processors.Flag{Short: "c", Value: base58Decode_flag_c}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_remove-spaces.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var removeSpaces_flag_s string 15 | 16 | func init() { 17 | removeSpacesCmd.Flags().StringVarP(&removeSpaces_flag_s, "separator", "s", "", "Separator to split spaces") 18 | rootCmd.AddCommand(removeSpacesCmd) 19 | } 20 | 21 | var removeSpacesCmd = &cobra.Command{ 22 | Use: "remove-spaces [string]", 23 | Short: "Remove all spaces + new lines", 24 | Aliases: []string{"remove-space", "trim-spaces", "trim-space"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.RemoveSpaces{} 32 | flags = append(flags, processors.Flag{Short: "s", Value: removeSpaces_flag_s}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /processors/markdown_test.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestMarkdown_Command(t *testing.T) { 9 | test := struct { 10 | alias []string 11 | description string 12 | filterValue string 13 | flags []Flag 14 | name string 15 | title string 16 | }{ 17 | alias: []string{"md-html"}, 18 | description: "Convert Markdown to HTML", 19 | filterValue: "Markdown to HTML (markdown-html)", 20 | flags: nil, 21 | name: "markdown-html", 22 | title: "Markdown to HTML (markdown-html)", 23 | } 24 | p := Markdown{} 25 | if got := p.Alias(); !reflect.DeepEqual(got, test.alias) { 26 | t.Errorf("Alias() = %v, want %v", got, test.alias) 27 | } 28 | if got := p.Description(); got != test.description { 29 | t.Errorf("Description() = %v, want %v", got, test.description) 30 | } 31 | if got := p.FilterValue(); got != test.filterValue { 32 | t.Errorf("FilterValue() = %v, want %v", got, test.filterValue) 33 | } 34 | if got := p.Flags(); !reflect.DeepEqual(got, test.flags) { 35 | t.Errorf("Flags() = %v, want %v", got, test.flags) 36 | } 37 | if got := p.Name(); got != test.name { 38 | t.Errorf("Name() = %v, want %v", got, test.name) 39 | } 40 | if got := p.Title(); got != test.title { 41 | t.Errorf("Title() = %v, want %v", got, test.title) 42 | } 43 | } 44 | 45 | func TestMarkdown_Transform(t *testing.T) { 46 | type args struct { 47 | data []byte 48 | in1 []Flag 49 | } 50 | tests := []struct { 51 | name string 52 | args args 53 | want string 54 | wantErr bool 55 | }{ 56 | { 57 | name: "test empty string", 58 | args: args{data: []byte("")}, 59 | want: "", 60 | }, 61 | { 62 | name: "test H1", 63 | args: args{data: []byte("# H1")}, 64 | want: "

H1

\n", 65 | }, 66 | { 67 | name: "test bold", 68 | args: args{data: []byte("**the quick brown fox jumps over a lazy dog**")}, 69 | want: "

the quick brown fox jumps over a lazy dog

\n", 70 | }, 71 | } 72 | for _, tt := range tests { 73 | t.Run(tt.name, func(t *testing.T) { 74 | p := Markdown{} 75 | got, err := p.Transform(tt.args.data, tt.args.in1...) 76 | if (err != nil) != tt.wantErr { 77 | t.Errorf("Transform() error = %v, wantErr %v", err, tt.wantErr) 78 | return 79 | } 80 | if got != tt.want { 81 | t.Errorf("Transform() got = %v, want %v", got, tt.want) 82 | } 83 | }) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /cmd/processor_base64url-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var base64UrlDecode_flag_r bool 15 | 16 | func init() { 17 | base64UrlDecodeCmd.Flags().BoolVarP(&base64UrlDecode_flag_r, "raw", "r", false, "unpadded base64 encoding") 18 | rootCmd.AddCommand(base64UrlDecodeCmd) 19 | } 20 | 21 | var base64UrlDecodeCmd = &cobra.Command{ 22 | Use: "base64url-decode [string]", 23 | Short: "Decode your Base64 text with URL Safe", 24 | Aliases: []string{"b64url-dec", "b64url-decode"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.Base64URLDecode{} 32 | flags = append(flags, processors.Flag{Short: "r", Value: base64UrlDecode_flag_r}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_base64url-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var base64UrlEncode_flag_r bool 15 | 16 | func init() { 17 | base64UrlEncodeCmd.Flags().BoolVarP(&base64UrlEncode_flag_r, "raw", "r", false, "unpadded base64 encoding") 18 | rootCmd.AddCommand(base64UrlEncodeCmd) 19 | } 20 | 21 | var base64UrlEncodeCmd = &cobra.Command{ 22 | Use: "base64url-encode [string]", 23 | Short: "Encode your text to Base64 with URL Safe", 24 | Aliases: []string{"b64url-enc", "b64url-encode"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.Base64URLEncode{} 32 | flags = append(flags, processors.Flag{Short: "r", Value: base64UrlEncode_flag_r}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_extract-emails.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var extractEmails_flag_s string 15 | 16 | func init() { 17 | extractEmailsCmd.Flags().StringVarP(&extractEmails_flag_s, "separator", "s", "", "Separator to split multiple emails") 18 | rootCmd.AddCommand(extractEmailsCmd) 19 | } 20 | 21 | var extractEmailsCmd = &cobra.Command{ 22 | Use: "extract-emails [string]", 23 | Short: "Extract emails from given text", 24 | Aliases: []string{"find-emails", "find-email", "extract-email"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.ExtractEmails{} 32 | flags = append(flags, processors.Flag{Short: "s", Value: extractEmails_flag_s}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_remove-newlines.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var removeNewlines_flag_s string 15 | 16 | func init() { 17 | removeNewlinesCmd.Flags().StringVarP(&removeNewlines_flag_s, "separator", "s", "", "Separator to split multiple lines") 18 | rootCmd.AddCommand(removeNewlinesCmd) 19 | } 20 | 21 | var removeNewlinesCmd = &cobra.Command{ 22 | Use: "remove-newlines [string]", 23 | Short: "Remove all new lines", 24 | Aliases: []string{"remove-new-lines", "trim-newlines", "trim-new-lines"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.RemoveNewLines{} 32 | flags = append(flags, processors.Flag{Short: "s", Value: removeNewlines_flag_s}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_crockford-base32-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var crockfordBase32Decode_flag_v bool 15 | 16 | func init() { 17 | crockfordBase32DecodeCmd.Flags().BoolVarP(&crockfordBase32Decode_flag_v, "verify", "v", false, "Verify Crockford checksum") 18 | rootCmd.AddCommand(crockfordBase32DecodeCmd) 19 | } 20 | 21 | var crockfordBase32DecodeCmd = &cobra.Command{ 22 | Use: "crockford-base32-decode [string]", 23 | Short: "Decode your Crockford Base32 text", 24 | Aliases: []string{"crockford-b32-dec", "cb32-decode"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.CrockfordBase32Decode{} 32 | flags = append(flags, processors.Flag{Short: "v", Value: crockfordBase32Decode_flag_v}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /processors/checksums.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "fmt" 5 | "hash/adler32" 6 | "hash/crc32" 7 | ) 8 | 9 | // CRC32 generates CRC32 checksum 10 | type CRC32 struct{} 11 | 12 | func (p CRC32) Name() string { 13 | return "crc32" 14 | } 15 | 16 | func (p CRC32) Alias() []string { 17 | return []string{"crc32-sum", "crc32-checksum"} 18 | } 19 | 20 | func (p CRC32) Transform(data []byte, f ...Flag) (string, error) { 21 | var polynomial string = "ieee" 22 | for _, flag := range f { 23 | if flag.Short == "p" { 24 | if pol, ok := flag.Value.(string); ok { 25 | polynomial = pol 26 | } 27 | } 28 | } 29 | 30 | var table *crc32.Table 31 | switch polynomial { 32 | case "ieee": 33 | table = crc32.IEEETable 34 | case "castagnoli": 35 | table = crc32.MakeTable(crc32.Castagnoli) 36 | case "koopman": 37 | table = crc32.MakeTable(crc32.Koopman) 38 | default: 39 | return "", fmt.Errorf("unsupported polynomial: %s (supported: ieee, castagnoli, koopman)", polynomial) 40 | } 41 | 42 | checksum := crc32.Checksum(data, table) 43 | return fmt.Sprintf("%08x", checksum), nil 44 | } 45 | 46 | func (p CRC32) Flags() []Flag { 47 | return []Flag{ 48 | { 49 | Name: "polynomial", 50 | Short: "p", 51 | Desc: "CRC32 polynomial (ieee, castagnoli, koopman)", 52 | Value: "ieee", 53 | Type: FlagString, 54 | }, 55 | } 56 | } 57 | 58 | func (p CRC32) Title() string { 59 | return fmt.Sprintf("CRC32 Checksum (%s)", p.Name()) 60 | } 61 | 62 | func (p CRC32) Description() string { 63 | return "Get the CRC32 checksum of your text" 64 | } 65 | 66 | func (p CRC32) FilterValue() string { 67 | return p.Title() 68 | } 69 | 70 | // Adler32 generates Adler32 checksum 71 | type Adler32 struct{} 72 | 73 | func (p Adler32) Name() string { 74 | return "adler32" 75 | } 76 | 77 | func (p Adler32) Alias() []string { 78 | return []string{"adler32-sum", "adler32-checksum"} 79 | } 80 | 81 | func (p Adler32) Transform(data []byte, _ ...Flag) (string, error) { 82 | checksum := adler32.Checksum(data) 83 | return fmt.Sprintf("%08x", checksum), nil 84 | } 85 | 86 | func (p Adler32) Flags() []Flag { 87 | return nil 88 | } 89 | 90 | func (p Adler32) Title() string { 91 | return fmt.Sprintf("Adler32 Checksum (%s)", p.Name()) 92 | } 93 | 94 | func (p Adler32) Description() string { 95 | return "Get the Adler32 checksum of your text" 96 | } 97 | 98 | func (p Adler32) FilterValue() string { 99 | return p.Title() 100 | } 101 | -------------------------------------------------------------------------------- /cmd/processor_crockford-base32-encode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var crockfordBase32Encode_flag_c bool 15 | 16 | func init() { 17 | crockfordBase32EncodeCmd.Flags().BoolVarP(&crockfordBase32Encode_flag_c, "checksum", "c", false, "Add Crockford checksum") 18 | rootCmd.AddCommand(crockfordBase32EncodeCmd) 19 | } 20 | 21 | var crockfordBase32EncodeCmd = &cobra.Command{ 22 | Use: "crockford-base32-encode [string]", 23 | Short: "Encode your text to Crockford Base32", 24 | Aliases: []string{"crockford-b32-enc", "cb32-encode"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.CrockfordBase32Encode{} 32 | flags = append(flags, processors.Flag{Short: "c", Value: crockfordBase32Encode_flag_c}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_morse-decode.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var morseDecode_flag_l string 15 | 16 | func init() { 17 | morseDecodeCmd.Flags().StringVarP(&morseDecode_flag_l, "lang", "l", "la", "Morse code set to decode [la(Latin), ru(Cyrillic), gr(Greek), he(Hebrew), ar(Arabic), ja(Japanese), kr(Korean), th(Thai)]") 18 | rootCmd.AddCommand(morseDecodeCmd) 19 | } 20 | 21 | var morseDecodeCmd = &cobra.Command{ 22 | Use: "morse-decode [string]", 23 | Short: "Decode Morse Code to text", 24 | Aliases: []string{"morse-dec", "morse-decode", "morse-code-decode", "morse-code-dec"}, 25 | Args: cobra.MaximumNArgs(1), 26 | RunE: func(cmd *cobra.Command, args []string) error { 27 | var err error 28 | var out string 29 | 30 | flags := make([]processors.Flag, 0) 31 | p := processors.MorseCodeDecode{} 32 | flags = append(flags, processors.Flag{Short: "l", Value: morseDecode_flag_l}) 33 | 34 | if len(args) == 0 { 35 | // Handle stdin/interactive input 36 | in := []byte(utils.ReadMultilineInput()) 37 | out, err = p.Transform(in, flags...) 38 | if err != nil { 39 | return err 40 | } 41 | } else { 42 | // Check if it's a file 43 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 44 | // It's a file - check if we should use streaming 45 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 46 | 47 | // Use central streaming function for all processors 48 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 49 | // Use streaming 50 | file, err := os.Open(args[0]) 51 | if err != nil { 52 | return err 53 | } 54 | defer file.Close() 55 | 56 | err = processors.TransformStream(p, file, os.Stdout, flags...) 57 | return err 58 | } else { 59 | // Use traditional method for small files 60 | d, err := os.ReadFile(args[0]) 61 | if err != nil { 62 | return err 63 | } 64 | out, err = p.Transform(d, flags...) 65 | if err != nil { 66 | return err 67 | } 68 | } 69 | } else { 70 | // Not a file, treat as string input 71 | out, err = p.Transform([]byte(args[0]), flags...) 72 | if err != nil { 73 | return err 74 | } 75 | } 76 | } 77 | 78 | _, err = fmt.Fprint(os.Stdout, out) 79 | return err 80 | }, 81 | } 82 | -------------------------------------------------------------------------------- /cmd/processor_zeropad.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var ( 15 | zeropad_flag_n uint 16 | zeropad_flag_p string 17 | ) 18 | 19 | func init() { 20 | zeropadCmd.Flags().UintVarP(&zeropad_flag_n, "number-of-zeros", "n", 5, "Number of zeros to be padded") 21 | zeropadCmd.Flags().StringVarP(&zeropad_flag_p, "prefix", "p", "", "The number get prefixed with this") 22 | rootCmd.AddCommand(zeropadCmd) 23 | } 24 | 25 | var zeropadCmd = &cobra.Command{ 26 | Use: "zeropad [string]", 27 | Short: "Pad a number with zeros", 28 | Aliases: []string{}, 29 | Args: cobra.MaximumNArgs(1), 30 | RunE: func(cmd *cobra.Command, args []string) error { 31 | var err error 32 | var out string 33 | 34 | flags := make([]processors.Flag, 0) 35 | p := processors.Zeropad{} 36 | flags = append(flags, processors.Flag{Short: "n", Value: zeropad_flag_n}) 37 | flags = append(flags, processors.Flag{Short: "p", Value: zeropad_flag_p}) 38 | 39 | if len(args) == 0 { 40 | // Handle stdin/interactive input 41 | in := []byte(utils.ReadMultilineInput()) 42 | out, err = p.Transform(in, flags...) 43 | if err != nil { 44 | return err 45 | } 46 | } else { 47 | // Check if it's a file 48 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 49 | // It's a file - check if we should use streaming 50 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 51 | 52 | // Use central streaming function for all processors 53 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 54 | // Use streaming 55 | file, err := os.Open(args[0]) 56 | if err != nil { 57 | return err 58 | } 59 | defer file.Close() 60 | 61 | err = processors.TransformStream(p, file, os.Stdout, flags...) 62 | return err 63 | } else { 64 | // Use traditional method for small files 65 | d, err := os.ReadFile(args[0]) 66 | if err != nil { 67 | return err 68 | } 69 | out, err = p.Transform(d, flags...) 70 | if err != nil { 71 | return err 72 | } 73 | } 74 | } else { 75 | // Not a file, treat as string input 76 | out, err = p.Transform([]byte(args[0]), flags...) 77 | if err != nil { 78 | return err 79 | } 80 | } 81 | } 82 | 83 | _, err = fmt.Fprint(os.Stdout, out) 84 | return err 85 | }, 86 | } 87 | -------------------------------------------------------------------------------- /processors/ip_test.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestExtractIPs_Command(t *testing.T) { 9 | test := struct { 10 | alias []string 11 | description string 12 | filterValue string 13 | flags []Flag 14 | name string 15 | title string 16 | }{ 17 | alias: []string{"find-ips", "find-ip", "extract-ips"}, 18 | description: "Extract IPv4 and IPv6 from your text", 19 | filterValue: "Extract IPs (extract-ip)", 20 | flags: nil, 21 | name: "extract-ip", 22 | title: "Extract IPs (extract-ip)", 23 | } 24 | p := ExtractIPs{} 25 | if got := p.Alias(); !reflect.DeepEqual(got, test.alias) { 26 | t.Errorf("Alias() = %v, want %v", got, test.alias) 27 | } 28 | if got := p.Description(); got != test.description { 29 | t.Errorf("Description() = %v, want %v", got, test.description) 30 | } 31 | if got := p.FilterValue(); got != test.filterValue { 32 | t.Errorf("FilterValue() = %v, want %v", got, test.filterValue) 33 | } 34 | if got := p.Flags(); !reflect.DeepEqual(got, test.flags) { 35 | t.Errorf("Flags() = %v, want %v", got, test.flags) 36 | } 37 | if got := p.Name(); got != test.name { 38 | t.Errorf("Name() = %v, want %v", got, test.name) 39 | } 40 | if got := p.Title(); got != test.title { 41 | t.Errorf("Title() = %v, want %v", got, test.title) 42 | } 43 | } 44 | 45 | func TestExtractIPs_Transform(t *testing.T) { 46 | type args struct { 47 | data []byte 48 | in1 []Flag 49 | } 50 | tests := []struct { 51 | name string 52 | args args 53 | want string 54 | wantErr bool 55 | }{ 56 | { 57 | name: "Test for IPv6", 58 | args: args{data: []byte("Test for IPv4 185.141.205.123")}, 59 | want: "185.141.205.123", 60 | }, 61 | { 62 | name: "Test for IPv6", 63 | args: args{data: []byte("Test for IPv6 bb62:9bb8:46e2:640:e3a6:33b5:670a:a74")}, 64 | want: "bb62:9bb8:46e2:640:e3a6:33b5:670a:a74", 65 | }, 66 | { 67 | name: "Test for IPv4 and IPv6", 68 | args: args{data: []byte("IPv4 = 185.141.205.123 IPv6 = bb62:9bb8:46e2:640:e3a6:33b5:670a:a74")}, 69 | want: "185.141.205.123\nbb62:9bb8:46e2:640:e3a6:33b5:670a:a74", 70 | }, 71 | } 72 | for _, tt := range tests { 73 | t.Run(tt.name, func(t *testing.T) { 74 | p := ExtractIPs{} 75 | got, err := p.Transform(tt.args.data, tt.args.in1...) 76 | if (err != nil) != tt.wantErr { 77 | t.Errorf("Transform() error = %v, wantErr %v", err, tt.wantErr) 78 | return 79 | } 80 | if got != tt.want { 81 | t.Errorf("Transform() got = %v, want %v", got, tt.want) 82 | } 83 | }) 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /processors/base64.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "encoding/base64" 5 | "fmt" 6 | ) 7 | 8 | var base64RawFlag = Flag{ 9 | Name: "raw", 10 | Short: "r", 11 | Desc: "unpadded base64 encoding", 12 | Value: false, 13 | Type: FlagBool, 14 | } 15 | 16 | func checkBase64RawFlag(f []Flag) bool { 17 | raw := false 18 | for _, flag := range f { 19 | if flag.Name == "raw" || flag.Short == "r" { 20 | r, ok := flag.Value.(bool) 21 | if ok { 22 | raw = r 23 | } 24 | } 25 | } 26 | return raw 27 | } 28 | 29 | // Base64Encode encodes plain text to Base64 string. 30 | type Base64Encode struct{} 31 | 32 | func (p Base64Encode) Name() string { 33 | return "base64-encode" 34 | } 35 | 36 | func (p Base64Encode) Alias() []string { 37 | return []string{"b64-enc", "b64-encode"} 38 | } 39 | 40 | func (p Base64Encode) Transform(data []byte, f ...Flag) (string, error) { 41 | if checkBase64RawFlag(f) { 42 | return base64.RawStdEncoding.EncodeToString(data), nil 43 | } 44 | return base64.StdEncoding.EncodeToString(data), nil 45 | } 46 | 47 | func (p Base64Encode) Flags() []Flag { 48 | return []Flag{base64RawFlag} 49 | } 50 | 51 | func (p Base64Encode) Title() string { 52 | title := "Base64 Encoding" 53 | return fmt.Sprintf("%s (%s)", title, p.Name()) 54 | } 55 | 56 | func (p Base64Encode) Description() string { 57 | return "Encode your text to Base64" 58 | } 59 | 60 | func (p Base64Encode) FilterValue() string { 61 | return p.Title() 62 | } 63 | 64 | // Base64Decode decodes string from Base64 string to plain text. 65 | type Base64Decode struct{} 66 | 67 | func (p Base64Decode) Name() string { 68 | return "base64-decode" 69 | } 70 | 71 | func (p Base64Decode) Alias() []string { 72 | return []string{"b64-dec", "b64-decode"} 73 | } 74 | 75 | func (p Base64Decode) Transform(data []byte, f ...Flag) (string, error) { 76 | var decodedString []byte 77 | var err error 78 | if checkBase64RawFlag(f) { 79 | decodedString, err = base64.RawStdEncoding.DecodeString(string(data)) 80 | } else { 81 | decodedString, err = base64.StdEncoding.DecodeString(string(data)) 82 | } 83 | return string(decodedString), err 84 | } 85 | 86 | func (p Base64Decode) Flags() []Flag { 87 | return []Flag{base64RawFlag} 88 | } 89 | 90 | func (p Base64Decode) Title() string { 91 | title := "Base64 Decode" 92 | return fmt.Sprintf("%s (%s)", title, p.Name()) 93 | } 94 | 95 | func (p Base64Decode) Description() string { 96 | return "Decode your Base64 text" 97 | } 98 | 99 | func (p Base64Decode) FilterValue() string { 100 | return p.Title() 101 | } 102 | -------------------------------------------------------------------------------- /cmd/processor_escape-quotes.go: -------------------------------------------------------------------------------- 1 | // Code generated by github.com/abhimanyu003/sttr/cmd/generate.go. DO NOT EDIT 2 | 3 | package cmd 4 | 5 | import ( 6 | "fmt" 7 | "os" 8 | 9 | "github.com/abhimanyu003/sttr/processors" 10 | "github.com/abhimanyu003/sttr/utils" 11 | "github.com/spf13/cobra" 12 | ) 13 | 14 | var ( 15 | escapeQuotes_flag_d bool 16 | escapeQuotes_flag_s bool 17 | ) 18 | 19 | func init() { 20 | escapeQuotesCmd.Flags().BoolVarP(&escapeQuotes_flag_d, "double-quote", "d", true, "Escape double quote") 21 | escapeQuotesCmd.Flags().BoolVarP(&escapeQuotes_flag_s, "single-quote", "s", true, "Escape single quote") 22 | rootCmd.AddCommand(escapeQuotesCmd) 23 | } 24 | 25 | var escapeQuotesCmd = &cobra.Command{ 26 | Use: "escape-quotes [string]", 27 | Short: "Escapes single and double quotes by default", 28 | Aliases: []string{"esc-quotes", "escape-quotes"}, 29 | Args: cobra.MaximumNArgs(1), 30 | RunE: func(cmd *cobra.Command, args []string) error { 31 | var err error 32 | var out string 33 | 34 | flags := make([]processors.Flag, 0) 35 | p := processors.EscapeQuotes{} 36 | flags = append(flags, processors.Flag{Short: "d", Value: escapeQuotes_flag_d}) 37 | flags = append(flags, processors.Flag{Short: "s", Value: escapeQuotes_flag_s}) 38 | 39 | if len(args) == 0 { 40 | // Handle stdin/interactive input 41 | in := []byte(utils.ReadMultilineInput()) 42 | out, err = p.Transform(in, flags...) 43 | if err != nil { 44 | return err 45 | } 46 | } else { 47 | // Check if it's a file 48 | if fi, err := os.Stat(args[0]); err == nil && !fi.IsDir() { 49 | // It's a file - check if we should use streaming 50 | const largeFileThreshold = 10 * 1024 * 1024 // 10MB 51 | 52 | // Use central streaming function for all processors 53 | if processors.CanStream(p) && (fi.Size() > largeFileThreshold || processors.PreferStream(p)) { 54 | // Use streaming 55 | file, err := os.Open(args[0]) 56 | if err != nil { 57 | return err 58 | } 59 | defer file.Close() 60 | 61 | err = processors.TransformStream(p, file, os.Stdout, flags...) 62 | return err 63 | } else { 64 | // Use traditional method for small files 65 | d, err := os.ReadFile(args[0]) 66 | if err != nil { 67 | return err 68 | } 69 | out, err = p.Transform(d, flags...) 70 | if err != nil { 71 | return err 72 | } 73 | } 74 | } else { 75 | // Not a file, treat as string input 76 | out, err = p.Transform([]byte(args[0]), flags...) 77 | if err != nil { 78 | return err 79 | } 80 | } 81 | } 82 | 83 | _, err = fmt.Fprint(os.Stdout, out) 84 | return err 85 | }, 86 | } 87 | -------------------------------------------------------------------------------- /processors/rot13_test.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestROT13_Transform(t *testing.T) { 9 | type args struct { 10 | data []byte 11 | in1 []Flag 12 | } 13 | tests := []struct { 14 | name string 15 | args args 16 | want string 17 | wantErr bool 18 | }{ 19 | { 20 | name: "String", 21 | args: args{data: []byte("the quick brown fox jumps over a lazy dog")}, 22 | want: "gur dhvpx oebja sbk wh`cf bire n ynml qbt", 23 | }, { 24 | name: "String Uppercase", 25 | args: args{data: []byte("THE QUICK BROWN FOX JUMPS OVER A LAZY DOG")}, 26 | want: "GUR DHVPX OEBJA SBK WH@CF BIRE N YNML QBT", 27 | }, { 28 | name: "Emoji", 29 | args: args{data: []byte("😃😇🙃🙂😉😌😙😗🇮🇳")}, 30 | want: "😃😇🙃🙂😉😌😙😗🇮🇳", 31 | }, { 32 | name: "Multi line string", 33 | args: args{data: []byte("123345\nabcd\n456\n123\nabc\n567\n7890")}, 34 | want: "123345\nnopq\n456\n123\nnop\n567\n7890", 35 | }, 36 | } 37 | for _, tt := range tests { 38 | t.Run(tt.name, func(t *testing.T) { 39 | p := ROT13{} 40 | got, err := p.Transform(tt.args.data, tt.args.in1...) 41 | if (err != nil) != tt.wantErr { 42 | t.Errorf("Transform() error = %v, wantErr %v", err, tt.wantErr) 43 | return 44 | } 45 | if got != tt.want { 46 | t.Errorf("Transform() got = %v, want %v", got, tt.want) 47 | } 48 | }) 49 | } 50 | } 51 | 52 | func TestROT13_Command(t *testing.T) { 53 | test := struct { 54 | alias []string 55 | description string 56 | filterValue string 57 | flags []Flag 58 | name string 59 | title string 60 | }{ 61 | alias: []string{"rot13-encode", "rot13-enc"}, 62 | description: "Cipher/Decipher your text with ROT13 letter substitution", 63 | filterValue: "ROT13 Letter Substitution (rot13)", 64 | flags: nil, 65 | name: "rot13", 66 | title: "ROT13 Letter Substitution (rot13)", 67 | } 68 | p := ROT13{} 69 | if got := p.Alias(); !reflect.DeepEqual(got, test.alias) { 70 | t.Errorf("Alias() = %v, want %v", got, test.alias) 71 | } 72 | if got := p.Description(); got != test.description { 73 | t.Errorf("Description() = %v, want %v", got, test.description) 74 | } 75 | if got := p.FilterValue(); got != test.filterValue { 76 | t.Errorf("FilterValue() = %v, want %v", got, test.filterValue) 77 | } 78 | if got := p.Flags(); !reflect.DeepEqual(got, test.flags) { 79 | t.Errorf("Flags() = %v, want %v", got, test.flags) 80 | } 81 | if got := p.Name(); got != test.name { 82 | t.Errorf("Name() = %v, want %v", got, test.name) 83 | } 84 | if got := p.Title(); got != test.title { 85 | t.Errorf("Title() = %v, want %v", got, test.title) 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /processors/url.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "fmt" 5 | "mvdan.cc/xurls/v2" 6 | "net/url" 7 | "strings" 8 | ) 9 | 10 | // URLEncode encode url string. 11 | type URLEncode struct{} 12 | 13 | func (p URLEncode) Name() string { 14 | return "url-encode" 15 | } 16 | 17 | func (p URLEncode) Alias() []string { 18 | return []string{"url-enc"} 19 | } 20 | 21 | func (p URLEncode) Transform(data []byte, _ ...Flag) (string, error) { 22 | return url.QueryEscape(string(data)), nil 23 | } 24 | 25 | func (p URLEncode) Flags() []Flag { 26 | return nil 27 | } 28 | 29 | func (p URLEncode) Title() string { 30 | title := "URL Encode" 31 | return fmt.Sprintf("%s (%s)", title, p.Name()) 32 | } 33 | 34 | func (p URLEncode) Description() string { 35 | return "Encode URL entities" 36 | } 37 | 38 | func (p URLEncode) FilterValue() string { 39 | return p.Title() 40 | } 41 | 42 | // URLDecode decode url string. 43 | type URLDecode struct{} 44 | 45 | func (p URLDecode) Name() string { 46 | return "url-decode" 47 | } 48 | 49 | func (p URLDecode) Alias() []string { 50 | return []string{"url-dec"} 51 | } 52 | 53 | func (p URLDecode) Transform(data []byte, _ ...Flag) (string, error) { 54 | res, _ := url.QueryUnescape(string(data)) 55 | return res, nil 56 | } 57 | 58 | func (p URLDecode) Flags() []Flag { 59 | return nil 60 | } 61 | 62 | func (p URLDecode) Title() string { 63 | title := "URL Decode" 64 | return fmt.Sprintf("%s (%s)", title, p.Name()) 65 | } 66 | 67 | func (p URLDecode) Description() string { 68 | return "Decode URL entities" 69 | } 70 | 71 | func (p URLDecode) FilterValue() string { 72 | return p.Title() 73 | } 74 | 75 | // ExtractURLs decode url string. 76 | type ExtractURLs struct{} 77 | 78 | func (p ExtractURLs) Name() string { 79 | return "extract-url" 80 | } 81 | 82 | func (p ExtractURLs) Alias() []string { 83 | return []string{"url-ext", "extract-urls", "ext-url"} 84 | } 85 | 86 | func (p ExtractURLs) Transform(data []byte, _ ...Flag) (string, error) { 87 | rxRelaxed := xurls.Relaxed() 88 | urls := rxRelaxed.FindAllString(string(data), -1) 89 | 90 | var output string 91 | 92 | for _, u := range urls { 93 | output = output + u + "\n" 94 | } 95 | 96 | output = strings.TrimSuffix(output, "\n") 97 | 98 | return output, nil 99 | } 100 | 101 | func (p ExtractURLs) Flags() []Flag { 102 | return nil 103 | } 104 | 105 | func (p ExtractURLs) Title() string { 106 | title := "Extract URLs" 107 | return fmt.Sprintf("%s (%s)", title, p.Name()) 108 | } 109 | 110 | func (p ExtractURLs) Description() string { 111 | return "Extract URLs from text" 112 | } 113 | 114 | func (p ExtractURLs) FilterValue() string { 115 | return p.Title() 116 | } 117 | -------------------------------------------------------------------------------- /processors/spaces.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "fmt" 5 | "regexp" 6 | "strings" 7 | ) 8 | 9 | // RemoveNewLines removes newlines from string. 10 | type RemoveNewLines struct{} 11 | 12 | func (p RemoveNewLines) Name() string { 13 | return "remove-newlines" 14 | } 15 | 16 | func (p RemoveNewLines) Alias() []string { 17 | return []string{"remove-new-lines", "trim-newlines", "trim-new-lines"} 18 | } 19 | 20 | func (p RemoveNewLines) Transform(data []byte, f ...Flag) (string, error) { 21 | separator := " " 22 | for _, flag := range f { 23 | if flag.Short == "s" { 24 | x, ok := flag.Value.(string) 25 | if ok { 26 | separator = x 27 | } 28 | } 29 | } 30 | 31 | str := regexp.MustCompile(`[\r\n]+`). 32 | ReplaceAllString(strings.TrimSpace(string(data)), separator) 33 | return str, nil 34 | } 35 | 36 | func (p RemoveNewLines) Flags() []Flag { 37 | return []Flag{ 38 | { 39 | Name: "separator", 40 | Short: "s", 41 | Desc: "Separator to split multiple lines", 42 | Value: "", 43 | Type: FlagString, 44 | }, 45 | } 46 | } 47 | 48 | func (p RemoveNewLines) Title() string { 49 | title := "Remove all new lines" 50 | return fmt.Sprintf("%s (%s)", title, p.Name()) 51 | } 52 | 53 | func (p RemoveNewLines) Description() string { 54 | return "Remove all new lines" 55 | } 56 | 57 | func (p RemoveNewLines) FilterValue() string { 58 | return p.Title() 59 | } 60 | 61 | // RemoveSpaces removes all the spaces from string. 62 | type RemoveSpaces struct{} 63 | 64 | func (p RemoveSpaces) Name() string { 65 | return "remove-spaces" 66 | } 67 | 68 | func (p RemoveSpaces) Alias() []string { 69 | return []string{"remove-space", "trim-spaces", "trim-space"} 70 | } 71 | 72 | func (p RemoveSpaces) Transform(data []byte, f ...Flag) (string, error) { 73 | separator := "" 74 | for _, flag := range f { 75 | if flag.Short == "s" { 76 | x, ok := flag.Value.(string) 77 | if ok { 78 | separator = x 79 | } 80 | } 81 | } 82 | 83 | str := regexp.MustCompile(`[\s\r\n]+`). 84 | ReplaceAllString(strings.TrimSpace(string(data)), separator) 85 | return str, nil 86 | } 87 | 88 | func (p RemoveSpaces) Flags() []Flag { 89 | return []Flag{ 90 | { 91 | Name: "separator", 92 | Short: "s", 93 | Desc: "Separator to split spaces", 94 | Value: "", 95 | Type: FlagString, 96 | }, 97 | } 98 | } 99 | 100 | func (p RemoveSpaces) Title() string { 101 | title := "Remove all spaces + new lines" 102 | return fmt.Sprintf("%s (%s)", title, p.Name()) 103 | } 104 | 105 | func (p RemoveSpaces) Description() string { 106 | return "Remove all spaces + new lines" 107 | } 108 | 109 | func (p RemoveSpaces) FilterValue() string { 110 | return p.Title() 111 | } 112 | -------------------------------------------------------------------------------- /processors/xxhash.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "fmt" 5 | 6 | "github.com/harsh16coder/xxhash" 7 | ) 8 | 9 | // XXH64 encodes string to XXH64 10 | type XXH64 struct{} 11 | 12 | func (x XXH64) Name() string { 13 | return "xxh-64" 14 | } 15 | 16 | func (x XXH64) Alias() []string { 17 | return []string{"xxh64", "xxhash64", "xxhash-64"} 18 | } 19 | 20 | func (x XXH64) Transform(data []byte, _ ...Flag) (string, error) { 21 | h := xxhash.New64() 22 | if _, err := h.Write(data); err != nil { 23 | return "", err 24 | } 25 | s := h.Sum64() 26 | return fmt.Sprintf("%016x", s), nil 27 | } 28 | 29 | func (x XXH64) Flags() []Flag { 30 | return nil 31 | } 32 | 33 | func (x XXH64) Title() string { 34 | title := "xxHash - XXH64" 35 | return fmt.Sprintf("%s (%s)", title, x.Name()) 36 | } 37 | 38 | func (x XXH64) Description() string { 39 | return "Get the XXH64 checksum of your text" 40 | } 41 | 42 | func (x XXH64) FilterValue() string { 43 | return x.Title() 44 | } 45 | 46 | // XX32 encodes string to XXH32 47 | type XXH32 struct{} 48 | 49 | func (x XXH32) Name() string { 50 | return "xxh-32" 51 | } 52 | 53 | func (x XXH32) Alias() []string { 54 | return []string{"xxh32", "xxhash32", "xxhash-32"} 55 | } 56 | 57 | func (x XXH32) Transform(data []byte, _ ...Flag) (string, error) { 58 | h := xxhash.New32() 59 | if _, err := h.Write(data); err != nil { 60 | return "", err 61 | } 62 | s := h.Sum32() 63 | return fmt.Sprintf("%08x", s), nil 64 | } 65 | 66 | func (x XXH32) Flags() []Flag { 67 | return nil 68 | } 69 | 70 | func (x XXH32) Title() string { 71 | title := "xxHash - XXH32" 72 | return fmt.Sprintf("%s (%s)", title, x.Name()) 73 | } 74 | 75 | func (x XXH32) Description() string { 76 | return "Get the XXH32 checksum of your text" 77 | } 78 | 79 | func (x XXH32) FilterValue() string { 80 | return x.Title() 81 | } 82 | 83 | // XX128 encodes string to XXH32 84 | type XXH128 struct{} 85 | 86 | func (x XXH128) Name() string { 87 | return "xxh-128" 88 | } 89 | 90 | func (x XXH128) Alias() []string { 91 | return []string{"xxh128", "xxhash128", "xxhash-128"} 92 | } 93 | 94 | func (x XXH128) Transform(data []byte, _ ...Flag) (string, error) { 95 | h := xxhash.New128() 96 | if _, err := h.Write(data); err != nil { 97 | return "", err 98 | } 99 | s := h.Sum128() 100 | return fmt.Sprintf("%016x%016x", s.Hi, s.Lo), nil 101 | } 102 | 103 | func (x XXH128) Flags() []Flag { 104 | return nil 105 | } 106 | 107 | func (x XXH128) Title() string { 108 | title := "xxHash - XXH128" 109 | return fmt.Sprintf("%s (%s)", title, x.Name()) 110 | } 111 | 112 | func (x XXH128) Description() string { 113 | return "Get the XXH128 checksum of your text" 114 | } 115 | 116 | func (x XXH128) FilterValue() string { 117 | return x.Title() 118 | } 119 | -------------------------------------------------------------------------------- /processors/emails_test.go: -------------------------------------------------------------------------------- 1 | package processors 2 | 3 | import ( 4 | "reflect" 5 | "testing" 6 | ) 7 | 8 | func TestExtractEmails_Command(t *testing.T) { 9 | test := struct { 10 | alias []string 11 | description string 12 | filterValue string 13 | flags []Flag 14 | name string 15 | title string 16 | }{ 17 | alias: []string{"find-emails", "find-email", "extract-email"}, 18 | description: "Extract emails from given text", 19 | filterValue: "Extract Emails (extract-emails)", 20 | flags: []Flag{ 21 | { 22 | Name: "separator", 23 | Short: "s", 24 | Desc: "Separator to split multiple emails", 25 | Value: "", 26 | Type: FlagString, 27 | }, 28 | }, 29 | name: "extract-emails", 30 | title: "Extract Emails (extract-emails)", 31 | } 32 | p := ExtractEmails{} 33 | if got := p.Alias(); !reflect.DeepEqual(got, test.alias) { 34 | t.Errorf("Alias() = %v, want %v", got, test.alias) 35 | } 36 | if got := p.Description(); got != test.description { 37 | t.Errorf("Description() = %v, want %v", got, test.description) 38 | } 39 | if got := p.FilterValue(); got != test.filterValue { 40 | t.Errorf("FilterValue() = %v, want %v", got, test.filterValue) 41 | } 42 | if got := p.Flags(); !reflect.DeepEqual(got, test.flags) { 43 | t.Errorf("Flags() = %v, want %v", got, test.flags) 44 | } 45 | if got := p.Name(); got != test.name { 46 | t.Errorf("Name() = %v, want %v", got, test.name) 47 | } 48 | if got := p.Title(); got != test.title { 49 | t.Errorf("Title() = %v, want %v", got, test.title) 50 | } 51 | } 52 | 53 | func TestExtractEmails_Transform(t *testing.T) { 54 | type args struct { 55 | data []byte 56 | opts []Flag 57 | } 58 | tests := []struct { 59 | name string 60 | args args 61 | want string 62 | wantErr bool 63 | }{ 64 | { 65 | name: "Email in single line string", 66 | args: args{data: []byte("this is example@gmail.com")}, 67 | want: "example@gmail.com", 68 | }, 69 | { 70 | name: "Multiple Emails in single line string", 71 | args: args{data: []byte("this is example@gmail.com and this is example2@gmail.com")}, 72 | want: "example@gmail.com\nexample2@gmail.com", 73 | }, 74 | { 75 | name: "No email in text", 76 | args: args{data: []byte("there is no email in text")}, 77 | want: "", 78 | }, 79 | { 80 | name: "Fake emails", 81 | args: args{data: []byte("this is @fake.com email")}, 82 | want: "", 83 | }, 84 | { 85 | name: "Multiple Emails with separator flag", 86 | args: args{data: []byte("this is example@gmail.com and this is example2@gmail.com"), opts: []Flag{{Short: "s", Value: ","}}}, 87 | want: "example@gmail.com,example2@gmail.com", 88 | }, 89 | } 90 | for _, tt := range tests { 91 | t.Run(tt.name, func(t *testing.T) { 92 | p := ExtractEmails{} 93 | if got, _ := p.Transform(tt.args.data, tt.args.opts...); got != tt.want { 94 | t.Errorf("ExtractEmails() = %v, want %v", got, tt.want) 95 | } 96 | }) 97 | } 98 | } 99 | --------------------------------------------------------------------------------