@@ -49,7 +49,8 @@ SwiftJava's `swift-java jextract` tool automates generating Java bindings from S
4949| Initializers: ` class ` , ` struct ` | ✅ | ✅ |
5050| Optional Initializers / Throwing Initializers | ❌ | ❌ |
5151| Deinitializers: ` class ` , ` struct ` | ✅ | ✅ |
52- | ` enum ` , ` actor ` | ❌ | ❌ |
52+ | ` enum ` | ❌ | ✅ |
53+ | ` actor ` | ❌ | ❌ |
5354| Global Swift ` func ` | ✅ | ✅ |
5455| Class/struct member ` func ` | ✅ | ✅ |
5556| Throwing functions: ` func x() throws ` | ❌ | ✅ |
@@ -157,3 +158,113 @@ you are expected to add a Guava dependency to your Java project.
157158| ` Double ` | ` double ` |
158159
159160> Note: The ` wrap-guava ` mode is currently only available in FFM mode of jextract.
161+
162+ #### Enums
163+
164+ > Note: Enums are currently only supported in JNI mode.
165+
166+ Swift enums are extracted into a corresponding Java ` class ` . To support associated values
167+ all cases are also extracted as Java ` record ` s.
168+
169+ Consider the following Swift enum:
170+ ``` swift
171+ public enum Vehicle {
172+ case car (String )
173+ case bicycle (maker : String )
174+ }
175+ ```
176+ You can then instantiate a case of ` Vehicle ` by using one of the static methods:
177+ ``` java
178+ try (var arena = SwiftArena . ofConfined()) {
179+ Vehicle vehicle = Vehicle . car(" BMW" , arena);
180+ Optional<Vehicle . Car > car = vehicle. getAsCar();
181+ assertEquals(" BMW" , car. orElseThrow(). arg0());
182+ }
183+ ```
184+ As you can see above, to access the associated values of a case you can call one of the
185+ ` getAsX ` methods that will return an Optional record with the associated values.
186+ ``` java
187+ try (var arena = SwiftArena . ofConfined()) {
188+ Vehicle vehicle = Vehicle . bycicle(" My Brand" , arena);
189+ Optional<Vehicle . Car > car = vehicle. getAsCar();
190+ assertFalse(car. isPresent());
191+
192+ Optional<Vehicle . Bicycle > bicycle = vehicle. getAsBicycle();
193+ assertEquals(" My Brand" , bicycle. orElseThrow(). maker());
194+ }
195+ ```
196+
197+ ##### Switching
198+
199+ If you only need to switch on the case and not access any associated values,
200+ you can use the ` getDiscriminator() ` method:
201+ ``` java
202+ Vehicle vehicle = ... ;
203+ switch (vehicle. getDiscriminator()) {
204+ case BICYCLE :
205+ System . out. println(" I am a bicycle!" );
206+ break
207+ case CAR :
208+ System . out. println(" I am a car!" );
209+ break
210+ }
211+ ```
212+ If you also want access to the associated values, you have various options
213+ depending on the Java version you are using.
214+ If you are running Java 21+ you can use [ pattern matching for switch] ( https://openjdk.org/jeps/441 ) :
215+ ``` java
216+ Vehicle vehicle = ... ;
217+ switch (vehicle. getCase()) {
218+ case Vehicle . Bicycle b:
219+ System . out. println(" Bicycle maker: " + b. maker());
220+ break
221+ case Vehicle . Car c:
222+ System . out. println(" Car: " + c. arg0());
223+ break
224+ }
225+ ```
226+ For Java 16+ you can use [ pattern matching for instanceof] ( https://openjdk.org/jeps/394 )
227+ ``` java
228+ Vehicle vehicle = ... ;
229+ Vehicle . Case case = vehicle. getCase();
230+ if (case instanceof Vehicle . Bicycle b) {
231+ System . out. println(" Bicycle maker: " + b. maker());
232+ } else if (case instanceof Vehicle . Car c) {
233+ System . out. println(" Car: " + c. arg0());
234+ }
235+ ```
236+ For any previous Java versions you can resort to casting the ` Case ` to the expected type:
237+ ``` java
238+ Vehicle vehicle = ... ;
239+ Vehicle . Case case = vehicle. getCase();
240+ if (case instanceof Vehicle . Bicycle ) {
241+ Vehicle . Bicycle b = (Vehicle . Bicycle ) case ;
242+ System . out. println(" Bicycle maker: " + b. maker());
243+ } else if (case instanceof Vehicle . Car ) {
244+ Vehicle . Car c = (Vehicle . Car ) case ;
245+ System . out. println(" Car: " + c. arg0());
246+ }
247+ ```
248+
249+ ##### RawRepresentable
250+
251+ JExtract also supports extracting enums that conform to ` RawRepresentable `
252+ by giving access to an optional initializer and the ` rawValue ` variable.
253+ Consider the following example:
254+ ``` swift
255+ public enum Alignment : String {
256+ case horizontal
257+ case vertical
258+ }
259+ ```
260+ you can then initialize ` Alignment ` from a ` String ` and also retrieve back its ` rawValue ` :
261+ ``` java
262+ try (var arena = SwiftArena . ofConfined()) {
263+ Optional<Alignment > alignment = Alignment . init(" horizontal" , arena);
264+ assertEqual(HORIZONTAL , alignment. orElseThrow(). getDiscriminator());
265+ assertEqual(" horizontal" , alignment. orElseThrow(). getRawValue());
266+ }
267+ ```
268+
269+
270+
0 commit comments