搜索插件、代码仓与 APP 分类

插件详情v1.0.3

lens4d

为 Dart 构建可组合、可重用且类型安全的透镜。

AndroidiOSLinuxmacOSWebWindows
近 30 天下载
1.9万
喜欢数
1
Pub 分数
160

安装插件

flutter pub add lens4d

插件介绍

基于插件公开信息、社区数据与项目使用情况整理的选型参考。

Lens4D 是一个 Dart 包,可用来创建可组合、可重用且类型安全的透镜,以处理不可变数据结构。它提供了一种函数式编程方法,用于访问和更新嵌套数据而无需修改原数据,从而提升代码的清晰度和可维护性。透镜使开发者能够专注于复杂数据模型中的特定部分,确保更新操作可预测且安全。适用于大型应用中的状态管理,Lens4D 支持所有主要平台,包括 Web、移动设备和桌面端。

适合场景

  • 不可变状态更新
  • 嵌套数据操作
  • 功能状态管理
  • 响应式 UI 开发
  • 类型安全的数据访问
  • 数据转换中的代码复用

主要特点

  • 类型安全的镜头创建
  • 可组合的镜头
  • 不可变数据更新
  • 对嵌套结构的支持
  • 函数式编程范式
  • 跨平台兼容性

适合对象

  • 使用函数式编程的开发者
  • 大型应用中的状态管理
  • 注重类型安全的团队
  • 具有复杂嵌套数据的应用程序
  • 面向多个平台的前端开发人员

使用建议

  • 需要理解函数式编程
  • 初学者的学习曲线
  • 最适合不可变数据模式
  • 在简单用例中可能增加开销
  • 与主流包相比,文档有限

原始 README

以下为关联源码仓库的 README 原文快照,最新内容请访问源码仓库。

lens4d

Dart Pub Version License

A functional lens library for Dart, enabling type-safe, composable data access and modification.

Overview

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.

Why Lenses?

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),
]);

Features

  • ✅ Type-safe data access - Extract and modify values with compile-time type safety
  • ✅ Functional composition - Chain operations with having() and havingAll()
  • ✅ Bidirectional lenses - Both read from and write to data structures
  • ✅ Type conversions - Built-in conversions for integers, booleans, dates, and more
  • ✅ Error handling - Comprehensive failure handling with detailed error information
  • ✅ Zero dependencies - Pure Dart implementation

Quick Start

Installation

Add lens4d to your pubspec.yaml:

dependencies:
  lens4d: ^1.0.0
Basic Usage

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}');
  }
}
Type Conversions

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
Functional Composition

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),
]);

API Overview

  • BiDiLensSpec<IN, OUT> - Bidirectional lens specification for extraction and injection
  • LensSpec<IN, OUT> - Unidirectional lens for extraction only
  • BiDiLens<IN, OUT> - Concrete bidirectional lens instance
  • Lens<IN, OUT> - Concrete unidirectional lens instance
Core Methods
  • required(name) - Extract required value, throw on missing
  • optional(name) - Extract optional value, return null if missing
  • defaulted(name, defaultValue) - Extract with fallback value
  • inject(value, target) - Inject value into target
  • of(value) - Create injection function for use with having()
Extension Methods
  • having(modifier) - Apply single lens modifier
  • havingAll(modifiers) - Apply multiple lens modifiers
  • Type conversions: integer(), boolean(), dateTime(), etc.

Contributing

Contributions are welcome! Please feel free to submit a PR.

License

This project is licensed under the Apache2 License - see the LICENSE file for details.

Acknowledgments

  • Inspired by the http4k Kotlin library
  • Based on functional programming patterns from Haskell and other FP languages
  • Thanks to the Dart community for feedback and contributions

所属分类

源码仓库

使用此插件的项目

暂无相关数据。

所在榜单