Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/rezojoglidze/rjswiftmacros
RJSwiftMacros is a Swift package that provides swift macros
https://github.com/rezojoglidze/rjswiftmacros
codingkeys codingkeys-xcode-extension ios ios-swift library macros mock mocking opensource swift swift-package-manager swiftmacros swiftui xcode
Last synced: about 1 month ago
JSON representation
RJSwiftMacros is a Swift package that provides swift macros
- Host: GitHub
- URL: https://github.com/rezojoglidze/rjswiftmacros
- Owner: rezojoglidze
- License: mit
- Created: 2024-07-14T13:52:42.000Z (6 months ago)
- Default Branch: main
- Last Pushed: 2024-11-22T12:46:17.000Z (about 1 month ago)
- Last Synced: 2024-11-22T13:36:06.992Z (about 1 month ago)
- Topics: codingkeys, codingkeys-xcode-extension, ios, ios-swift, library, macros, mock, mocking, opensource, swift, swift-package-manager, swiftmacros, swiftui, xcode
- Language: Swift
- Homepage:
- Size: 229 KB
- Stars: 11
- Watchers: 1
- Forks: 0
- Open Issues: 0
-
Metadata Files:
- Readme: README.md
- Changelog: CHANGELOG.md
- License: LICENSE
Awesome Lists containing this project
README
# RJSwiftMacros
RJSwiftMacros is a Swift package that provides macros.
> [!TIP]
> All macros are used in SwiftUIDemo project. see the [LINK](https://github.com/rezojoglidze/SwiftUIDemo).## Macros
> [!WARNING]
> `MockBuilder` macro doesn't work at `SwiftUI` `#Preview` macro. Here is a [solution](https://stackoverflow.com/questions/78856674/does-attached-macros-work-in-the-preview-body/78856731#78856731).### MockBuilder
- ``MockBuilder(numberOfItems: Int)``: Generates a mock instance and an array of mock data based on your model.
- `MockBuilder` has `MockBuilderProperty` member macro, with which you can set the initial value to the desired property.
##### Key Features:
- **Default Usage**: `@MockBuilder()` generates a one single mock instance.
- **Customizable**: You can also specify parameter like `numberOfItems` if you need to have array of mock items.#### MockBuilderProperty macro
- ``MockBuilderProperty(value: T)``: Sets an initial value to a property within a struct or class.### CodingKeys
- ``CodingKeys(codingKeyType: CodingKeyType)``: Automatically generates `CodingKeys` for a struct based on the specified `CodingKeyType` which has two cases: `.camelCase` and `.snakeCase`.
- ``CodingKeyProperty(:_)``: Allows you to adjust the coding key for a specific property.
- ``CodingKeyIgnored()``: Allows you to exclude specific properties from the coding process when using the `CodingKeys` macro.## Installation
**Swift Package Manager**To depend on `RJSwiftMacros` in a SwiftPM package, add the following to your Package.swift.
```swift
dependencies: [
.package(url: "https://github.com/rezojoglidze/RJSwiftMacros", from: "<#latest RJSwiftMacros tag#>"),
],
```
To add `RJSwiftMacros` as a dependency of your Xcode project, go to the Package Dependencies tab of your Xcode project, click the plus button and search for https://github.com/rezojoglidze/RJSwiftMacros## Usage
### MockBuilder macro
Import the RJSwiftMacros module and apply the macros to your structs and properties:Usage of `MockBuilder`:
Macro generates two `static` properties: `mock` and `mockArray`. `mockArray` count equals `numberOfItems` value. If you want to set a custom value to the desired property, use `@MockBuilderProperty` macro. If the custom value granted is prohibited you will get a swift standard warning error.To generate only `.mock` value, you can use `@MockBuilder()` without any param passing.
> [!IMPORTANT]
> Type which participating in the mock building should have `@MockBuilder()` itself. Below example, we want to have `let type: VehicleType` mocked version, so `VehicleType` should have `@MockBuilder()`
```swift
import RJSwiftMacros@MockBuilder(numberOfItems: 2)
enum VehicleType: String, Decodable {
case car
case bus
case motorcycle
}@MockBuilder()
struct ExampleAllSupportedTypes {
let intVariable: Int
let int8Variable: Int8
let int16Variable: Int16
let int32Variable: Int32
let int64Variable: Int64
let uintVariable: UInt
let uint8Variable: UInt8
let uint16Variable: UInt16
let uint32Variable: UInt32
let uint64Variable: UInt64
let floatVariable: Float
let float32Variable: Float32
let float64Variable: Float64
let doubleVariable: Double
let decimalVariable: Decimal
let nsDecimalNumberVariable: NSDecimalNumber
let stringVariable: String
let boolVariable: Bool
let dateVariable: Date
let uuidVariable: UUID
let cgPointVariable: CGPoint
let cgRectVariable: CGRect
let cgSizeVariable: CGSize
let cgVectorVariable: CGVector
let cgFloatVariable: CGFloat
let urlVariable: URL
let imageVariable: Image
let colorVariable: Color
let vehicle: VehicleType
let availableTimeSlot: Set
let arrayOfString: [String]
let closureVariable: () -> Void
let tuples: ((String, String, Int), Bool?)let passthroughSubject: PassthroughSubject
let currentValueSubject: CurrentValueSubject
}#if DEBUG
public static var mock: ExampleAllSupportedTypes {
.init(
intVariable: 54248,
int8Variable: 92,
int16Variable: 17693,
int32Variable: 1748550107,
int64Variable: 85105,
uintVariable: 75340,
uint8Variable: 221,
uint16Variable: 6060,
uint32Variable: 34678,
uint64Variable: 4145,
floatVariable: 38105.523,
float32Variable: 99252.86,
float64Variable: 57161.44399989151,
doubleVariable: 45860.372174783995,
decimalVariable: 80414.91669166147584,
nsDecimalNumberVariable: 57109.7344805794816,
stringVariable: "Lorem ipsum dolor sit amet",
boolVariable: false,
dateVariable: Date(timeInterval: 77349, since: Date()),
uuidVariable: UUID(),
cgPointVariable: CGPoint(),
cgRectVariable: CGRect(),
cgSizeVariable: CGSize(),
cgVectorVariable: CGVector(),
cgFloatVariable: CGFloat(),
urlVariable: URL(string: "https://www.tiktok.com")!,
imageVariable: Image(systemName: "swift"),
colorVariable: Color.primary.opacity(0.6),
vehicle: VehicleType.mock,
availableTimeSlot: Set(),
arrayOfString: ["in voluptate velit esse cillum dolore"]
"Duis aute irure dolor in reprehenderit",
"Excepteur sint occaecat cupidatat non proident",
"sed do eiusmod tempor incididunt",
],
closureVariable: {},
tuples: (("Duis ac tellus et risus vulputate vehicula", "Duis aute irure dolor in reprehenderit", 42372),false),
passthroughSubject: PassthroughSubject(),
currentValueSubject: CurrentValueSubject(())
)
}
#endif
}
```To generate both `.mock` and `.mockArray` properties use `@MockBuilder(numberOfItems: 2)`. `numberOfItems` is equal to the count of mock array.
```swift
import RJSwiftMacros@MockBuilder(numberOfItems: 2)
struct Person {
let name: String?
let surname: [String]?
@MockBuilderProperty(value: Color.blue) let color: Color?
@MockBuilderProperty(value: Image(systemName: "swift")) let image: Image?
@MockBuilderProperty(value: "k") let character: Character#if DEBUG
static var mock: Person {
.init(
name: "Lorna,
surname: ["Clare"],
color: Color.blue.opacity(0.6),
image: Image(systemName: "swift"),
character: "k"
)
}static var mockArray: [Person ] {
[
.init(
name: "Valentina,
surname: ["Queenie"],
color: Color.blue.opacity(0.6),
image: Image(systemName: "swift"),
character: "k"
),
.init(
name: "Lorna,
surname: ["Bettye"],
color: Color.blue.opacity(0.6),
image: Image(systemName: "swift"),
character: "k"
)
]
}
#endif
}
```### CodingKeys macro
Usage of `CodingKeys` without `codingKeyType` param passing generates CodingKeys with `.camelCase`. `CodingKeys` macro works only with stored property types. If you want to set custom coding key to the desired param, use `@CodingKeyProperty(desired_value)`. To ignore desired param from `CodingKeys` enum, use `@CodingKeyIgnored()`.
```swift
import RJSwiftMacros@CodingKeys()
class Car {
let modelColor: String
@CodingKeyProperty("car_model") let model: String
@CodingKeyIgnored() let speed: Intinit(modelColor: String, model: String, speed: Int) {
self.modelColor = modelColor
self.model = model
self.speed = speed
}enum CodingKeys: String, CodingKey {
case modelColor
case model = "car_model"
}
}
```CodingKeys generation with `.snakeCase`.
```swift
import RJSwiftMacros@CodingKeys(codingKeyType: .snakeCase)
struct University {
let name: String
let studentCapacity: Int
let cars: [String]?
var closure: (() -> ())?static var students: [String] = []
var oldName: String {
"Tbilisi"
}
enum CodingKeys: String, CodingKey {
case name = "name"
case studentCapacity = "student_capacity"
case cars = "cars"
}
}
```## Requirements
- Swift 5.10 or later
- macOS 10.15 or later
- iOS 15 or later
## Contributing
Contributions are welcome! Please open an issue or submit a pull request on GitHub.## Contact
For questions or feedback, feel free to reach out to [email protected].