summary.go 2.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100
  1. // Copyright (c) Tailscale Inc & AUTHORS
  2. // SPDX-License-Identifier: BSD-3-Clause
  3. package setting
  4. import (
  5. jsonv2 "github.com/go-json-experiment/json"
  6. "github.com/go-json-experiment/json/jsontext"
  7. "tailscale.com/types/opt"
  8. )
  9. // Summary is an immutable [PolicyScope] and [Origin].
  10. type Summary struct {
  11. data summary
  12. }
  13. type summary struct {
  14. Scope opt.Value[PolicyScope] `json:",omitzero"`
  15. Origin opt.Value[Origin] `json:",omitzero"`
  16. }
  17. // SummaryWith returns a [Summary] with the specified options.
  18. func SummaryWith(opts ...SummaryOption) Summary {
  19. var summary Summary
  20. for _, o := range opts {
  21. o.applySummaryOption(&summary)
  22. }
  23. return summary
  24. }
  25. // IsEmpty reports whether s is empty.
  26. func (s Summary) IsEmpty() bool {
  27. return s == Summary{}
  28. }
  29. // Scope reports the [PolicyScope] in s.
  30. func (s Summary) Scope() opt.Value[PolicyScope] {
  31. return s.data.Scope
  32. }
  33. // Origin reports the [Origin] in s.
  34. func (s Summary) Origin() opt.Value[Origin] {
  35. return s.data.Origin
  36. }
  37. // String implements [fmt.Stringer].
  38. func (s Summary) String() string {
  39. if s.IsEmpty() {
  40. return "{Empty}"
  41. }
  42. if origin, ok := s.data.Origin.GetOk(); ok {
  43. return origin.String()
  44. }
  45. return s.data.Scope.String()
  46. }
  47. // MarshalJSONV2 implements [jsonv2.MarshalerV2].
  48. func (s Summary) MarshalJSONV2(out *jsontext.Encoder, opts jsonv2.Options) error {
  49. return jsonv2.MarshalEncode(out, &s.data, opts)
  50. }
  51. // UnmarshalJSONV2 implements [jsonv2.UnmarshalerV2].
  52. func (s *Summary) UnmarshalJSONV2(in *jsontext.Decoder, opts jsonv2.Options) error {
  53. return jsonv2.UnmarshalDecode(in, &s.data, opts)
  54. }
  55. // MarshalJSON implements [json.Marshaler].
  56. func (s Summary) MarshalJSON() ([]byte, error) {
  57. return jsonv2.Marshal(s) // uses MarshalJSONV2
  58. }
  59. // UnmarshalJSON implements [json.Unmarshaler].
  60. func (s *Summary) UnmarshalJSON(b []byte) error {
  61. return jsonv2.Unmarshal(b, s) // uses UnmarshalJSONV2
  62. }
  63. // SummaryOption is an option that configures [Summary]
  64. // The following are allowed options:
  65. //
  66. // - [Summary]
  67. // - [PolicyScope]
  68. // - [Origin]
  69. type SummaryOption interface {
  70. applySummaryOption(summary *Summary)
  71. }
  72. func (s PolicyScope) applySummaryOption(summary *Summary) {
  73. summary.data.Scope.Set(s)
  74. }
  75. func (o Origin) applySummaryOption(summary *Summary) {
  76. summary.data.Origin.Set(o)
  77. if !summary.data.Scope.IsSet() {
  78. summary.data.Scope.Set(o.Scope())
  79. }
  80. }
  81. func (s Summary) applySummaryOption(summary *Summary) {
  82. *summary = s
  83. }