lens4d
Dart용 조합 가능하고 재사용 가능하며 타입 안전한 렌즈를 구축합니다.
Dart용 조합 가능하고 재사용 가능하며 타입 안전한 렌즈를 구축합니다.
아래는 영문 원문 스냅샷입니다. 최신 내용은 GitHub에서 확인하세요.
A functional lens library for Dart, enabling type-safe, composable data access and modification.
Lenses are a functional programming pattern that provide a clean, type-safe way to focus on, extract from, and modify deeply nested data structures. Originally from Haskell and popularized in languages like Scala and Kotlin, lenses solve the problem of working with immutable data in an elegant, composable way.
This library is inspired by and adapted from the lens system in http4k Kotlin library, bringing the power of functional lenses to Dart.
Working with immutable data often leads to verbose, error-prone code:
// Without lenses - verbose and fragile
final newUri = uri.replace(
queryParameters: {
...uri.queryParameters,
'search': 'flutter',
'limit': '20',
}
);
With lenses, the same operation becomes clean and composable:
// With lenses - clean and type-safe
final newUri = uri.havingAll([
Query.required('search').of('flutter'),
Query.integer().required('limit').of(20),
]);
having() and havingAll()Add lens4d to your pubspec.yaml:
dependencies:
lens4d: ^1.0.0
Here's a practical example working with URI query parameters:
import 'package:lens4d/lens4d.dart';
/// Define a Query lens for Uri objects
final Query = BiDiLensSpec<Uri, String>(
'query',
const StringParam(),
LensGet<Uri, String>((name, uri) {
final value = uri.queryParameters[name];
return value != null ? [value] : [];
}),
LensSet<Uri, String>((name, values, uri) {
final newParams = Map<String, String>.from(uri.queryParameters);
if (values.isEmpty) {
newParams.remove(name);
} else {
newParams[name] = values.first;
}
return uri.replace(queryParameters: newParams);
}),
);
void main() {
final uri = Uri.parse('https://api.example.com/search?q=dart&limit=10');
// Extract values with type safety
final searchTerm = Query.required('q')(uri); // 'dart'
final limit = Query.integer().required('limit')(uri); // 10 (as int)
final page = Query.integer().optional('page')(uri); // null
// Single modification
final newUri = uri.having(Query.required('q').of('flutter'));
// Multiple modifications
final complexUri = uri.havingAll([
Query.required('search').of('dart programming'),
Query.integer().required('limit').of(50),
Query.boolean().required('debug').of(true),
]);
// Error handling
try {
Query.required('missing')(uri);
} on LensFailure catch (e) {
print('Parameter not found: ${e.failures.first}');
}
}
Lenses support automatic type conversions, which are extensible via extension methods:
// String conversions
Query.required('name') // String (default)
Query.string().required('name') // String (explicit)
Query.nonEmptyString().required('title') // Non-empty string
// Numeric conversions
Query.integer().required('count') // int
Query.decimal().required('price') // double
// Other conversions
Query.boolean().required('enabled') // bool
Query.dateTime().required('created') // DateTime
The having() and havingAll() extension methods enable clean functional composition:
// Chain single modifications
final result = data
.having(someLens.of(value1))
.having(anotherLens.of(value2));
// Apply multiple modifications at once
final result = data.havingAll([
lens1.of(value1),
lens2.of(value2),
lens3.of(value3),
]);
BiDiLensSpec<IN, OUT> - Bidirectional lens specification for extraction and injectionLensSpec<IN, OUT> - Unidirectional lens for extraction onlyBiDiLens<IN, OUT> - Concrete bidirectional lens instanceLens<IN, OUT> - Concrete unidirectional lens instancerequired(name) - Extract required value, throw on missingoptional(name) - Extract optional value, return null if missingdefaulted(name, defaultValue) - Extract with fallback valueinject(value, target) - Inject value into targetof(value) - Create injection function for use with having()having(modifier) - Apply single lens modifierhavingAll(modifiers) - Apply multiple lens modifiersinteger(), boolean(), dateTime(), etc.Contributions are welcome! Please feel free to submit a PR.
This project is licensed under the Apache2 License - see the LICENSE file for details.
의존성 목록 1 개
^1.16.0사용 목적에 따라 검색하고 개발 활동을 비교한 뒤 원본 저장소에서 요구 사항을 확인하세요.
“A repository is the most basic element of GitHub.”
GitHub Docs — About repositories ↗