Skip to content

Commit

Permalink
refactor: proper error bubbling
Browse files Browse the repository at this point in the history
  • Loading branch information
mgjules committed May 15, 2022
1 parent 7bcbade commit 1d25d14
Show file tree
Hide file tree
Showing 7 changed files with 60 additions and 35 deletions.
6 changes: 5 additions & 1 deletion card/code.go
Original file line number Diff line number Diff line change
@@ -1,9 +1,13 @@
package card

import (
"errors"
"fmt"
)

// ErrInvalidCode is returned when a code is invalid.
var ErrInvalidCode = errors.New("invalid code")

// Code represents a card code.
type Code struct {
r string
Expand All @@ -16,7 +20,7 @@ type Code struct {
// The second character must be a valid suit.
func CodeFromString(c string) (*Code, error) {
if len(c) != 2 {
return nil, fmt.Errorf("card code '%s' should be 2 characters", c)
return nil, ErrInvalidCode
}

return &Code{
Expand Down
14 changes: 10 additions & 4 deletions card/rank.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package card

import "strings"
import (
"errors"
"strings"
)

// ErrInvalidRank is returned when a rank is invalid.
var ErrInvalidRank = errors.New("invalid rank")

// Rank represents the rank of a card.
type Rank struct {
Expand Down Expand Up @@ -35,12 +41,12 @@ func (rs Ranks) Ranks() []Rank {
}

// RankFromCode returns the rank from the given code.
func (rs Ranks) RankFromCode(c Code) (*Rank, bool) {
func (rs Ranks) RankFromCode(c Code) (*Rank, error) {
for _, r := range rs.Ranks() {
if strings.EqualFold(r.Code(), c.Rank()) {
return &r, true
return &r, nil
}
}

return nil, false
return nil, ErrInvalidRank
}
8 changes: 4 additions & 4 deletions card/rank_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ var _ = Describe("Rank", func() {
Expect(err).ToNot(HaveOccurred())

It("should return back a valid rank", func() {
r, ok := ranks.RankFromCode(*code)
Expect(ok).To(BeTrue())
r, err := ranks.RankFromCode(*code)
Expect(err).ToNot(HaveOccurred())
Expect(*r).To(Equal(ranks[0]))
})
})
Expand All @@ -31,8 +31,8 @@ var _ = Describe("Rank", func() {
Expect(err).ToNot(HaveOccurred())

It("should not return any rank", func() {
r, ok := ranks.RankFromCode(*code)
Expect(ok).To(BeFalse())
r, err := ranks.RankFromCode(*code)
Expect(err).To(MatchError(card.ErrInvalidRank))
Expect(r).To(BeNil())
})
})
Expand Down
14 changes: 10 additions & 4 deletions card/suit.go
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
package card

import "strings"
import (
"errors"
"strings"
)

// ErrInvalidSuit is returned when a suit is invalid.
var ErrInvalidSuit = errors.New("invalid suit")

// Suit represents the suit of a card.
type Suit struct {
Expand Down Expand Up @@ -35,12 +41,12 @@ func (ss Suits) Suits() []Suit {
}

// SuitFromCode returns the suit from the given code.
func (ss Suits) SuitFromCode(c Code) (*Suit, bool) {
func (ss Suits) SuitFromCode(c Code) (*Suit, error) {
for _, s := range ss.Suits() {
if strings.EqualFold(s.Code(), c.Suit()) {
return &s, true
return &s, nil
}
}

return nil, false
return nil, ErrInvalidSuit
}
8 changes: 4 additions & 4 deletions card/suit_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -20,8 +20,8 @@ var _ = Describe("Suit", func() {
Expect(err).ToNot(HaveOccurred())

It("should return back a valid suit", func() {
s, ok := suits.SuitFromCode(*code)
Expect(ok).To(BeTrue())
s, err := suits.SuitFromCode(*code)
Expect(err).ToNot(HaveOccurred())
Expect(*s).To(Equal(suits[0]))
})
})
Expand All @@ -31,8 +31,8 @@ var _ = Describe("Suit", func() {
Expect(err).ToNot(HaveOccurred())

It("should not return any rank", func() {
s, ok := suits.SuitFromCode(*code)
Expect(ok).To(BeFalse())
s, err := suits.SuitFromCode(*code)
Expect(err).To(MatchError(card.ErrInvalidSuit))
Expect(s).To(BeNil())
})
})
Expand Down
33 changes: 21 additions & 12 deletions deck/deck.go
Original file line number Diff line number Diff line change
Expand Up @@ -39,53 +39,62 @@ func New(opts ...Option) (*Deck, error) {
d.composition = composition.French
}

if err := d.generateCards(); err != nil {
return nil, fmt.Errorf("generate cards: %w", err)
}

return &d, nil
}

// generateCards generates the cards for the deck.
func (d *Deck) generateCards() error {
comp, err := composition.FromString(d.composition)
if err != nil {
return nil, fmt.Errorf("parse composition: %w", err)
return fmt.Errorf("parse composition: %w", err)
}

// Partial cards using codes.
if len(d.codes) > 0 {
codes, err := card.CodesFromStrings(d.codes...)
if err != nil {
return nil, fmt.Errorf("new codes: %w", err)
return fmt.Errorf("new codes: %w", err)
}

for _, c := range codes {
r, ok := comp.Ranks().RankFromCode(c)
if !ok {
return nil, fmt.Errorf("card code '%s' has an invalid rank", c)
r, err := comp.Ranks().RankFromCode(c)
if err != nil {
return fmt.Errorf("rank from code: %w", err)
}

s, ok := comp.Suits().SuitFromCode(c)
if !ok {
return nil, fmt.Errorf("card code '%s' has an invalid suit", c)
s, err := comp.Suits().SuitFromCode(c)
if err != nil {
return fmt.Errorf("suit from code: %w", err)
}

card, err := card.NewCard(*r, *s)
if err != nil {
return nil, fmt.Errorf("new card: %w", err)
return fmt.Errorf("new card: %w", err)
}

d.cards = append(d.cards, *card)
}

return &d, nil
return nil
}

// Full cards.
for _, s := range comp.Suits() {
for _, r := range comp.Ranks() {
card, err := card.NewCard(r, s)
if err != nil {
return nil, fmt.Errorf("new card: %w", err)
return fmt.Errorf("new card: %w", err)
}

d.cards = append(d.cards, *card)
}
}

return &d, nil
return nil
}

// ID returns the id of the deck.
Expand Down
12 changes: 6 additions & 6 deletions http/deck.go
Original file line number Diff line number Diff line change
Expand Up @@ -65,14 +65,14 @@ func RepoDeckToDeckOpened(rd *repo.Deck) (*DeckOpened, error) {
return nil, fmt.Errorf("new code: %w", err)
}

r, ok := comp.Ranks().RankFromCode(*c)
if !ok {
return nil, fmt.Errorf("card code '%s' has an invalid rank", c)
r, err := comp.Ranks().RankFromCode(*c)
if err != nil {
return nil, fmt.Errorf("rank from code: %w", err)
}

s, ok := comp.Suits().SuitFromCode(*c)
if !ok {
return nil, fmt.Errorf("card code '%s' has an invalid suit", c)
s, err := comp.Suits().SuitFromCode(*c)
if err != nil {
return nil, fmt.Errorf("suit from code: %w", err)
}

d.Cards = append(d.Cards, Card{
Expand Down

0 comments on commit 1d25d14

Please sign in to comment.