File: serialization.go

package info (click to toggle)
gitlab-shell 14.35.0%2Bds1-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 23,652 kB
  • sloc: ruby: 1,129; makefile: 583; sql: 391; sh: 384
file content (113 lines) | stat: -rw-r--r-- 3,289 bytes parent folder | download | duplicates (3)
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
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package git2go

import (
	"encoding/gob"
	"errors"
	"fmt"
	"reflect"
)

func init() {
	for typeToRegister := range registeredTypes {
		gob.Register(reflect.Zero(typeToRegister).Interface())
	}
}

var registeredTypes = map[reflect.Type]struct{}{
	reflect.TypeOf(ChangeFileMode{}):         {},
	reflect.TypeOf(CreateDirectory{}):        {},
	reflect.TypeOf(CreateFile{}):             {},
	reflect.TypeOf(DeleteFile{}):             {},
	reflect.TypeOf(MoveFile{}):               {},
	reflect.TypeOf(UpdateFile{}):             {},
	reflect.TypeOf(wrapError{}):              {},
	reflect.TypeOf(IndexError{}):             {},
	reflect.TypeOf(UnknownIndexError("")):    {},
	reflect.TypeOf(InvalidArgumentError("")): {},
	reflect.TypeOf(HasConflictsError{}):      {},
	reflect.TypeOf(ConflictingFilesError{}):  {},
	reflect.TypeOf(EmptyError{}):             {},
	reflect.TypeOf(UnknownIndexError("")):    {},
	reflect.TypeOf(ConflictError{}):          {},
	reflect.TypeOf(CommitNotFoundError{}):    {},
}

// Result is the serialized result.
type Result struct {
	// CommitID is the result of the call.
	CommitID string
	// Err is set if an error occurred. Err must exist on all gob serialized
	// results so that all errors can be returned.
	Err error
}

// wrapError is used to serialize wrapped errors as fmt.wrapError type only has
// private fields and can't be serialized via gob. It's also used to serialize unregistered
// error types by serializing only their error message.
type wrapError struct {
	Message string
	Err     error
}

func (err wrapError) Error() string { return err.Message }

func (err wrapError) Unwrap() error { return err.Err }

// HasConflictsError is used when a change, for example a revert, could not be
// applied due to a conflict.
type HasConflictsError struct{}

func (err HasConflictsError) Error() string {
	return "could not apply due to conflicts"
}

// ConflictingFilesError is an error raised when there are conflicting files.
type ConflictingFilesError struct {
	// ConflictingFiles is the set of files which have conflicts.
	ConflictingFiles []string
}

func (err ConflictingFilesError) Error() string {
	return "there are conflicting files"
}

// EmptyError indicates the command, for example cherry-pick, did result in no
// changes, so the result is empty.
type EmptyError struct{}

func (err EmptyError) Error() string {
	return "could not apply because the result was empty"
}

// CommitNotFoundError indicates that the given commit rev could not be found.
type CommitNotFoundError struct {
	// Revision used to lookup the commit
	Revision string
}

func (err CommitNotFoundError) Error() string {
	return fmt.Sprintf("commit not found: %q", err.Revision)
}

// SerializableError returns an error that is Gob serializable.
// Registered types are serialized directly. Unregistered types
// are transformed in to an opaque error using their error message.
// Wrapped errors remain unwrappable.
func SerializableError(err error) error {
	if err == nil {
		return nil
	}

	if unwrappedErr := errors.Unwrap(err); unwrappedErr != nil {
		return wrapError{
			Message: err.Error(),
			Err:     SerializableError(unwrappedErr),
		}
	}

	if _, ok := registeredTypes[reflect.TypeOf(err)]; !ok {
		return wrapError{Message: err.Error()}
	}

	return err
}