fn apply_edits(edits: &[Edit], file_path: &Path) -> Result<(), Box<dyn Error>> {
        // check if there are any edits
        if edits.is_empty() {
            return Ok(());
        }

        // open up the original file and the temp file which we are writing to
        let file = BufReader::new(File::open(file_path)?);

        // TODO: use NamedTempFile here
        let tmp_path = file_path.with_extension(".tmp");
        let mut tmp = BufWriter::new(File::create(&tmp_path)?);

        let mut edit_index = 0;
        let mut skipped_lines_left = 0;

        for (line_number, line) in file.lines().enumerate() {
            let line = line?;
            let edit = &edits[edit_index];

            // if previous edits had us delete this line, don't write it
            // and move to the next line
            if skipped_lines_left > 0 {
                skipped_lines_left -= 1;
                continue;
            }

            // check if there is an edit operating on this line.
            if edit.original.line == line_number {
                match edit.op {
                    Operation::Insert => {
                        // nothing to delete, only add the original line + inserted lines
                        tmp.write_all((line + "\n").as_bytes())?;
                        tmp.write_all((edit.modified.content.join("\n") + "\n").as_bytes())?;
                    }
                    Operation::Delete => {
                        // skip adding both this line and future lines.
                        // Subtract one because we are also not writing this line.
                        skipped_lines_left = edit.original.content.len() - 1;
                    }
                    Operation::Replace => {
                        // skip adding both this line and future lines, instead add inserted lines.
                        // Subtract one because we are also not writing this line.
                        skipped_lines_left = edit.original.content.len() - 1;
                        tmp.write_all((edit.modified.content.join("\n") + "\n").as_bytes())?;
                    }
                }
                edit_index += 1;
            } else {
                // write line to file
                tmp.write_all((line + "\n").as_bytes())?;
            }
        }

        // sometimes theres an insert edit left over, in which case we apply it. Also check for a few errors
        if edit_index == edits.len() - 1 && edits[edit_index].op == Operation::Insert {
            tmp.write_all((edits[edit_index].modified.content.join("\n") + "\n").as_bytes())?;
        } else if edit_index < edits.len() - 1 {
            return Err("Too many edits left over".into());
        } else if edit_index == edits.len() - 1 && edits[edit_index].op != Operation::Insert {
            return Err("Wrong edit type left over".into());
        }

        // drop the writer to the tmp file
        std::mem::drop(tmp);

        // overwrite the main file with the tmp file
        fs::rename(tmp_path, file_path)?;

        Ok(())
    }
/// Applies a series of edits to a file
/// Goes line by line through the file to add edits in a tmp file,
/// then overwriting the normal file with the tmp file.
Applies a series of edits to a file
Goes line by line through the file to add edits in a tmp file,
then overwriting the normal file with the tmp file.
Applies a series of edits to a file Goes line by line through the file to add edits in a tmp file then overwriting the normal file with the tmp file .
fn apply_edits(edits: &[Edit], file_path: &Path) -> Result<(), Box<dyn Error>> {
        // check if there are any edits
        if edits.is_empty() {
            return Ok(());
        }
        // open up the original file and the temp file which we are writing to
        let file = BufReader::new(File::open(file_path)?);
        // TODO: use NamedTempFile here
        let tmp_path = file_path.with_extension(".tmp");
        let mut tmp = BufWriter::new(File::create(&tmp_path)?);
        let mut edit_index = 0;
        let mut skipped_lines_left = 0;
        for (line_number, line) in file.lines().enumerate() {
            let line = line?;
            let edit = &edits[edit_index];
            // if previous edits had us delete this line, don't write it
            // and move to the next line
            if skipped_lines_left > 0 {
                skipped_lines_left -= 1;
                continue;
            }
            // check if there is an edit operating on this line.
            if edit.original.line == line_number {
                match edit.op {
                    Operation::Insert => {
                        // nothing to delete, only add the original line + inserted lines
                        tmp.write_all((line + "\n").as_bytes())?;
                        tmp.write_all((edit.modified.content.join("\n") + "\n").as_bytes())?;
                    }
                    Operation::Delete => {
                        // skip adding both this line and future lines.
                        // Subtract one because we are also not writing this line.
                        skipped_lines_left = edit.original.content.len() - 1;
                    }
                    Operation::Replace => {
                        // skip adding both this line and future lines, instead add inserted lines.
                        // Subtract one because we are also not writing this line.
                        skipped_lines_left = edit.original.content.len() - 1;
                        tmp.write_all((edit.modified.content.join("\n") + "\n").as_bytes())?;
                    }
                }
                edit_index += 1;
            } else {
                // write line to file
                tmp.write_all((line + "\n").as_bytes())?;
            }
        }
        // sometimes theres an insert edit left over, in which case we apply it. Also check for a few errors
        if edit_index == edits.len() - 1 && edits[edit_index].op == Operation::Insert {
            tmp.write_all((edits[edit_index].modified.content.join("\n") + "\n").as_bytes())?;
        } else if edit_index < edits.len() - 1 {
            return Err("Too many edits left over".into());
        } else if edit_index == edits.len() - 1 && edits[edit_index].op != Operation::Insert {
            return Err("Wrong edit type left over".into());
        }
        // drop the writer to the tmp file
        std::mem::drop(tmp);
        // overwrite the main file with the tmp file
        fs::rename(tmp_path, file_path)?;
        Ok(())
    }
fn apply_edits ( edits : & [ Edit ] , file_path : & Path ) -> Result < ( ) , Box < dyn Error > > { // check if there are any edits if edits . is_empty ( ) { return Ok ( ( ) ) ; } // open up the original file and the temp file which we are writing to let file = BufReader :: new ( File :: open ( file_path ) ? ) ; // TODO: use NamedTempFile here let tmp_path = file_path . with_extension ( " " ) ; let mut tmp = BufWriter :: new ( File :: create ( & tmp_path ) ? ) ; let mut edit_index = 0 ; let mut skipped_lines_left = 0 ; for ( line_number , line ) in file . lines ( ) . enumerate ( ) { let line = line ? ; let edit = & edits [ edit_index ] ; // if previous edits had us delete this line, don't write it // and move to the next line if skipped_lines_left > 0 { skipped_lines_left -= 1 ; continue ; } // check if there is an edit operating on this line. if edit . original . line == line_number { match edit . op { Operation :: Insert => { // nothing to delete, only add the original line + inserted lines tmp . write_all ( ( line + " \n " ) . as_bytes ( ) ) ? ; tmp . write_all ( ( edit . modified . content . join ( " \n " ) + " \n " ) . as_bytes ( ) ) ? ; } Operation :: Delete => { // skip adding both this line and future lines. // Subtract one because we are also not writing this line. skipped_lines_left = edit . original . content . len ( ) - 1 ; } Operation :: Replace => { // skip adding both this line and future lines, instead add inserted lines. // Subtract one because we are also not writing this line. skipped_lines_left = edit . original . content . len ( ) - 1 ; tmp . write_all ( ( edit . modified . content . join ( " \n " ) + " \n " ) . as_bytes ( ) ) ? ; } } edit_index += 1 ; } else { // write line to file tmp . write_all ( ( line + " \n " ) . as_bytes ( ) ) ? ; } } // sometimes theres an insert edit left over, in which case we apply it. Also check for a few errors if edit_index == edits . len ( ) - 1 && edits [ edit_index ] . op == Operation :: Insert { tmp . write_all ( ( edits [ edit_index ] . modified . content . join ( " \n " ) + " \n " ) . as_bytes ( ) ) ? ; } else if edit_index < edits . len ( ) - 1 { return Err ( " " . into ( ) ) ; } else if edit_index == edits . len ( ) - 1 && edits [ edit_index ] . op != Operation :: Insert { return Err ( " " . into ( ) ) ; } // drop the writer to the tmp file std :: mem :: drop ( tmp ) ; // overwrite the main file with the tmp file fs :: rename ( tmp_path , file_path ) ? ; Ok ( ( ) ) }
Applies a series of edits to a file
Goes line by line through the file to add edits in a tmp file,
then overwriting the normal file with the tmp file.
Applies a series of edits to a file Goes line by line through the file to add edits in a tmp file then overwriting the normal file with the tmp file .
edits
&[Edit]
file_path
&Path
edits
&[Edit]
file_path
&Path