it/date_time.go   A
last analyzed

Size/Duplication

Total Lines 102
Duplicated Lines 0 %

Importance

Changes 0
Metric Value
cc 14
eloc 54
dl 0
loc 102
rs 10
c 0
b 0
f 0

9 Methods

Rating   Name   Duplication   Size   Complexity  
A it.IsDate 0 5 1
A it.DateTimeConstraint.WithMessage 0 4 1
A it.IsTime 0 5 1
A it.DateTimeConstraint.WithLayout 0 3 1
A it.IsDateTime 0 5 1
A it.DateTimeConstraint.WithError 0 3 1
A it.DateTimeConstraint.When 0 3 1
A it.DateTimeConstraint.WhenGroups 0 3 1
B it.DateTimeConstraint.ValidateString 0 16 6
1
package it
2
3
import (
4
	"context"
5
	"time"
6
7
	"github.com/muonsoft/validation"
8
)
9
10
// DateTimeConstraint checks that the string value is a valid date and time value specified by a specific layout.
11
// The layout can be redefined using the [DateTimeConstraint.WithLayout] method.
12
type DateTimeConstraint struct {
13
	isIgnored         bool
14
	groups            []string
15
	err               error
16
	layout            string
17
	messageTemplate   string
18
	messageParameters validation.TemplateParameterList
19
}
20
21
// IsDateTime checks that the string value is a valid date and time. By default, it uses [time.RFC3339] layout.
22
// The layout can be redefined using the [DateTimeConstraint.WithLayout] method.
23
func IsDateTime() DateTimeConstraint {
24
	return DateTimeConstraint{
25
		layout:          time.RFC3339,
26
		err:             validation.ErrInvalidDateTime,
27
		messageTemplate: validation.ErrInvalidDateTime.Message(),
28
	}
29
}
30
31
// IsDate checks that the string value is a valid date. It uses "2006-01-02" layout.
32
// The layout can be redefined using the [DateTimeConstraint.WithLayout] method.
33
func IsDate() DateTimeConstraint {
34
	return DateTimeConstraint{
35
		layout:          "2006-01-02",
36
		err:             validation.ErrInvalidDate,
37
		messageTemplate: validation.ErrInvalidDate.Message(),
38
	}
39
}
40
41
// IsTime checks that the string value is a valid time. It uses "15:04:05" layout.
42
// The layout can be redefined using the WithLayout method.
43
func IsTime() DateTimeConstraint {
44
	return DateTimeConstraint{
45
		layout:          "15:04:05",
46
		err:             validation.ErrInvalidTime,
47
		messageTemplate: validation.ErrInvalidTime.Message(),
48
	}
49
}
50
51
// WithLayout specifies the layout to be used for datetime parsing.
52
func (c DateTimeConstraint) WithLayout(layout string) DateTimeConstraint {
53
	c.layout = layout
54
	return c
55
}
56
57
// WithError overrides default error for produced violation.
58
func (c DateTimeConstraint) WithError(err error) DateTimeConstraint {
59
	c.err = err
60
	return c
61
}
62
63
// WithMessage sets the violation message template. You can set custom template parameters
64
// for injecting its values into the final message. Also, you can use default parameters:
65
//
66
//	{{ layout }} - date time layout used for parsing;
67
//	{{ value }} - the current (invalid) value.
68
func (c DateTimeConstraint) WithMessage(template string, parameters ...validation.TemplateParameter) DateTimeConstraint {
69
	c.messageTemplate = template
70
	c.messageParameters = parameters
71
	return c
72
}
73
74
// When enables conditional validation of this constraint. If the expression evaluates to false,
75
// then the constraint will be ignored.
76
func (c DateTimeConstraint) When(condition bool) DateTimeConstraint {
77
	c.isIgnored = !condition
78
	return c
79
}
80
81
// WhenGroups enables conditional validation of the constraint by using the validation groups.
82
func (c DateTimeConstraint) WhenGroups(groups ...string) DateTimeConstraint {
83
	c.groups = groups
84
	return c
85
}
86
87
func (c DateTimeConstraint) ValidateString(ctx context.Context, validator *validation.Validator, value *string) error {
88
	if c.isIgnored || validator.IsIgnoredForGroups(c.groups...) || value == nil || *value == "" {
89
		return nil
90
	}
91
	if _, err := time.Parse(c.layout, *value); err == nil {
92
		return nil
93
	}
94
95
	return validator.BuildViolation(ctx, c.err, c.messageTemplate).
96
		WithParameters(
97
			c.messageParameters.Prepend(
98
				validation.TemplateParameter{Key: "{{ layout }}", Value: c.layout},
99
				validation.TemplateParameter{Key: "{{ value }}", Value: *value},
100
			)...,
101
		).
102
		WithParameter("{{ value }}", *value).Create()
103
}
104