aboutsummaryrefslogtreecommitdiff
path: root/ident.go
diff options
context:
space:
mode:
Diffstat (limited to 'ident.go')
-rw-r--r--ident.go127
1 files changed, 0 insertions, 127 deletions
diff --git a/ident.go b/ident.go
deleted file mode 100644
index 50676a45..00000000
--- a/ident.go
+++ /dev/null
@@ -1,127 +0,0 @@
-package furgit
-
-import (
- "bytes"
- "errors"
- "fmt"
- "math"
- "strconv"
- "strings"
- "time"
-)
-
-// Ident represents a Git identity (author/committer/tagger).
-type Ident struct {
- // Name represents the person's name.
- Name []byte
- // Email represents the person's email.
- Email []byte
- // WhenUnix represents the timestamp as a Unix time.
- // This value is in UTC.
- WhenUnix int64
- // The timezone offset in minutes.
- OffsetMinutes int32
-}
-
-// parseIdent parses an identity line from the canonical Git format:
-// "Name <email> 123456789 +0000".
-func parseIdent(line []byte) (*Ident, error) {
- lt := bytes.IndexByte(line, '<')
- if lt < 0 {
- return nil, errors.New("furgit: ident: missing opening <")
- }
- gtRel := bytes.IndexByte(line[lt+1:], '>')
- if gtRel < 0 {
- return nil, errors.New("furgit: ident: missing closing >")
- }
- gt := lt + 1 + gtRel
- nameBytes := append([]byte(nil), line[:lt]...)
- emailBytes := append([]byte(nil), line[lt+1:gt]...)
-
- rest := line[gt+1:]
- if len(rest) == 0 || rest[0] != ' ' {
- return nil, errors.New("furgit: ident: missing timestamp separator")
- }
- rest = rest[1:]
- sp := bytes.IndexByte(rest, ' ')
- if sp < 0 {
- return nil, errors.New("furgit: ident: missing timezone separator")
- }
- whenStr := string(rest[:sp])
- when, err := strconv.ParseInt(whenStr, 10, 64)
- if err != nil {
- return nil, fmt.Errorf("furgit: ident: invalid timestamp: %w", err)
- }
-
- tz := rest[sp+1:]
- if len(tz) < 5 {
- return nil, errors.New("furgit: ident: invalid timezone encoding")
- }
- sign := 1
- switch tz[0] {
- case '-':
- sign = -1
- case '+':
- default:
- return nil, errors.New("furgit: ident: invalid timezone sign")
- }
-
- hh, err := strconv.Atoi(string(tz[1:3]))
- if err != nil {
- return nil, fmt.Errorf("furgit: ident: invalid timezone hours: %w", err)
- }
- mm, err := strconv.Atoi(string(tz[3:5]))
- if err != nil {
- return nil, fmt.Errorf("furgit: ident: invalid timezone minutes: %w", err)
- }
- if hh < 0 || hh > 23 {
- return nil, errors.New("furgit: ident: invalid timezone hours range")
- }
- if mm < 0 || mm > 59 {
- return nil, errors.New("furgit: ident: invalid timezone minutes range")
- }
- total := int64(hh)*60 + int64(mm)
- if total > math.MaxInt32 {
- return nil, errors.New("furgit: ident: timezone overflow")
- }
- offset := int32(total)
- if sign < 0 {
- offset = -offset
- }
-
- return &Ident{
- Name: nameBytes,
- Email: emailBytes,
- WhenUnix: when,
- OffsetMinutes: offset,
- }, nil
-}
-
-// Serialize renders an Ident into canonical Git format.
-func (ident Ident) Serialize() ([]byte, error) {
- var b strings.Builder
- b.Grow(len(ident.Name) + len(ident.Email) + 32)
- b.Write(ident.Name)
- b.WriteString(" <")
- b.Write(ident.Email)
- b.WriteString("> ")
- b.WriteString(strconv.FormatInt(ident.WhenUnix, 10))
- b.WriteByte(' ')
-
- offset := ident.OffsetMinutes
- sign := '+'
- if offset < 0 {
- sign = '-'
- offset = -offset
- }
- hh := offset / 60
- mm := offset % 60
- fmt.Fprintf(&b, "%c%02d%02d", sign, hh, mm)
- return []byte(b.String()), nil
-}
-
-// When returns the ident's time.Time with the correct timezone.
-func (ident Ident) When() time.Time {
- loc := time.FixedZone("git", int(ident.OffsetMinutes)*60)
- return time.Unix(ident.WhenUnix, 0).In(loc)
-}