yorkie-ios-sdk/Sources/Document/Json/JSONCounter.swift

106 lines
2.8 KiB
Swift

/*
* Copyright 2022 The Yorkie Authors. All rights reserved.
*
* Licensed under the Apache License, Version 2.0 (the "License")
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
import Foundation
/**
* `JSONCounter` is a custom data type that is used to counter.
*/
public class JSONCounter<T: YorkieCountable> {
private let _value: T
private var context: ChangeContext?
private var counter: CRDTCounter<T>?
public init(value: T) {
self._value = value
}
/**
* `initialize` initialize this text with context and internal text.
*/
func initialize(context: ChangeContext, counter: CRDTCounter<T>) {
self.context = context
self.counter = counter
}
/**
* `id` returns the ID of this text.
*/
public var id: TimeTicket? {
self.counter?.id
}
/**
* `value` returns the value of this counter;
* @internal
*/
public var value: some YorkieCountable {
guard let counter else {
return self._value
}
return counter.value
}
/**
* `increase` increases numeric data.
*/
@discardableResult
public func increase(value: any BinaryInteger) -> Self {
guard let context, let counter else {
let log = "it is not initialized yet"
Logger.critical(log)
return self
}
guard let primitiveValue = Primitive.type(of: value) else {
let log = "Unsupported type of value: \(type(of: T.self))"
Logger.critical(log)
return self
}
let ticket = context.issueTimeTicket()
let primitive = Primitive(value: primitiveValue, createdAt: ticket)
guard primitive.isNumericType else {
let log = "Unsupported type of value: \(type(of: T.self))"
Logger.critical(log)
return self
}
do {
try counter.increase(primitive)
} catch {
let log = "catch error when increase counter: [\(error)]"
Logger.critical(log)
return self
}
context.push(operation: IncreaseOperation(parentCreatedAt: counter.createdAt, value: primitive, executedAt: ticket))
return self
}
@discardableResult
public func increase(value: any BinaryFloatingPoint) -> Self {
self.increase(value: T(value))
}
}