File: revert.go

package info (click to toggle)
incus 6.0.4-2
  • links: PTS, VCS
  • area: main
  • in suites: trixie
  • size: 23,864 kB
  • sloc: sh: 16,015; ansic: 3,121; python: 456; makefile: 321; ruby: 51; sql: 50; lisp: 6
file content (47 lines) | stat: -rw-r--r-- 1,539 bytes parent folder | download | duplicates (8)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
package revert

// Hook is a function that can be added to the revert via the Add() function.
// These will be run in the reverse order that they were added if the reverter's Fail() function is called.
type Hook func()

// Reverter is a helper type to manage revert functions.
type Reverter struct {
	revertFuncs []Hook
}

// New returns a new Reverter.
func New() *Reverter {
	return &Reverter{}
}

// Add adds a revert function to the list to be run when Revert() is called.
func (r *Reverter) Add(f Hook) {
	r.revertFuncs = append(r.revertFuncs, f)
}

// Fail runs any revert functions in the reverse order they were added.
// Should be used with defer or when a task has encountered an error and needs to be reverted.
func (r *Reverter) Fail() {
	funcCount := len(r.revertFuncs)
	for k := range r.revertFuncs {
		// Run the revert functions in reverse order.
		k = funcCount - 1 - k
		r.revertFuncs[k]()
	}
}

// Success clears the revert functions previously added.
// Should be called on successful completion of a task to prevent revert functions from being run.
func (r *Reverter) Success() {
	r.revertFuncs = nil
}

// Clone returns a copy of the reverter with the current set of revert functions added.
// This can be used if you want to return a reverting function to an external caller but do not want to actually
// execute the previously deferred reverter.Fail() function.
func (r *Reverter) Clone() *Reverter {
	rNew := New()
	rNew.revertFuncs = append(make([]Hook, 0, len(r.revertFuncs)), r.revertFuncs...)

	return rNew
}