1 package com.guinetik.corefun.examples;
2
3 import com.guinetik.corefun.Loggable;
4 import com.guinetik.corefun.Result;
5 import com.guinetik.corefun.SafeExecutor;
6
7
8
9
10
11
12
13
14 public class SafeExecutorExample {
15
16 public static void main(String[] args) {
17 System.out.println("=== SafeExecutor Examples ===\n");
18
19 basicUsage();
20 implementingSafeExecutor();
21 safelyResultPattern();
22 customLogging();
23 }
24
25
26
27
28 static void basicUsage() {
29 System.out.println("--- Basic Usage (println logger) ---");
30
31
32 SafeExecutor executor = SafeExecutor.println();
33
34
35 String result = executor.safely("Compute greeting", () -> {
36 Thread.sleep(50);
37 return "Hello, World!";
38 });
39 System.out.println("Result: " + result);
40
41
42 System.out.println("\nVoid operation:");
43 executor.safelySafe("Perform cleanup", () -> {
44 Thread.sleep(30);
45 System.out.println(" [Cleanup work happening...]");
46 });
47
48
49 System.out.println("\nSilent executor:");
50 SafeExecutor silent = SafeExecutor.noop();
51 String silentResult = silent.safely("No logs", () -> "Done quietly");
52 System.out.println("Silent result: " + silentResult);
53
54 System.out.println();
55 }
56
57
58
59
60 static void implementingSafeExecutor() {
61 System.out.println("--- Implementing SafeExecutor ---");
62
63
64 DataProcessor processor = new DataProcessor();
65 processor.processData("some-data-id");
66
67 System.out.println();
68 }
69
70
71
72
73 static void safelyResultPattern() {
74 System.out.println("--- safelyResult (No Exceptions) ---");
75
76 SafeExecutor executor = SafeExecutor.println();
77
78
79 Result<Integer, String> success = executor.safelyResult(
80 "Parse valid number",
81 () -> Integer.parseInt("42")
82 );
83 System.out.println("Parse result: " + success);
84
85 Result<Integer, String> failure = executor.safelyResult(
86 "Parse invalid number",
87 () -> Integer.parseInt("not-a-number")
88 );
89 System.out.println("Parse failure: " + failure);
90
91
92 String message = success
93 .map(n -> n * 2)
94 .fold(
95 error -> "Error: " + error,
96 value -> "Doubled value: " + value
97 );
98 System.out.println(message);
99
100 System.out.println();
101 }
102
103
104
105
106 static void customLogging() {
107 System.out.println("--- Custom Logging ---");
108
109
110 Loggable.Logger customLogger = new Loggable.Logger() {
111 @Override
112 public void info(String message) {
113 System.out.println("📘 " + message);
114 }
115
116 @Override
117 public void warn(String message) {
118 System.out.println("⚠️ " + message);
119 }
120
121 @Override
122 public void error(String message) {
123 System.err.println("❌ " + message);
124 }
125
126 @Override
127 public void error(String message, Throwable t) {
128 System.err.println("❌ " + message + " - " + t.getMessage());
129 }
130 };
131
132 SafeExecutor customExecutor = SafeExecutor.withLogger(customLogger);
133 customExecutor.safely("Custom logged operation", () -> {
134 Thread.sleep(25);
135 return "done";
136 });
137
138
139 System.out.println("\nTagged logger:");
140 Loggable.Logger tagged = Loggable.Logger.tagged("DataService",
141 Loggable.Logger.println());
142 SafeExecutor taggedExecutor = SafeExecutor.withLogger(tagged);
143 taggedExecutor.safely("Tagged operation", () -> "result");
144
145
146 System.out.println("\n// SLF4J integration example:");
147 System.out.println("// private static final org.slf4j.Logger LOG = LoggerFactory.getLogger(MyClass.class);");
148 System.out.println("// Loggable.Logger logger = Loggable.Logger.of(LOG::info, LOG::warn, LOG::error);");
149
150 System.out.println();
151 }
152
153
154
155
156 static class DataProcessor implements SafeExecutor {
157
158 private final Loggable.Logger log = Loggable.Logger.tagged("DataProcessor",
159 Loggable.Logger.println());
160
161 @Override
162 public Loggable.Logger logger() {
163 return log;
164 }
165
166 public void processData(String dataId) {
167
168 Result<String, String> result = safelyResult(
169 "Process data " + dataId,
170 () -> {
171
172 Thread.sleep(75);
173 return "Processed: " + dataId;
174 }
175 );
176
177 result
178 .peekSuccess(data -> logger().info("Success: " + data))
179 .peekFailure(error -> logger().error("Failed: " + error));
180 }
181 }
182 }