From be5271780caa8091c224db0a41c1aa6f89f08e32 Mon Sep 17 00:00:00 2001 From: Mani Ramezan Date: Thu, 27 Jul 2023 17:19:33 -0400 Subject: [PATCH] Add DocC for macros --- Sources/UserDefault/UserDefault.swift | 116 ++++++++++++++++++++++++++ 1 file changed, 116 insertions(+) diff --git a/Sources/UserDefault/UserDefault.swift b/Sources/UserDefault/UserDefault.swift index c2bf8dd..9d39671 100644 --- a/Sources/UserDefault/UserDefault.swift +++ b/Sources/UserDefault/UserDefault.swift @@ -1,12 +1,128 @@ import Foundation import UserDefaultMacro +/// # ``UserDefaultMacro`` + +/// Generates `userDefaults` variable and `init(userDefaults:)` method for the type. It marks all mutable properties are also marked `@UserDefaultRecord` +/// This attribute can be used on type definitions like `class` and `struct`. +/// ```swift +/// @UserDefaultDataStore +/// struct UserDefaultsStore { +/// var myBoolean: Bool +/// } +/// ``` +/// is expanded to: +/// +/// ```swift +/// @UserDefaultDataStore +/// struct UserDefaultsStore { +/// // START: Added by UserDefaultDataStore +/// private let userDefaults: UserDefaults +/// +/// internal init(userDefaults: UserDefaults = .standard) { +/// self.userDefaults = userDefaults +/// } +/// // END +/// +/// @UserDefaultRecord +/// var myBoolean: Bool +/// } +/// ``` +/// If the variable already has `@UserDefaultRecord`, it'll be ignored by this macro. Check ``UserDefaultRecord(key:defaultValue:)`` for more details. +/// +/// - Parameters: +/// - userDefaults: Instance of `UserDefaults` to use. Defaults to `.standard` +/// - accessLevel: Access level of the generated `init`. Defaults to `.internal` @attached(member, names: named(userDefaults), named(init(userDefaults:))) @attached(memberAttribute) public macro UserDefaultDataStore(using userDefaults: UserDefaults = .standard, accessLevel: AccessLevel = .internal) = #externalMacro(module: "UserDefaultMacro", type: "UserDefaultDataStoreMacro") +/// Intended to be used on mutable properties with no body. This attribute relies on the type already attributed by ``UserDefaultDataStore(using:accessLevel:)`` and used on any mutable property with no body. +/// +/// This attribute allows overriding the key and default value when storing in `UserDefaults`. By default, it uses variable name and the default value returned by `UserDefaults` for the specified type. Following shows an example of how this can be used with `@UserDefaultDataStore`: +/// ```swift +/// @UserDefaultDataStore +/// struct UserDefaultsStore { +/// @UserDefaultRecord(key: "isInitialLaunch", defaultValue: true) +/// var isFirstTimeLaunching: Bool +/// } +/// ``` +/// is Expanded to: +/// ```swift +/// @UserDefaultDataStore +/// struct UserDefaultsStore { +/// @UserDefaultRecord(key: "isInitialLaunch", defaultValue: true) +/// var isFirstTimeLaunching: Bool +/// // START: Generated code for UserDefaultRecord +/// { +/// get { +/// userDefaults.bool(forKey: "isInitialLaunch") +/// } +/// +/// set { +/// userDefaults.setValue(newValue, forKey: "isInitialLaunch") +/// } +/// } +/// // END: Generated code for UserDefaultRecord +/// +/// // START: Generated code for UserDefaultDataStore +/// private let userDefaults: UserDefaults +/// +/// public init(userDefaults: UserDefaults = .standard) { +/// self.userDefaults = userDefaults +/// // START: Generated code for UserDefaultRecord +/// userDefaults.register(defaults: ["isInitialLaunch": true]) +/// // END: Generated code for UserDefaultRecord +/// } +/// // END: Generated code for UserDefaultDataStore +/// } +/// ``` +/// - Parameters: +/// - key: Key to use for storing this variable. Defaults to the name of the variable +/// - defaultValue: Default value to use when the variable is not set. Defaults to what `UserDefaults` method returns for this type @attached(accessor) public macro UserDefaultRecord(key: String? = nil, defaultValue: T? = Void.self) = #externalMacro(module: "UserDefaultMacro", type: "UserDefaultRecordMacro") +/// This attribute can be used on any mutable property with no body. This attribute creates the computational body needed to store the value in `UserDefaults`. +/// +/// Similar to ``UserDefaultRecord(key:defaultValue:)``, unless specified, it uses variable name as the key and no default value. `UserDefaults.standard` is the default storage unless defined as well. Following shows an example of how this can be used:: +/// ```swift +/// extension UserDefaults { +/// static let test = UserDefaults(suiteName: "test")! +/// } +/// +/// struct SomeEntity { +/// static let key = "customized_key" +/// @UserDefaultProperty(using: .test, key: Self.key, defaultValue: "Some default value") +/// var randomGeneratedString: String +/// } +/// ``` +/// ```swift +/// /// extension UserDefaults { +/// static let test = UserDefaults(suiteName: "test")! +/// } +/// +/// struct SomeEntity { +/// static let key = "customized_key" +/// @UserDefaultProperty(using: .test, key: Self.key, defaultValue: "Some default value") +/// var randomGeneratedString: String +/// // START: Generated by UserDefaultProperty +/// { +/// get { +/// UserDefaults.test.register(defaults: [Self.key: "Some default value"]) +/// return UserDefaults.test.string(forKey: Self.key)! +/// } +/// +/// set { +/// UserDefaults.test.setValue(newValue, forKey: Self.key) +/// } +/// } +/// // END: Generated by UserDefaultProperty +/// } +/// ``` +/// - Parameters: +/// - using: Instance of `UserDefaults` to use. Defaults to `.standard` +/// - key: Key to use for storing this variable. Defaults to the name of the variable +/// - defaultValue: Default value to use when the variable is not set. Defaults to what `UserDefaults` method returns for this type @attached(accessor) public macro UserDefaultProperty(using userDefaults: UserDefaults = .standard, key: String? = nil, defaultValue: T? = Void.self) = #externalMacro(module: "UserDefaultMacro", type: "UserDefaultPropertyMacro")