package openapi import ( "bufio" "io" "strings" ) // DiffBlock represents a single file change in a git diff. type DiffBlock struct { File string Content string // The full diff content for this file } // DiffParser parses a stream of git diff output. type DiffParser struct { onBlock func(DiffBlock) current *DiffBlock sb strings.Builder } // NewDiffParser creates a new DiffParser. func NewDiffParser(onBlock func(DiffBlock)) *DiffParser { return &DiffParser{onBlock: onBlock} } // Parse reads from r and calls onBlock for each completed diff block. func (p *DiffParser) Parse(r io.Reader) error { scanner := bufio.NewScanner(r) for scanner.Scan() { p.Feed(scanner.Text()) } p.Flush() return scanner.Err() } // Feed processes a single line of diff output. func (p *DiffParser) Feed(line string) { if strings.HasPrefix(line, "diff --git ") { p.Flush() p.current = &DiffBlock{} // Extract file path from "diff --git a/path/to/file b/path/to/file" parts := strings.Split(line, " ") if len(parts) >= 4 { p.current.File = strings.TrimPrefix(parts[3], "b/") } } if p.current != nil { p.sb.WriteString(line) p.sb.WriteString("\n") } } // Flush finalizes the current block and emits it. func (p *DiffParser) Flush() { if p.current != nil { p.current.Content = p.sb.String() p.onBlock(*p.current) p.current = nil p.sb.Reset() } }