package input import ( "fmt" "os" "path/filepath" "strings" "img2pdf/internal/convert" ) // Collect expands provided paths, walking folders to gather image files. func Collect(inputs []string) ([]string, error) { var results []string for _, p := range inputs { info, err := os.Stat(p) if err != nil { return nil, fmt.Errorf("stat %s: %w", p, err) } if info.IsDir() { err = filepath.WalkDir(p, func(path string, d os.DirEntry, err error) error { if err != nil { return err } if d.IsDir() { return nil } if IsImage(path) { results = append(results, path) } return nil }) if err != nil { return nil, err } continue } if IsImage(p) { results = append(results, p) } } if len(results) == 0 { return nil, fmt.Errorf("no supported image files found") } return results, nil } // IsImage returns true if the path has an image extension supported by the stdlib decoders. func IsImage(path string) bool { ext := strings.ToLower(filepath.Ext(path)) switch ext { case ".jpg", ".jpeg", ".png", ".gif": return true default: return false } } // ReadSources reads file data for conversion. func ReadSources(paths []string) ([]convert.SourceFile, error) { var files []convert.SourceFile for _, p := range paths { data, err := os.ReadFile(p) if err != nil { return nil, fmt.Errorf("read %s: %w", p, err) } files = append(files, convert.SourceFile{ Name: filepath.Base(p), Data: data, }) } return files, nil } // DefaultOutput derives an output path based on the first input. func DefaultOutput(first string) (string, error) { info, err := os.Stat(first) if err != nil { return "", fmt.Errorf("stat %s: %w", first, err) } if info.IsDir() { name := filepath.Base(first) if name == "." || name == "" { name = "images" } return filepath.Join(first, name+".pdf"), nil } base := strings.TrimSuffix(filepath.Base(first), filepath.Ext(first)) if base == "" { base = "images" } return filepath.Join(filepath.Dir(first), base+".pdf"), nil }