MCPcopy Index your code
hub / github.com/crawshaw/jsonfile / Write

Method Write

jsonfile.go:72–114  ·  view source on GitHub ↗

Write calls fn with a copy of the data, then writes the changes to the file. If fn returns an error, Write does not change the file and returns the error.

(fn func(*Data) error)

Source from the content-addressed store, hash-verified

70// Write calls fn with a copy of the data, then writes the changes to the file.
71// If fn returns an error, Write does not change the file and returns the error.
72func (p *JSONFile[Data]) Write(fn func(*Data) error) error {
73 p.mu.Lock()
74 defer p.mu.Unlock()
75
76 data := new(Data) // operate on copy to allow concurrent reads and rollback
77 if err := json.Unmarshal(p.bytes, data); err != nil {
78 return fmt.Errorf("JSONFile.Write: %w", err)
79 }
80 if err := fn(data); err != nil {
81 return err
82 }
83 b, err := json.Marshal(data)
84 if err != nil {
85 return fmt.Errorf("JSONFile.Write: %w", err)
86 }
87 if bytes.Equal(b, p.bytes) {
88 return nil // no change
89 }
90
91 f, err := os.CreateTemp(filepath.Dir(p.path), filepath.Base(p.path)+".tmp")
92 if err != nil {
93 return fmt.Errorf("JSONFile.Write: temp: %w", err)
94 }
95 _, err = f.Write(b)
96 if err1 := f.Close(); err1 != nil && err == nil {
97 err = err1
98 }
99 if err != nil {
100 return fmt.Errorf("JSONFile.Write: %w", err)
101 }
102 if err := os.Rename(f.Name(), p.path); err != nil {
103 return fmt.Errorf("JSONFile.Write: rename: %w", err)
104 }
105
106 data = new(Data) // avoid any aliased memory
107 if err := json.Unmarshal(b, data); err != nil {
108 return fmt.Errorf("JSONFile.Write: %w", err)
109 }
110
111 p.data = data
112 p.bytes = b
113 return nil
114}

Callers 4

NewFunction · 0.95
mustWriteFunction · 0.80
TestFileErrorFunction · 0.80

Calls

no outgoing calls

Tested by 3

mustWriteFunction · 0.64
TestFileErrorFunction · 0.64