_MethodConfigurations.swift 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105
  1. /*
  2. * Copyright 2023, gRPC Authors All rights reserved.
  3. *
  4. * Licensed under the Apache License, Version 2.0 (the "License");
  5. * you may not use this file except in compliance with the License.
  6. * You may obtain a copy of the License at
  7. *
  8. * http://www.apache.org/licenses/LICENSE-2.0
  9. *
  10. * Unless required by applicable law or agreed to in writing, software
  11. * distributed under the License is distributed on an "AS IS" BASIS,
  12. * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  13. * See the License for the specific language governing permissions and
  14. * limitations under the License.
  15. */
  16. // TODO: when swift(>=5.9), use 'package' access level
  17. /// A collection of ``MethodConfiguration``s, mapped to specific methods or services.
  18. ///
  19. /// When creating a new instance, no overrides and no default will be set for using when getting
  20. /// a configuration for a method that has not been given a specific override.
  21. /// Use ``setDefaultConfiguration(_:forService:)`` to set a specific override for a whole
  22. /// service, or set a default configuration for all methods by calling ``setDefaultConfiguration(_:)``.
  23. ///
  24. /// Use the subscript to get and set configurations for specific methods.
  25. @available(macOS 13.0, iOS 16.0, watchOS 9.0, tvOS 16.0, *)
  26. public struct _MethodConfigurations: Sendable, Hashable {
  27. private var elements: [MethodConfiguration.Name: MethodConfiguration]
  28. /// Create a new ``_MethodConfigurations``.
  29. ///
  30. /// - Parameter serviceConfiguration: The configuration to read ``MethodConfiguration`` from.
  31. public init(serviceConfiguration: ServiceConfiguration = ServiceConfiguration()) {
  32. self.elements = [:]
  33. for configuration in serviceConfiguration.methodConfiguration {
  34. for name in configuration.names {
  35. self.elements[name] = configuration
  36. }
  37. }
  38. }
  39. /// Get or set the corresponding ``MethodConfiguration`` for the given ``MethodDescriptor``.
  40. ///
  41. /// Configuration is hierarchical and can be set per-method, per-service
  42. /// (``setDefaultConfiguration(_:forService:)``) and globally (``setDefaultConfiguration(_:)``).
  43. /// This subscript sets the per-method configuration but retrieves a configuration respecting
  44. /// the hierarchy. If no per-method configuration is present, the per-service configuration is
  45. /// checked and returned if present. If the per-service configuration isn't present then the
  46. /// global configuration is returned, if present.
  47. ///
  48. /// - Parameters:
  49. /// - descriptor: The ``MethodDescriptor`` for which to get or set a ``MethodConfiguration``.
  50. public subscript(_ descriptor: MethodDescriptor) -> MethodConfiguration? {
  51. get {
  52. var name = MethodConfiguration.Name(service: descriptor.service, method: descriptor.method)
  53. if let configuration = self.elements[name] {
  54. return configuration
  55. }
  56. // Check if the config is set at the service level by clearing the method.
  57. name.method = ""
  58. if let configuration = self.elements[name] {
  59. return configuration
  60. }
  61. // Check if the config is set at the global level by clearing the service and method.
  62. name.service = ""
  63. return self.elements[name]
  64. }
  65. set {
  66. let name = MethodConfiguration.Name(service: descriptor.service, method: descriptor.method)
  67. self.elements[name] = newValue
  68. }
  69. }
  70. /// Set a default configuration for all methods that have no overrides.
  71. ///
  72. /// - Parameter configuration: The default configuration.
  73. public mutating func setDefaultConfiguration(_ configuration: MethodConfiguration?) {
  74. let name = MethodConfiguration.Name(service: "", method: "")
  75. self.elements[name] = configuration
  76. }
  77. /// Set a default configuration for a service.
  78. ///
  79. /// If getting a configuration for a method that's part of a service, and the method itself doesn't have an
  80. /// override, then this configuration will be used instead of the default configuration passed when creating
  81. /// this instance of ``MethodConfigurations``.
  82. ///
  83. /// - Parameters:
  84. /// - configuration: The default configuration for the service.
  85. /// - service: The name of the service for which this override applies.
  86. public mutating func setDefaultConfiguration(
  87. _ configuration: MethodConfiguration?,
  88. forService service: String
  89. ) {
  90. let name = MethodConfiguration.Name(service: "", method: "")
  91. self.elements[name] = configuration
  92. }
  93. }