// Copyright (c) 2025 GeWuYou
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
namespace GFramework.Core.Functional.Pipe;
///
/// 提供函数式编程中的管道和组合操作扩展方法
///
public static class PipeExtensions
{
///
/// Also:
/// 对值执行副作用操作并返回原值
/// 适用于日志、调试、状态同步等场景
///
public static T Also(
this T value,
Action action)
{
action(value);
return value;
}
///
/// Tap:
/// Also 的别名,对值执行副作用操作并返回原值
/// 提供更符合某些编程风格的命名
///
/// 值的类型
/// 要处理的值
/// 要执行的副作用操作
/// 原始值
/// 当 action 为 null 时抛出
///
///
/// var result = GetUser()
/// .Tap(user => Console.WriteLine($"User: {user.Name}"))
/// .Tap(user => _logger.LogInfo($"Processing user {user.Id}"));
///
///
public static T Tap(this T value, Action action)
{
ArgumentNullException.ThrowIfNull(action);
action(value);
return value;
}
///
/// Pipe:
/// 管道操作符,将值传递给函数并返回结果
/// 用于构建流式的函数调用链
///
/// 输入类型
/// 输出类型
/// 输入值
/// 转换函数
/// 转换后的值
/// 当 func 为 null 时抛出
///
///
/// var result = 42
/// .Pipe(x => x * 2)
/// .Pipe(x => x.ToString())
/// .Pipe(s => $"Result: {s}");
///
///
public static TResult Pipe(
this TSource value,
Func func)
{
ArgumentNullException.ThrowIfNull(func);
return func(value);
}
///
/// Let:
/// 作用域函数,将值传递给函数并返回结果
/// 与 Pipe 功能相同,但提供不同的语义(Kotlin 风格)
///
/// 输入类型
/// 输出类型
/// 输入值
/// 转换函数
/// 转换后的值
/// 当 transform 为 null 时抛出
///
///
/// var result = GetUser().Let(user => new UserDto
/// {
/// Id = user.Id,
/// Name = user.Name
/// });
///
///
public static TResult Let(
this TSource value,
Func transform)
{
ArgumentNullException.ThrowIfNull(transform);
return transform(value);
}
///
/// PipeIf:
/// 条件管道,根据条件选择不同的转换函数
///
/// 输入类型
/// 输出类型
/// 输入值
/// 条件判断函数
/// 条件为真时的转换函数
/// 条件为假时的转换函数
/// 转换后的值
/// 当任何参数为 null 时抛出
///
///
/// var result = 42.PipeIf(
/// x => x > 0,
/// x => $"Positive: {x}",
/// x => $"Non-positive: {x}"
/// );
///
///
public static TResult PipeIf(
this TSource value,
Func predicate,
Func ifTrue,
Func ifFalse)
{
ArgumentNullException.ThrowIfNull(predicate);
ArgumentNullException.ThrowIfNull(ifTrue);
ArgumentNullException.ThrowIfNull(ifFalse);
return predicate(value) ? ifTrue(value) : ifFalse(value);
}
}