valueobject

package
v1.2.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 21, 2025 License: MIT Imports: 17 Imported by: 0

README

Value Objects

Overview

Value Objects are immutable objects that represent a concept in your domain with no identity. They are defined by their attributes rather than by a unique identifier. Value Objects are used to encapsulate and validate domain values, ensuring that they are always in a valid state.

This package provides a collection of common Value Objects that can be used in your applications.

Characteristics of Value Objects

  • Immutability: Once created, Value Objects cannot be changed. Any operation that would change a Value Object returns a new instance.
  • Equality by value: Two Value Objects are equal if all their attributes are equal.
  • Self-validation: Value Objects validate their attributes during creation and reject invalid values.
  • Encapsulation: Value Objects encapsulate domain rules and behaviors related to the values they represent.

Available Value Objects

Value Object Description
Address Represents a physical address with validation
Color Represents a color in various formats (RGB, HEX, etc.)
Coordinate Represents a geographic coordinate (latitude and longitude)
DateOfBirth Represents a person's date of birth with validation
DateOfDeath Represents a person's date of death with validation
Duration Represents a time duration with various units
Email Represents an email address with validation
FileSize Represents a file size with various units (bytes, KB, MB, etc.)
Gender Represents a person's gender
ID Represents a unique identifier
IPAddress Represents an IP address (IPv4 or IPv6)
Money Represents a monetary value with currency
Name Represents a person's name
Password Represents a password with validation and security features
Percentage Represents a percentage value
Phone Represents a phone number with validation
Rating Represents a rating value (e.g., 1-5 stars)
Temperature Represents a temperature value with various units
URL Represents a URL with validation
Username Represents a username with validation
Version Represents a version number (e.g., semantic versioning)

Usage Examples

FileSize

See the FileSize example for a complete, runnable example of how to use the FileSize value object.

ID

See the ID example for a complete, runnable example of how to use the ID value object.

IPAddress

See the IPAddress example for a complete, runnable example of how to use the IPAddress value object.

URL

See the URL example for a complete, runnable example of how to use the URL value object.

Username

See the Username example for a complete, runnable example of how to use the Username value object.

Coordinate

See the Coordinate example for a complete, runnable example of how to use the Coordinate value object.

Money

See the Money example for a complete, runnable example of how to use the Money value object.

Email

See the Email example for a complete, runnable example of how to use the Email value object.

Address
// Example usage of the Address value object
package main

import (
	"fmt"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new address
	address, err := valueobject.NewAddress("123 Main St, Anytown, CA 12345")
	if err != nil {
		// Handle error
		fmt.Println("Error creating address:", err)
		return
	}

	// Access the address as string
	fmt.Printf("Address: %s\n", address.String())

	// Check if address is empty
	isEmpty := address.IsEmpty()
	fmt.Printf("Is address empty? %v\n", isEmpty)

	// Compare addresses (case insensitive)
	otherAddress, _ := valueobject.NewAddress("123 Main St, Anytown, CA 12345")
	areEqual := address.Equals(otherAddress)
	fmt.Printf("Are addresses equal? %v\n", areEqual)
}
Color
// Example usage of the Color value object
package main

import (
	"fmt"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new color
	color, err := valueobject.NewColor("#FF5733")
	if err != nil {
		// Handle error
		fmt.Println("Error creating color:", err)
		return
	}

	// Create from shorthand notation
	shortColor, _ := valueobject.NewColor("#F53")
	fmt.Printf("Expanded color: %s\n", shortColor.String()) // #FF5533

	// Get RGB components
	r, g, b, err := color.RGB()
	if err != nil {
		// Handle error
		fmt.Println("Error getting RGB components:", err)
		return
	}
	fmt.Printf("RGB: (%d, %d, %d)\n", r, g, b)

	// Add alpha component
	colorWithAlpha, _ := color.WithAlpha(128)
	fmt.Printf("Color with alpha: %s\n", colorWithAlpha)

	// Check if color is dark
	isDark, _ := color.IsDark()
	fmt.Printf("Is color dark? %v\n", isDark)

	// Invert color
	inverted, _ := color.Invert()
	fmt.Printf("Inverted color: %s\n", inverted.String())
}
DateOfBirth
// Example usage of the DateOfBirth value object
package main

import (
	"fmt"
	"time"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new date of birth
	dob, err := valueobject.NewDateOfBirth("1990-01-15")
	if err != nil {
		// Handle error
		fmt.Println("Error creating date of birth:", err)
		return
	}

	// Create from time.Time
	dobTime := time.Date(1990, 1, 15, 0, 0, 0, 0, time.UTC)
	dob, err = valueobject.NewDateOfBirthFromTime(dobTime)
	if err != nil {
		// Handle error
		fmt.Println("Error creating date of birth from time:", err)
		return
	}

	// Get age
	age := dob.Age()
	fmt.Printf("Age: %d years\n", age)

	// Format as string
	fmt.Printf("Date of birth: %s\n", dob.String())

	// Check if adult
	isAdult := dob.IsAdult()
	fmt.Printf("Is adult? %v\n", isAdult)
}
DateOfDeath
// Example usage of the DateOfDeath value object
package main

import (
	"fmt"
	"time"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a date of birth first
	dob, _ := valueobject.NewDateOfBirth("1930-01-15")

	// Create a new date of death
	dod, err := valueobject.NewDateOfDeath("2020-05-20", dob)
	if err != nil {
		// Handle error
		fmt.Println("Error creating date of death:", err)
		return
	}

	// Create from time.Time
	dodTime := time.Date(2020, 5, 20, 0, 0, 0, 0, time.UTC)
	dod, err = valueobject.NewDateOfDeathFromTime(dodTime, dob)
	if err != nil {
		// Handle error
		fmt.Println("Error creating date of death from time:", err)
		return
	}

	// Get age at death
	ageAtDeath := dod.AgeAtDeath()
	fmt.Printf("Age at death: %d years\n", ageAtDeath)

	// Format as string
	fmt.Printf("Date of death: %s\n", dod.String())
}
Duration
// Example usage of the Duration value object
package main

import (
	"fmt"
	"time"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new duration
	duration, err := valueobject.NewDuration(3, 30, 15)
	if err != nil {
		// Handle error
		fmt.Println("Error creating duration:", err)
		return
	}

	// Create from time.Duration
	timeDuration := 2*time.Hour + 45*time.Minute + 30*time.Second
	duration, err = valueobject.NewDurationFromTimeDuration(timeDuration)
	if err != nil {
		// Handle error
		fmt.Println("Error creating duration from time.Duration:", err)
		return
	}

	// Parse from string
	duration, err = valueobject.ParseDuration("1h30m45s")
	if err != nil {
		// Handle error
		fmt.Println("Error parsing duration:", err)
		return
	}

	// Access components
	hours := duration.Hours()
	minutes := duration.Minutes()
	seconds := duration.Seconds()
	fmt.Printf("Duration: %d hours, %d minutes, %d seconds\n", hours, minutes, seconds)

	// Format as string
	fmt.Printf("Formatted duration: %s\n", duration.String())

	// Convert to time.Duration
	timeDur := duration.ToTimeDuration()
	fmt.Printf("As time.Duration: %v\n", timeDur)
}
Gender
// Example usage of the Gender value object
package main

import (
	"fmt"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new gender
	gender, err := valueobject.NewGender("male")
	if err != nil {
		// Handle error
		fmt.Println("Error creating gender:", err)
		return
	}

	// Check gender type
	isMale := gender.IsMale()
	isFemale := gender.IsFemale()
	isOther := gender.IsOther()
	fmt.Printf("Is male: %v, Is female: %v, Is other: %v\n", isMale, isFemale, isOther)

	// Format as string
	fmt.Printf("Gender: %s\n", gender.String())

	// Create with different case
	gender, _ = valueobject.NewGender("FEMALE")
	fmt.Printf("Normalized gender: %s\n", gender.String()) // "female"
}
Name
// Example usage of the Name value object
package main

import (
	"fmt"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new name
	name, err := valueobject.NewName("John", "Doe")
	if err != nil {
		// Handle error
		fmt.Println("Error creating name:", err)
		return
	}

	// Create with middle name
	nameWithMiddle, _ := valueobject.NewNameWithMiddle("Jane", "Marie", "Smith")

	// Access components
	firstName := name.FirstName()
	lastName := name.LastName()
	fmt.Printf("First name: %s, Last name: %s\n", firstName, lastName)

	// Get full name
	fullName := name.FullName()
	fmt.Printf("Full name: %s\n", fullName)

	// Get initials
	initials := name.Initials()
	fmt.Printf("Initials: %s\n", initials)

	// Format with middle name
	middleInitial := nameWithMiddle.MiddleInitial()
	fmt.Printf("Name with middle initial: %s %s. %s\n", 
		nameWithMiddle.FirstName(), middleInitial, nameWithMiddle.LastName())
}
Password
// Example usage of the Password value object
package main

import (
	"fmt"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new password
	password, err := valueobject.NewPassword("P@ssw0rd123!")
	if err != nil {
		// Handle error
		fmt.Println("Error creating password:", err)
		return
	}

	// Check password strength
	strength := password.Strength()
	fmt.Printf("Password strength: %d/5\n", strength)

	// Check if password meets requirements
	hasUppercase := password.HasUppercase()
	hasLowercase := password.HasLowercase()
	hasDigit := password.HasDigit()
	hasSpecial := password.HasSpecialChar()
	fmt.Printf("Has uppercase: %v, Has lowercase: %v, Has digit: %v, Has special: %v\n",
		hasUppercase, hasLowercase, hasDigit, hasSpecial)

	// Verify a password
	isMatch := password.Verify("P@ssw0rd123!")
	fmt.Printf("Password matches: %v\n", isMatch)

	// Masked representation for logging
	fmt.Printf("Masked password: %s\n", password.Masked())
}
Percentage
// Example usage of the Percentage value object
package main

import (
	"fmt"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new percentage
	percentage, err := valueobject.NewPercentage(75.5)
	if err != nil {
		// Handle error
		fmt.Println("Error creating percentage:", err)
		return
	}

	// Access value
	value := percentage.Value()
	fmt.Printf("Percentage value: %.2f%%\n", value)

	// Format as string
	fmt.Printf("Formatted: %s\n", percentage.String()) // "75.50%"

	// Convert to decimal (0-1 range)
	decimal := percentage.ToDecimal()
	fmt.Printf("As decimal: %.4f\n", decimal) // 0.7550

	// Calculate percentage of a value
	amount := 200.0
	result := percentage.Of(amount)
	fmt.Printf("%.2f%% of %.2f = %.2f\n", value, amount, result) // 151.00
}
Phone
// Example usage of the Phone value object
package main

import (
	"fmt"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new phone number
	phone, err := valueobject.NewPhone("+1-555-123-4567")
	if err != nil {
		// Handle error
		fmt.Println("Error creating phone:", err)
		return
	}

	// Format in different ways
	fmt.Println(phone.String())                // "+1-555-123-4567"
	fmt.Println(phone.Format("E.164"))         // "+15551234567"
	fmt.Println(phone.Format("national"))      // "(555) 123-4567"
	fmt.Println(phone.Format("international")) // "+1 555 123 4567"

	// Get country code
	countryCode := phone.CountryCode()
	fmt.Printf("Country code: %s\n", countryCode)

	// Check if valid for country
	isValidUS := phone.IsValidForCountry("US")
	fmt.Printf("Valid for US: %v\n", isValidUS)

	// Get normalized version (E.164 format)
	normalized := phone.Normalized()
	fmt.Printf("Normalized: %s\n", normalized)
}
Rating
// Example usage of the Rating value object
package main

import (
	"fmt"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new rating (1-5 scale)
	rating, err := valueobject.NewRating(4.5, 5)
	if err != nil {
		// Handle error
		fmt.Println("Error creating rating:", err)
		return
	}

	// Access values
	value := rating.Value()
	scale := rating.Scale()
	fmt.Printf("Rating: %.1f out of %d\n", value, scale)

	// Format as string
	fmt.Printf("Formatted: %s\n", rating.String()) // "4.5/5"

	// Convert to percentage
	percentage := rating.ToPercentage()
	fmt.Printf("As percentage: %.1f%%\n", percentage) // 90.0%

	// Convert to different scale
	tenScale := rating.ToScale(10)
	fmt.Printf("On 10-point scale: %.1f\n", tenScale) // 9.0
}
Temperature
// Example usage of the Temperature value object
package main

import (
	"fmt"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new temperature in Celsius
	temp, err := valueobject.NewTemperature(25.5, valueobject.Celsius)
	if err != nil {
		// Handle error
		fmt.Println("Error creating temperature:", err)
		return
	}

	// Convert to different units
	fahrenheit := temp.ToFahrenheit()
	kelvin := temp.ToKelvin()
	fmt.Printf("%.1f°C = %.1f°F = %.1fK\n", temp.Value(), fahrenheit, kelvin)

	// Create from Fahrenheit
	tempF, _ := valueobject.NewTemperature(98.6, valueobject.Fahrenheit)
	celsius := tempF.ToCelsius()
	fmt.Printf("%.1f°F = %.1f°C\n", tempF.Value(), celsius)

	// Format with unit
	fmt.Println(temp.String())                     // "25.5°C"
	fmt.Println(temp.Format(valueobject.Fahrenheit)) // "77.9°F"
	fmt.Println(temp.Format(valueobject.Kelvin))     // "298.7K"
}
Version
// Example usage of the Version value object
package main

import (
	"fmt"

	"github.com/abitofhelp/servicelib/valueobject"
)

func main() {
	// Create a new semantic version
	version, err := valueobject.NewVersion("1.2.3")
	if err != nil {
		// Handle error
		fmt.Println("Error creating version:", err)
		return
	}

	// Create with pre-release and build metadata
	versionWithMeta, _ := valueobject.NewVersion("2.0.0-alpha.1+build.123")

	// Access components
	major := version.Major()
	minor := version.Minor()
	patch := version.Patch()
	fmt.Printf("Version: %d.%d.%d\n", major, minor, patch)

	// Get pre-release and build info
	preRelease := versionWithMeta.PreRelease()
	buildMeta := versionWithMeta.BuildMetadata()
	fmt.Printf("Pre-release: %s, Build metadata: %s\n", preRelease, buildMeta)

	// Compare versions
	otherVersion, _ := valueobject.NewVersion("1.3.0")
	isGreater := otherVersion.IsGreaterThan(version)
	fmt.Printf("Is 1.3.0 greater than 1.2.3? %v\n", isGreater) // true

	// Format as string
	fmt.Println(version.String())         // "1.2.3"
	fmt.Println(versionWithMeta.String()) // "2.0.0-alpha.1+build.123"
}

Common Patterns

All Value Objects in this package follow these common patterns:

  1. Constructor Functions: Each Value Object has one or more constructor functions (e.g., New<ObjectName>) that validate inputs and return errors for invalid values.

  2. Parser Functions: Many Value Objects have parser functions to create objects from string representations.

  3. Getter Methods: Value Objects provide getter methods to access their attributes.

  4. String Method: All Value Objects implement the String() method for string representation.

  5. Equals Method: Value Objects provide an Equals() method to compare with other instances.

  6. Domain-Specific Methods: Value Objects include methods specific to their domain (e.g., DistanceTo() for Coordinate).

  7. JSON Marshaling/Unmarshaling: Many Value Objects implement JSON marshaling and unmarshaling for serialization.

Best Practices

  • Always check for errors when creating Value Objects.
  • Treat Value Objects as immutable; never modify their internal state.
  • Use the appropriate Value Object for the domain concept you're modeling.
  • Create custom Value Objects for domain-specific concepts not covered by this package.
  • Use Value Objects to encapsulate validation logic and business rules related to values.

Contributing

If you need a Value Object that isn't provided by this package, consider creating it following the patterns established here and contributing it back to the package.

Documentation

Index

Constants

This section is empty.

Variables

This section is empty.

Functions

This section is empty.

Types

type Address

type Address string

Address represents a postal address value object

func NewAddress

func NewAddress(address string) (Address, error)

NewAddress creates a new Address with validation

func (Address) Equals

func (a Address) Equals(other Address) bool

Equals checks if two Addresses are equal

func (Address) IsEmpty

func (a Address) IsEmpty() bool

IsEmpty checks if the Address is empty

func (Address) String

func (a Address) String() string

String returns the string representation of the Address

type Color

type Color string

Color represents a color value object in hexadecimal format (#RRGGBB)

func NewColor

func NewColor(hexColor string) (Color, error)

NewColor creates a new Color with validation

func (Color) Equals

func (c Color) Equals(other Color) bool

Equals checks if two Colors are equal (case insensitive)

func (Color) Invert

func (c Color) Invert() (Color, error)

Invert returns the inverted color

func (Color) IsDark

func (c Color) IsDark() (bool, error)

IsDark returns true if the color is considered dark

func (Color) IsEmpty

func (c Color) IsEmpty() bool

IsEmpty checks if the Color is empty

func (Color) RGB

func (c Color) RGB() (r, g, b int, err error)

RGB returns the RGB components of the color

func (Color) String

func (c Color) String() string

String returns the string representation of the Color

func (Color) WithAlpha

func (c Color) WithAlpha(alpha int) (string, error)

WithAlpha returns a new color with the specified alpha component (0-255)

type Coordinate

type Coordinate struct {
	// contains filtered or unexported fields
}

Coordinate represents a geographic coordinate (latitude and longitude)

func NewCoordinate

func NewCoordinate(latitude, longitude float64) (Coordinate, error)

NewCoordinate creates a new Coordinate with validation

func ParseCoordinate

func ParseCoordinate(s string) (Coordinate, error)

ParseCoordinate creates a new Coordinate from a string in format "lat,lng"

func (Coordinate) DistanceTo

func (c Coordinate) DistanceTo(other Coordinate) float64

DistanceTo calculates the distance to another coordinate in kilometers using the Haversine formula

func (Coordinate) Equals

func (c Coordinate) Equals(other Coordinate) bool

Equals checks if two Coordinates are equal

func (Coordinate) Format

func (c Coordinate) Format(format string) string

Format returns the coordinate in the specified format Format options: - "dms": Degrees, minutes, seconds (e.g., "41°24'12.2"N, 2°10'26.5"E") - "dm": Degrees and decimal minutes (e.g., "41°24.2033'N, 2°10.4417'E") - "dd": Decimal degrees (e.g., "41.40339, 2.17403")

func (Coordinate) IsEastOf

func (c Coordinate) IsEastOf(other Coordinate) bool

IsEastOf checks if this coordinate is east of another coordinate

func (Coordinate) IsEmpty

func (c Coordinate) IsEmpty() bool

IsEmpty checks if the Coordinate is empty (zero value)

func (Coordinate) IsNorthOf

func (c Coordinate) IsNorthOf(other Coordinate) bool

IsNorthOf checks if this coordinate is north of another coordinate

func (Coordinate) IsSouthOf

func (c Coordinate) IsSouthOf(other Coordinate) bool

IsSouthOf checks if this coordinate is south of another coordinate

func (Coordinate) IsWestOf

func (c Coordinate) IsWestOf(other Coordinate) bool

IsWestOf checks if this coordinate is west of another coordinate

func (Coordinate) Latitude

func (c Coordinate) Latitude() float64

Latitude returns the latitude value

func (Coordinate) Longitude

func (c Coordinate) Longitude() float64

Longitude returns the longitude value

func (Coordinate) String

func (c Coordinate) String() string

String returns the string representation of the Coordinate

type DateOfBirth

type DateOfBirth struct {
	// contains filtered or unexported fields
}

DateOfBirth represents a date of birth value object

func NewDateOfBirth

func NewDateOfBirth(year, month, day int) (DateOfBirth, error)

NewDateOfBirth creates a new DateOfBirth with validation

func ParseDateOfBirth

func ParseDateOfBirth(dateStr string) (DateOfBirth, error)

ParseDateOfBirth creates a new DateOfBirth from a string in format "YYYY-MM-DD"

func (DateOfBirth) Age

func (dob DateOfBirth) Age() int

Age calculates the age based on the date of birth and current date

func (DateOfBirth) Date

func (dob DateOfBirth) Date() time.Time

Date returns the underlying time.Time value

func (DateOfBirth) Equals

func (dob DateOfBirth) Equals(other DateOfBirth) bool

Equals checks if two DateOfBirth values are equal

func (DateOfBirth) Format

func (dob DateOfBirth) Format(layout string) string

Format returns the date formatted according to the given layout

func (DateOfBirth) IsAdult

func (dob DateOfBirth) IsAdult() bool

IsAdult checks if the person is an adult (18 years or older)

func (DateOfBirth) IsEmpty

func (dob DateOfBirth) IsEmpty() bool

IsEmpty checks if the DateOfBirth is empty (zero value)

func (DateOfBirth) String

func (dob DateOfBirth) String() string

String returns the string representation of the DateOfBirth

type DateOfDeath

type DateOfDeath struct {
	// contains filtered or unexported fields
}

DateOfDeath represents a date of death value object

func NewDateOfDeath

func NewDateOfDeath(year, month, day int) (DateOfDeath, error)

NewDateOfDeath creates a new DateOfDeath with validation

func ParseDateOfDeath

func ParseDateOfDeath(dateStr string) (DateOfDeath, error)

ParseDateOfDeath creates a new DateOfDeath from a string in format "YYYY-MM-DD"

func (DateOfDeath) Date

func (dod DateOfDeath) Date() time.Time

Date returns the underlying time.Time value

func (DateOfDeath) Equals

func (dod DateOfDeath) Equals(other DateOfDeath) bool

Equals checks if two DateOfDeath values are equal

func (DateOfDeath) Format

func (dod DateOfDeath) Format(layout string) string

Format returns the date formatted according to the given layout

func (DateOfDeath) IsEmpty

func (dod DateOfDeath) IsEmpty() bool

IsEmpty checks if the DateOfDeath is empty (zero value)

func (DateOfDeath) IsRecent

func (dod DateOfDeath) IsRecent() bool

IsRecent checks if the death occurred within the last year

func (DateOfDeath) String

func (dod DateOfDeath) String() string

String returns the string representation of the DateOfDeath

func (DateOfDeath) TimeSinceDeath

func (dod DateOfDeath) TimeSinceDeath() int

TimeSinceDeath calculates the time elapsed since death in years

type Duration

type Duration struct {
	// contains filtered or unexported fields
}

Duration represents a time duration value object

func NewDuration

func NewDuration(duration time.Duration) (Duration, error)

NewDuration creates a new Duration with validation

func ParseDuration

func ParseDuration(s string) (Duration, error)

ParseDuration creates a new Duration from a string

func (Duration) Add

func (d Duration) Add(other Duration) (Duration, error)

Add adds another Duration and returns a new Duration

func (Duration) Equals

func (d Duration) Equals(other Duration) bool

Equals checks if two Durations are equal

func (Duration) Format

func (d Duration) Format(format string) string

Format returns a formatted string representation of the duration Format options: - "short": "1h 30m 45s" - "long": "1 hour 30 minutes 45 seconds" - "compact": "1:30:45"

func (Duration) Hours

func (d Duration) Hours() float64

Hours returns the duration as a floating point number of hours

func (Duration) IsEmpty

func (d Duration) IsEmpty() bool

IsEmpty checks if the Duration is zero

func (Duration) Milliseconds

func (d Duration) Milliseconds() int64

Milliseconds returns the duration as an integer number of milliseconds

func (Duration) Minutes

func (d Duration) Minutes() float64

Minutes returns the duration as a floating point number of minutes

func (Duration) Seconds

func (d Duration) Seconds() float64

Seconds returns the duration as a floating point number of seconds

func (Duration) String

func (d Duration) String() string

String returns the string representation of the Duration

func (Duration) Subtract

func (d Duration) Subtract(other Duration) (Duration, error)

Subtract subtracts another Duration and returns a new Duration If the result would be negative, it returns zero duration

func (Duration) Value

func (d Duration) Value() time.Duration

Value returns the underlying time.Duration value

type Email

type Email string

Email represents an email address value object

func NewEmail

func NewEmail(email string) (Email, error)

NewEmail creates a new Email with validation

func (Email) Equals

func (e Email) Equals(other Email) bool

Equals checks if two Emails are equal

func (Email) IsEmpty

func (e Email) IsEmpty() bool

IsEmpty checks if the Email is empty

func (Email) String

func (e Email) String() string

String returns the string representation of the Email

type FileSize

type FileSize struct {
	// contains filtered or unexported fields
}

FileSize represents a file size value object

func NewFileSize

func NewFileSize(value float64, unit FileSizeUnit) (FileSize, error)

NewFileSize creates a new FileSize with validation

func ParseFileSize

func ParseFileSize(s string) (FileSize, error)

ParseFileSize creates a new FileSize from a string

func (FileSize) Add

func (fs FileSize) Add(other FileSize) FileSize

Add adds another FileSize and returns a new FileSize

func (FileSize) Bytes

func (fs FileSize) Bytes() uint64

Bytes returns the size in bytes

func (FileSize) Equals

func (fs FileSize) Equals(other FileSize) bool

Equals checks if two FileSizes are equal

func (FileSize) Format

func (fs FileSize) Format(format string) string

Format returns the file size in the specified format Format options: - "B": Always in bytes - "KB": Always in kilobytes - "MB": Always in megabytes - "GB": Always in gigabytes - "TB": Always in terabytes - "PB": Always in petabytes - "auto": Uses the most appropriate unit for readability - "binary": Uses binary prefixes (KiB, MiB, GiB, etc.) - "decimal": Uses decimal prefixes (KB, MB, GB, etc.)

func (FileSize) Gigabytes

func (fs FileSize) Gigabytes() float64

Gigabytes returns the size in gigabytes

func (FileSize) IsEmpty

func (fs FileSize) IsEmpty() bool

IsEmpty checks if the FileSize is empty (zero value)

func (FileSize) IsLargerThan

func (fs FileSize) IsLargerThan(other FileSize) bool

IsLargerThan checks if this FileSize is larger than another FileSize

func (FileSize) IsSmallerThan

func (fs FileSize) IsSmallerThan(other FileSize) bool

IsSmallerThan checks if this FileSize is smaller than another FileSize

func (FileSize) Kilobytes

func (fs FileSize) Kilobytes() float64

Kilobytes returns the size in kilobytes

func (FileSize) Megabytes

func (fs FileSize) Megabytes() float64

Megabytes returns the size in megabytes

func (FileSize) Petabytes

func (fs FileSize) Petabytes() float64

Petabytes returns the size in petabytes

func (FileSize) String

func (fs FileSize) String() string

String returns the string representation of the FileSize Uses the most appropriate unit for readability

func (FileSize) Subtract

func (fs FileSize) Subtract(other FileSize) FileSize

Subtract subtracts another FileSize and returns a new FileSize If the result would be negative, it returns zero

func (FileSize) Terabytes

func (fs FileSize) Terabytes() float64

Terabytes returns the size in terabytes

type FileSizeUnit

type FileSizeUnit string

FileSizeUnit represents a file size unit

const (
	// Bytes unit (B)
	Bytes FileSizeUnit = "B"
	// Kilobytes unit (KB)
	Kilobytes FileSizeUnit = "KB"
	// Megabytes unit (MB)
	Megabytes FileSizeUnit = "MB"
	// Gigabytes unit (GB)
	Gigabytes FileSizeUnit = "GB"
	// Terabytes unit (TB)
	Terabytes FileSizeUnit = "TB"
	// Petabytes unit (PB)
	Petabytes FileSizeUnit = "PB"
)

type Gender

type Gender string

Gender represents a person's gender value object

const (
	GenderMale   Gender = "male"
	GenderFemale Gender = "female"
	GenderOther  Gender = "other"
)

func NewGender

func NewGender(gender string) (Gender, error)

NewGender creates a new Gender with validation

func (Gender) Equals

func (g Gender) Equals(other Gender) bool

Equals checks if two Genders are equal

func (Gender) IsEmpty

func (g Gender) IsEmpty() bool

IsEmpty checks if the Gender is empty

func (Gender) String

func (g Gender) String() string

String returns the string representation of the Gender

type ID

type ID string

ID represents a unique identifier value object

func GenerateID

func GenerateID() ID

GenerateID creates a new random ID

func NewID

func NewID(id string) (ID, error)

NewID creates a new ID with validation

func (ID) Equals

func (id ID) Equals(other ID) bool

Equals checks if two IDs are equal

func (ID) IsEmpty

func (id ID) IsEmpty() bool

IsEmpty checks if the ID is empty

func (ID) String

func (id ID) String() string

String returns the string representation of the ID

type IPAddress

type IPAddress string

IPAddress represents an IP address value object that supports both IPv4 and IPv6 formats

func NewIPAddress

func NewIPAddress(ip string) (IPAddress, error)

NewIPAddress creates a new IPAddress with validation for both IPv4 and IPv6 formats It uses Go's net.ParseIP function which supports both IPv4 (e.g., "192.168.1.1") and IPv6 (e.g., "2001:db8::1") address formats

func (IPAddress) Equals

func (ip IPAddress) Equals(other IPAddress) bool

Equals checks if two IPAddresses are equal Properly handles comparison of both IPv4 and IPv6 addresses in different representations (e.g., IPv4 mapped to IPv6, or different IPv6 notations for the same address)

func (IPAddress) IsEmpty

func (ip IPAddress) IsEmpty() bool

IsEmpty checks if the IPAddress is empty

func (IPAddress) IsIPv4

func (ip IPAddress) IsIPv4() bool

IsIPv4 checks if the IP address is in IPv4 format (e.g., "192.168.1.1") Returns true only for valid IPv4 addresses, false for IPv6 addresses or invalid formats

func (IPAddress) IsIPv6

func (ip IPAddress) IsIPv6() bool

IsIPv6 checks if the IP address is in IPv6 format (e.g., "2001:db8::1") Returns true only for valid IPv6 addresses, false for IPv4 addresses or invalid formats

func (IPAddress) IsLoopback

func (ip IPAddress) IsLoopback() bool

IsLoopback checks if the IP address is a loopback address Works with both IPv4 loopback (127.0.0.0/8) and IPv6 loopback (::1) addresses

func (IPAddress) IsPrivate

func (ip IPAddress) IsPrivate() bool

IsPrivate checks if the IP address is in a private range Supports both IPv4 private ranges (10.0.0.0/8, 172.16.0.0/12, 192.168.0.0/16) and IPv6 private ranges (fc00::/7)

func (IPAddress) String

func (ip IPAddress) String() string

String returns the string representation of the IPAddress

type Money

type Money struct {
	// contains filtered or unexported fields
}

Money represents a monetary value object with amount and currency Uses decimal.Decimal to store amount with arbitrary precision to avoid floating-point precision issues

This implementation uses the github.com/shopspring/decimal package instead of int64 for the following reasons: 1. Decimal arithmetic is more precise than floating-point arithmetic for monetary values 2. It can handle arbitrary precision, which is important for financial calculations 3. It provides methods for rounding, scaling, and other operations that are useful for monetary values 4. It avoids common floating-point errors like 0.1 + 0.2 != 0.3

Note: This implementation requires the github.com/shopspring/decimal package to be added to the project's dependencies with: go get github.com/shopspring/decimal

func Max

func Max(a, b Money) (Money, error)

Max returns the larger of two Money values Both Money values must have the same currency

func Min

func Min(a, b Money) (Money, error)

Min returns the smaller of two Money values Both Money values must have the same currency

func NewMoneyFromFloat64

func NewMoneyFromFloat64(amount float64, currency string) (Money, error)

NewMoneyFromFloat64 creates a new Money with validation from a float64 amount

func NewMoneyFromString

func NewMoneyFromString(amount string, currency string) (Money, error)

NewMoneyFromString creates a new Money with validation from a string amount This is more precise than using a float64 for monetary values

func NewMoneyFromUint64

func NewMoneyFromUint64(amount uint64, currency string) (Money, error)

NewMoneyFromUint64 creates a new Money with validation from a uint64 amount This is useful for representing monetary values in the smallest currency unit (e.g., cents)

func Parse

func Parse(s string) (Money, error)

Parse creates a Money object from a string representation like "10.99 USD"

func (Money) Abs

func (m Money) Abs() Money

Abs returns the absolute value of the Money

func (Money) Add

func (m Money) Add(other Money) (Money, error)

Add adds another Money value and returns a new Money Both Money values must have the same currency

func (Money) Amount

func (m Money) Amount() float64

Amount returns the amount as a float64 in the standard currency unit (e.g., dollars) This is for backward compatibility with the previous API

func (Money) AmountInCents

func (m Money) AmountInCents() int64

AmountInCents returns the amount in the smallest currency unit (e.g., cents)

func (Money) Currency

func (m Money) Currency() string

Currency returns the currency code

func (Money) Divide

func (m Money) Divide(divisor decimal.Decimal) (Money, error)

Divide divides the money amount by a divisor (e.g., for splitting payments) and returns a new Money object Returns an error if the divisor is zero

func (Money) Equals

func (m Money) Equals(other Money) bool

Equals checks if two Money values are equal

func (Money) IsGreaterThan

func (m Money) IsGreaterThan(other Money) (bool, error)

IsGreaterThan checks if the Money amount is greater than another Money amount Returns an error if the currencies are different

func (Money) IsLessThan

func (m Money) IsLessThan(other Money) (bool, error)

IsLessThan checks if the Money amount is less than another Money amount Returns an error if the currencies are different

func (Money) IsNegative

func (m Money) IsNegative() bool

IsNegative checks if the Money amount is negative

func (Money) IsPositive

func (m Money) IsPositive() bool

IsPositive checks if the Money amount is positive

func (Money) IsZero

func (m Money) IsZero() bool

IsZero checks if the Money amount is zero

func (Money) MarshalJSON

func (m Money) MarshalJSON() ([]byte, error)

MarshalJSON implements the json.Marshaler interface

func (Money) Multiply

func (m Money) Multiply(factor decimal.Decimal) Money

Multiply multiplies the money amount by a factor (e.g., for calculating interest) and returns a new Money object

func (Money) Negate

func (m Money) Negate() Money

Negate returns the negated value of the Money

func (Money) Round

func (m Money) Round(places int32) Money

Round rounds the money amount to the specified number of decimal places and returns a new Money object

func (Money) Scale

func (m Money) Scale(factor decimal.Decimal, newCurrency string) (Money, error)

Scale scales the money amount by a factor (e.g., for currency conversion) and returns a new Money with the specified currency

func (Money) String

func (m Money) String() string

String returns the string representation of the Money

func (Money) Subtract

func (m Money) Subtract(other Money) (Money, error)

Subtract subtracts another Money value and returns a new Money Both Money values must have the same currency

func (*Money) UnmarshalJSON

func (m *Money) UnmarshalJSON(data []byte) error

UnmarshalJSON implements the json.Unmarshaler interface

type MoneyJSON

type MoneyJSON struct {
	Amount   string `json:"amount"`
	Currency string `json:"currency"`
}

MoneyJSON is a struct used for JSON marshaling and unmarshaling

type Name

type Name string

Name represents a person's name value object

func NewName

func NewName(name string) (Name, error)

NewName creates a new Name with validation

func (Name) Equals

func (n Name) Equals(other Name) bool

Equals checks if two Names are equal

func (Name) IsEmpty

func (n Name) IsEmpty() bool

IsEmpty checks if the Name is empty

func (Name) String

func (n Name) String() string

String returns the string representation of the Name

type Password

type Password struct {
	// contains filtered or unexported fields
}

Password represents a password value object It stores the hashed password, not the plain text

func NewPassword

func NewPassword(plainPassword string) (Password, error)

NewPassword creates a new Password with validation and hashing

func (Password) Equals

func (p Password) Equals(other Password) bool

Equals checks if two Password values are equal This compares the underlying hashed passwords

func (Password) HashedPassword

func (p Password) HashedPassword() string

HashedPassword returns the base64-encoded hashed password

func (Password) IsEmpty

func (p Password) IsEmpty() bool

IsEmpty checks if the Password is empty

func (Password) Salt

func (p Password) Salt() []byte

Salt returns a copy of the salt used for hashing

func (Password) String

func (p Password) String() string

String returns a masked representation of the password Never returns the actual password or hash

func (Password) Verify

func (p Password) Verify(plainPassword string) bool

Verify checks if the provided plain password matches the stored hashed password

type Percentage

type Percentage float64

Percentage represents a percentage value object

func NewPercentage

func NewPercentage(value float64) (Percentage, error)

NewPercentage creates a new Percentage with validation

func ParsePercentage

func ParsePercentage(s string) (Percentage, error)

ParsePercentage creates a new Percentage from a string

func (Percentage) Add

func (p Percentage) Add(other Percentage) (Percentage, error)

Add adds another percentage and returns a new Percentage The result is capped at 100%

func (Percentage) AsDecimal

func (p Percentage) AsDecimal() float64

AsDecimal returns the percentage as a decimal (e.g., 75% -> 0.75)

func (Percentage) Equals

func (p Percentage) Equals(other Percentage) bool

Equals checks if two Percentages are equal

func (Percentage) Inverse

func (p Percentage) Inverse() (Percentage, error)

Inverse returns the inverse percentage (100% - p)

func (Percentage) IsEmpty

func (p Percentage) IsEmpty() bool

IsEmpty checks if the Percentage is zero

func (Percentage) Of

func (p Percentage) Of(value float64) float64

Of calculates the percentage of a given value For example: 25% of 200 = 50

func (Percentage) String

func (p Percentage) String() string

String returns the string representation of the Percentage

func (Percentage) Subtract

func (p Percentage) Subtract(other Percentage) (Percentage, error)

Subtract subtracts another percentage and returns a new Percentage The result is floored at 0%

func (Percentage) Value

func (p Percentage) Value() float64

Value returns the raw float64 value

type Phone

type Phone string

Phone represents a phone number value object

func NewPhone

func NewPhone(phone string) (Phone, error)

NewPhone creates a new Phone with validation

func (Phone) Equals

func (p Phone) Equals(other Phone) bool

Equals checks if two Phones are equal

func (Phone) IsEmpty

func (p Phone) IsEmpty() bool

IsEmpty checks if the Phone is empty

func (Phone) String

func (p Phone) String() string

String returns the string representation of the Phone

type Rating

type Rating struct {
	// contains filtered or unexported fields
}

Rating represents a rating value object (e.g., 1-5 stars)

func NewRating

func NewRating(value float64, maxValue float64) (Rating, error)

NewRating creates a new Rating with validation

func ParseRating

func ParseRating(s string) (Rating, error)

ParseRating creates a new Rating from a string Formats supported: - "4" (assumes max value of 5) - "4/5" (explicit max value) - "8/10" (explicit max value)

func (Rating) Equals

func (r Rating) Equals(other Rating) bool

Equals checks if two Ratings are equal This compares the normalized values (value/maxValue)

func (Rating) Format

func (r Rating) Format(format string) string

Format returns the rating in the specified format Format options: - "decimal": "4.5/5.0" - "percentage": "90%" - "stars": "★★★★½" - "fraction": "9/10"

func (Rating) IsEmpty

func (r Rating) IsEmpty() bool

IsEmpty checks if the Rating is empty (zero value)

func (Rating) IsHigher

func (r Rating) IsHigher(other Rating) bool

IsHigher checks if this rating is higher than another rating This compares the normalized values to handle different scales

func (Rating) IsLower

func (r Rating) IsLower(other Rating) bool

IsLower checks if this rating is lower than another rating This compares the normalized values to handle different scales

func (Rating) MaxValue

func (r Rating) MaxValue() float64

MaxValue returns the maximum rating value

func (Rating) Normalized

func (r Rating) Normalized() float64

Normalized returns the rating normalized to a 0-1 scale

func (Rating) Percentage

func (r Rating) Percentage() float64

Percentage returns the rating as a percentage of the maximum value

func (Rating) Stars

func (r Rating) Stars() string

Stars returns the rating as a string of stars (★) and empty stars (☆) For example, a rating of 3.5/5 would return "★★★½☆"

func (Rating) String

func (r Rating) String() string

String returns the string representation of the Rating

func (Rating) ToScale

func (r Rating) ToScale(newMaxValue float64) (Rating, error)

ToScale converts the rating to a different scale

func (Rating) Value

func (r Rating) Value() float64

Value returns the rating value

type Temperature

type Temperature struct {
	// contains filtered or unexported fields
}

Temperature represents a temperature value object

func NewTemperature

func NewTemperature(value float64, unit TemperatureUnit) (Temperature, error)

NewTemperature creates a new Temperature with validation

func ParseTemperature

func ParseTemperature(s string) (Temperature, error)

ParseTemperature creates a new Temperature from a string

func (Temperature) Add

func (t Temperature) Add(other Temperature) Temperature

Add adds another temperature and returns a new Temperature

func (Temperature) Equals

func (t Temperature) Equals(other Temperature) bool

Equals checks if two Temperatures are equal This compares the actual temperature values, not just the raw values and units

func (Temperature) Format

func (t Temperature) Format(format string) string

Format returns the temperature in the specified format Format options: - "short": "25°C" - "long": "25 degrees Celsius" - "scientific": "298.15K"

func (Temperature) IsBoiling

func (t Temperature) IsBoiling() bool

IsBoiling checks if the temperature is at or above the boiling point of water

func (Temperature) IsEmpty

func (t Temperature) IsEmpty() bool

IsEmpty checks if the Temperature is empty (zero value)

func (Temperature) IsFreezing

func (t Temperature) IsFreezing() bool

IsFreezing checks if the temperature is at or below the freezing point of water

func (Temperature) String

func (t Temperature) String() string

String returns the string representation of the Temperature

func (Temperature) Subtract

func (t Temperature) Subtract(other Temperature) (Temperature, error)

Subtract subtracts another temperature and returns a new Temperature

func (Temperature) ToCelsius

func (t Temperature) ToCelsius() Temperature

ToCelsius converts the temperature to Celsius

func (Temperature) ToFahrenheit

func (t Temperature) ToFahrenheit() Temperature

ToFahrenheit converts the temperature to Fahrenheit

func (Temperature) ToKelvin

func (t Temperature) ToKelvin() Temperature

ToKelvin converts the temperature to Kelvin

func (Temperature) Unit

func (t Temperature) Unit() TemperatureUnit

Unit returns the temperature unit

func (Temperature) Value

func (t Temperature) Value() float64

Value returns the temperature value

type TemperatureUnit

type TemperatureUnit string

TemperatureUnit represents a temperature unit

const (
	// Celsius temperature unit (°C)
	Celsius TemperatureUnit = "C"
	// Fahrenheit temperature unit (°F)
	Fahrenheit TemperatureUnit = "F"
	// Kelvin temperature unit (K)
	Kelvin TemperatureUnit = "K"
)

type URL

type URL string

URL represents a URL value object

func NewURL

func NewURL(rawURL string) (URL, error)

NewURL creates a new URL with validation

func (URL) Domain

func (u URL) Domain() (string, error)

Domain returns the domain part of the URL

func (URL) Equals

func (u URL) Equals(other URL) bool

Equals checks if two URLs are equal

func (URL) IsEmpty

func (u URL) IsEmpty() bool

IsEmpty checks if the URL is empty

func (URL) Path

func (u URL) Path() (string, error)

Path returns the path part of the URL

func (URL) Query

func (u URL) Query() (url.Values, error)

Query returns the query part of the URL

func (URL) String

func (u URL) String() string

String returns the string representation of the URL

type Username

type Username string

Username represents a username value object

func NewUsername

func NewUsername(username string) (Username, error)

NewUsername creates a new Username with validation

func (Username) ContainsSubstring

func (u Username) ContainsSubstring(substring string) bool

ContainsSubstring checks if the username contains the given substring (case insensitive)

func (Username) Equals

func (u Username) Equals(other Username) bool

Equals checks if two Usernames are equal (case insensitive)

func (Username) IsEmpty

func (u Username) IsEmpty() bool

IsEmpty checks if the Username is empty

func (Username) Length

func (u Username) Length() int

Length returns the length of the username

func (Username) String

func (u Username) String() string

String returns the string representation of the Username

func (Username) ToLower

func (u Username) ToLower() Username

ToLower returns the lowercase version of the username

type Version

type Version struct {
	// contains filtered or unexported fields
}

Version represents a semantic version (major.minor.patch)

func NewVersion

func NewVersion(major, minor, patch int, preRelease, build string) (Version, error)

NewVersion creates a new Version with validation

func ParseVersion

func ParseVersion(s string) (Version, error)

ParseVersion creates a new Version from a string in format "major.minor.patch[-prerelease][+build]"

func (Version) Build

func (v Version) Build() string

Build returns the build metadata

func (Version) CompareTo

func (v Version) CompareTo(other Version) int

CompareTo compares this version to another version Returns:

-1 if this version is less than the other
 0 if this version is equal to the other
 1 if this version is greater than the other

func (Version) Equals

func (v Version) Equals(other Version) bool

Equals checks if two Versions are equal

func (Version) IsEmpty

func (v Version) IsEmpty() bool

IsEmpty checks if the Version is empty (zero value)

func (Version) IsPreRelease

func (v Version) IsPreRelease() bool

IsPreRelease checks if this is a pre-release version

func (Version) Major

func (v Version) Major() int

Major returns the major version number

func (Version) Minor

func (v Version) Minor() int

Minor returns the minor version number

func (Version) NextMajor

func (v Version) NextMajor() Version

NextMajor returns the next major version

func (Version) NextMinor

func (v Version) NextMinor() Version

NextMinor returns the next minor version

func (Version) NextPatch

func (v Version) NextPatch() Version

NextPatch returns the next patch version

func (Version) Patch

func (v Version) Patch() int

Patch returns the patch version number

func (Version) PreRelease

func (v Version) PreRelease() string

PreRelease returns the pre-release identifier

func (Version) String

func (v Version) String() string

String returns the string representation of the Version

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL