Add support for sampling (#119)
* Add UnitInterval type * Add test coverage for UnitInterval * Add support for sampling * Add integration tests for sampling
This commit is contained in:
parent
ddde66dc08
commit
fac4df6b1a
1 changed files with 1584 additions and 0 deletions
126
Sources/MCP/Base/UnitInterval.swift
Normal file
126
Sources/MCP/Base/UnitInterval.swift
Normal file
|
|
@ -0,0 +1,126 @@
|
|||
/// A value constrained to the range 0.0 to 1.0, inclusive.
|
||||
///
|
||||
/// `UnitInterval` represents a normalized value that is guaranteed to be within
|
||||
/// the unit interval [0, 1]. This type is commonly used for representing
|
||||
/// priorities in sampling request model preferences.
|
||||
///
|
||||
/// The type provides safe initialization that returns `nil` for values outside
|
||||
/// the valid range, ensuring that all instances contain valid unit interval values.
|
||||
///
|
||||
/// - Example:
|
||||
/// ```swift
|
||||
/// let zero: UnitInterval = 0 // 0.0
|
||||
/// let half = UnitInterval(0.5)! // 0.5
|
||||
/// let one: UnitInterval = 1.0 // 1.0
|
||||
/// let invalid = UnitInterval(1.5) // nil
|
||||
/// ```
|
||||
public struct UnitInterval: Hashable, Sendable {
|
||||
private let value: Double
|
||||
|
||||
/// Creates a unit interval value from a `Double`.
|
||||
///
|
||||
/// - Parameter value: A double value that must be in the range 0.0...1.0
|
||||
/// - Returns: A `UnitInterval` instance if the value is valid, `nil` otherwise
|
||||
///
|
||||
/// - Example:
|
||||
/// ```swift
|
||||
/// let valid = UnitInterval(0.75) // Optional(0.75)
|
||||
/// let invalid = UnitInterval(-0.1) // nil
|
||||
/// let boundary = UnitInterval(1.0) // Optional(1.0)
|
||||
/// ```
|
||||
public init?(_ value: Double) {
|
||||
guard (0...1).contains(value) else { return nil }
|
||||
self.value = value
|
||||
}
|
||||
|
||||
/// The underlying double value.
|
||||
///
|
||||
/// This property provides access to the raw double value that is guaranteed
|
||||
/// to be within the range [0, 1].
|
||||
///
|
||||
/// - Returns: The double value between 0.0 and 1.0, inclusive
|
||||
public var doubleValue: Double { value }
|
||||
}
|
||||
|
||||
// MARK: - Comparable
|
||||
|
||||
extension UnitInterval: Comparable {
|
||||
public static func < (lhs: UnitInterval, rhs: UnitInterval) -> Bool {
|
||||
lhs.value < rhs.value
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - CustomStringConvertible
|
||||
|
||||
extension UnitInterval: CustomStringConvertible {
|
||||
public var description: String { "\(value)" }
|
||||
}
|
||||
|
||||
// MARK: - Codable
|
||||
|
||||
extension UnitInterval: Codable {
|
||||
public init(from decoder: Decoder) throws {
|
||||
let container = try decoder.singleValueContainer()
|
||||
let doubleValue = try container.decode(Double.self)
|
||||
guard let interval = UnitInterval(doubleValue) else {
|
||||
throw DecodingError.dataCorrupted(
|
||||
DecodingError.Context(
|
||||
codingPath: decoder.codingPath,
|
||||
debugDescription: "Value \(doubleValue) is not in range 0...1")
|
||||
)
|
||||
}
|
||||
self = interval
|
||||
}
|
||||
|
||||
public func encode(to encoder: Encoder) throws {
|
||||
var container = encoder.singleValueContainer()
|
||||
try container.encode(value)
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ExpressibleByFloatLiteral
|
||||
|
||||
extension UnitInterval: ExpressibleByFloatLiteral {
|
||||
/// Creates a unit interval from a floating-point literal.
|
||||
///
|
||||
/// This initializer allows you to create `UnitInterval` instances using
|
||||
/// floating-point literals. The literal value must be in the range [0, 1]
|
||||
/// or a runtime error will occur.
|
||||
///
|
||||
/// - Parameter value: A floating-point literal between 0.0 and 1.0
|
||||
///
|
||||
/// - Warning: This initializer will crash if the literal is outside the valid range.
|
||||
/// Use the failable initializer `init(_:)` for runtime validation.
|
||||
///
|
||||
/// - Example:
|
||||
/// ```swift
|
||||
/// let quarter: UnitInterval = 0.25
|
||||
/// let half: UnitInterval = 0.5
|
||||
/// ```
|
||||
public init(floatLiteral value: Double) {
|
||||
self.init(value)!
|
||||
}
|
||||
}
|
||||
|
||||
// MARK: - ExpressibleByIntegerLiteral
|
||||
|
||||
extension UnitInterval: ExpressibleByIntegerLiteral {
|
||||
/// Creates a unit interval from an integer literal.
|
||||
///
|
||||
/// This initializer allows you to create `UnitInterval` instances using
|
||||
/// integer literals. Only the values 0 and 1 are valid.
|
||||
///
|
||||
/// - Parameter value: An integer literal, either 0 or 1
|
||||
///
|
||||
/// - Warning: This initializer will crash if the literal is outside the valid range.
|
||||
/// Use the failable initializer `init(_:)` for runtime validation.
|
||||
///
|
||||
/// - Example:
|
||||
/// ```swift
|
||||
/// let zero: UnitInterval = 0
|
||||
/// let one: UnitInterval = 1
|
||||
/// ```
|
||||
public init(integerLiteral value: Int) {
|
||||
self.init(Double(value))!
|
||||
}
|
||||
}
|
||||
Loading…
Reference in a new issue