Skip to content

Commit

Permalink
Convert equality check from method to a function (#34)
Browse files Browse the repository at this point in the history
The equality check is a readonly operation on Text values hence it is
more of a package function candidate rather than a method on the type
itself.
  • Loading branch information
rsjethani authored Jun 1, 2024
1 parent 2a49149 commit 4526b39
Show file tree
Hide file tree
Showing 2 changed files with 22 additions and 24 deletions.
12 changes: 6 additions & 6 deletions example_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -75,12 +75,12 @@ func ExampleText_UnmarshalText() {
// $ecre!
}

func ExampleText_Equals() {
s1 := secret.New("hello")
s2 := secret.New("hello")
s3 := secret.New("hi")
fmt.Println(s1.Equals(s2))
fmt.Println(s1.Equals(s3))
func ExampleEqual() {
tx1 := secret.New("hello")
tx2 := secret.New("hello", secret.RedactHint(secret.Redacted))
tx3 := secret.New("world")
fmt.Println(secret.Equal(tx1, tx2))
fmt.Println(secret.Equal(tx1, tx3))

// Output:
// true
Expand Down
34 changes: 16 additions & 18 deletions secret.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,22 +7,20 @@ package secret
// Text provides a way to safely store your secret value and a corresponding redact hint. This
// redact hint is what is used in operations like printing and serializing.
type Text struct {
// v is the actual secret values.
v *string
// r is the redact hint to be used in place of secret.
r *string
secret *string
redact *string
}

// New returns [Text] for the secret with [FiveStar] as the default redact hint. Provide options
// like [RedactHint] to modify default behavior.
func New(secret string, options ...func(*Text)) Text {
tx := Text{
v: new(string),
r: new(string),
secret: new(string),
redact: new(string),
}

*tx.v = secret
*tx.r = FiveStar
*tx.secret = secret
*tx.redact = FiveStar

for _, o := range options {
o(&tx)
Expand All @@ -42,25 +40,25 @@ const (
// the common redact hints provided with this package like [FiveX] or provide your own string.
func RedactHint(r string) func(*Text) {
return func(t *Text) {
*t.r = r
*t.redact = r
}
}

// String implements the [fmt.Stringer] interface and returns only the redact hint. This prevents the
// secret value from being printed to std*, logs etc.
func (tx Text) String() string {
if tx.r == nil {
if tx.redact == nil {
return FiveStar
}
return *tx.r
return *tx.redact
}

// Value gives you access to the actual secret value stored inside Text.
func (tx Text) Value() string {
if tx.v == nil {
if tx.secret == nil {
return ""
}
return *tx.v
return *tx.secret
}

// MarshalText implements [encoding.TextMarshaler]. It marshals redact string into bytes rather than
Expand All @@ -75,15 +73,15 @@ func (tx *Text) UnmarshalText(b []byte) error {
s := string(b)

// If the original redact is not nil then use it otherwise fallback to default.
if tx.r != nil {
*tx = New(s, RedactHint(*tx.r))
if tx.redact != nil {
*tx = New(s, RedactHint(*tx.redact))
} else {
*tx = New(s)
}
return nil
}

// Equals checks whether s2 has same secret string or not.
func (tx *Text) Equals(s2 Text) bool {
return *tx.v == *s2.v
// Equal returns true if both arguments have the same secret. The redact strings are not considered.
func Equal(tx1, tx2 Text) bool {
return *tx1.secret == *tx2.secret
}

0 comments on commit 4526b39

Please sign in to comment.