Commit c3572cb6 authored by HankG's avatar HankG
Browse files

Add temp file intermediate example

parent 8f53ed48
Pipeline #417933111 passed with stage
in 56 seconds
......@@ -45,4 +45,95 @@ void main() {
invert(0).match(
onSuccess: (value) => print("Inverse is: $value"),
onError: (error) => print(error));
}```
\ No newline at end of file
}
```
## Intermediate Example: Temporary File Creation/Writing
The example below is a larger example to show a more real world
example. This program has methods for figuring out the temporary
folder for the user and then creating a temporary file in that
folder that the user can write to. It then attempts to write to
that file. This shows how comprehensively one can use the various
parts of the library, from the `runCatching` surrounding file I/O,
to the mapError to create uniform return error types, and finally
showing off `andThen` chaining and `fold` for final value extraction.
```dart
import 'dart:io';
import 'package:result_monad/result_monad.dart';
enum ErrorEnum { environment, fileAccess }
void main(List<String> arguments) {
final stringToWrite = 'Data written to the temp file ${DateTime.now()}';
final tmpFileResult = getTempFile();
tmpFileResult.match(
onSuccess: (file) => print('Temp file: ${file.path}'),
onError: (error) => print('Error getting temp file: $error'));
// Probably would check if failure and stop here normally but want to show
// that even starting with an error Result Monad flows correctly.
final writtenSuccessfully = tmpFileResult
.andThen((file) => runCatching(() {
file.writeAsStringSync(stringToWrite);
return Result.ok(file);
}))
.andThen((file) => runCatching(() => Result.ok(file.readAsStringSync())))
.fold(
onSuccess: (text) => text == stringToWrite,
onError: (_) => false);
print('Successfully wrote to temp file? $writtenSuccessfully');
}
Result<File, ErrorEnum> getTempFile(
{String prefix = '', String suffix = '.tmp'}) {
String tmpName = '$prefix${DateTime.now().millisecondsSinceEpoch}$suffix';
return getTempFolder()
.andThen((tempFolder) =>
Result.ok('$tempFolder${Platform.pathSeparator}$tmpName'))
.andThen((tmpPath) => Result.ok(File(tmpPath)))
.mapError((error) => error is ErrorEnum ? error : ErrorEnum.fileAccess);
}
Result<String, ErrorEnum> getTempFolder() {
String folderName = '';
if (Platform.isMacOS || Platform.isWindows) {
final varName = Platform.isMacOS ? 'TMPDIR' : 'TEMP';
final tempDirPathFromEnv = Platform.environment[varName];
if (tempDirPathFromEnv != null) {
folderName = tempDirPathFromEnv;
} else {
return Result.error(ErrorEnum.environment);
}
} else if (Platform.isLinux) {
folderName = '/tmp';
}
if (folderName.isEmpty) {
return Result.error(ErrorEnum.environment);
}
final Result<bool, dynamic> canWriteResult = runCatching(() {
if (!Directory(folderName).existsSync()) {
return Result.ok(false);
}
final testFilePath =
'$folderName${Platform.pathSeparator}${DateTime.now().millisecondsSinceEpoch}.tmp';
final tmpFile = File(testFilePath);
tmpFile.writeAsStringSync('test');
tmpFile.deleteSync();
return Result.ok(true);
});
return canWriteResult
.andThen<String, ErrorEnum>((canWrite) =>
canWrite ? Result.ok(folderName) : Result.error(ErrorEnum.fileAccess))
.mapError((_) => ErrorEnum.fileAccess);
}
```
\ No newline at end of file
/// Illustrates are more real world comprehensive use of the library with
/// an example of a function that returns a temporary file in the OS
/// specified temporary directory and then attempting to write into that file.
///
///
import 'dart:io';
import 'package:result_monad/result_monad.dart';
enum ErrorEnum { environment, fileAccess }
void main(List<String> arguments) {
final stringToWrite = 'Data written to the temp file ${DateTime.now()}';
final tmpFileResult = getTempFile();
tmpFileResult.match(
onSuccess: (file) => print('Temp file: ${file.path}'),
onError: (error) => print('Error getting temp file: $error'));
// Probably would check if failure and stop here normally but want to show
// that even starting with an error Result Monad flows correctly.
final writtenSuccessfully = tmpFileResult
.andThen((file) => runCatching(() {
file.writeAsStringSync(stringToWrite);
return Result.ok(file);
}))
.andThen((file) => runCatching(() => Result.ok(file.readAsStringSync())))
.fold(
onSuccess: (text) => text == stringToWrite,
onError: (_) => false);
print('Successfully wrote to temp file? $writtenSuccessfully');
}
Result<File, ErrorEnum> getTempFile(
{String prefix = '', String suffix = '.tmp'}) {
String tmpName = '$prefix${DateTime.now().millisecondsSinceEpoch}$suffix';
return getTempFolder()
.andThen((tempFolder) =>
Result.ok('$tempFolder${Platform.pathSeparator}$tmpName'))
.andThen((tmpPath) => Result.ok(File(tmpPath)))
.mapError((error) => error is ErrorEnum ? error : ErrorEnum.fileAccess);
}
Result<String, ErrorEnum> getTempFolder() {
String folderName = '';
if (Platform.isMacOS || Platform.isWindows) {
final varName = Platform.isMacOS ? 'TMPDIR' : 'TEMP';
final tempDirPathFromEnv = Platform.environment[varName];
if (tempDirPathFromEnv != null) {
folderName = tempDirPathFromEnv;
} else {
return Result.error(ErrorEnum.environment);
}
} else if (Platform.isLinux) {
folderName = '/tmp';
}
if (folderName.isEmpty) {
return Result.error(ErrorEnum.environment);
}
final Result<bool, dynamic> canWriteResult = runCatching(() {
if (!Directory(folderName).existsSync()) {
return Result.ok(false);
}
final testFilePath =
'$folderName${Platform.pathSeparator}${DateTime.now().millisecondsSinceEpoch}.tmp';
final tmpFile = File(testFilePath);
tmpFile.writeAsStringSync('test');
tmpFile.deleteSync();
return Result.ok(true);
});
return canWriteResult
.andThen<String, ErrorEnum>((canWrite) =>
canWrite ? Result.ok(folderName) : Result.error(ErrorEnum.fileAccess))
.mapError((_) => ErrorEnum.fileAccess);
}
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment