Skip to content

Commit

Permalink
prefer EitherAsync instead of Task<Either<>> (#33)
Browse files Browse the repository at this point in the history
* prefer EitherAsync instead of Task<Either<>>
* update of dbosoft.functional package
  • Loading branch information
fw2568 authored Apr 22, 2021
1 parent 2be61ca commit 5e6388f
Show file tree
Hide file tree
Showing 9 changed files with 144 additions and 165 deletions.
12 changes: 6 additions & 6 deletions src/YaNco.Abstractions/IConnection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ namespace Dbosoft.YaNco
{
public interface IConnection : IDisposable
{
Task<Either<RfcErrorInfo, Unit>> CommitAndWait();
Task<Either<RfcErrorInfo, Unit>> Commit();
Task<Either<RfcErrorInfo, Unit>> Rollback();
Task<Either<RfcErrorInfo, IFunction>> CreateFunction(string name);
Task<Either<RfcErrorInfo, Unit>> InvokeFunction(IFunction function);
Task<Either<RfcErrorInfo, Unit>> AllowStartOfPrograms(StartProgramDelegate callback);
EitherAsync<RfcErrorInfo, Unit> CommitAndWait();
EitherAsync<RfcErrorInfo, Unit> Commit();
EitherAsync<RfcErrorInfo, Unit> Rollback();
EitherAsync<RfcErrorInfo, IFunction> CreateFunction(string name);
EitherAsync<RfcErrorInfo, Unit> InvokeFunction(IFunction function);
EitherAsync<RfcErrorInfo, Unit> AllowStartOfPrograms(StartProgramDelegate callback);
}
}
17 changes: 11 additions & 6 deletions src/YaNco.Abstractions/IRfcContext.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,16 @@ namespace Dbosoft.YaNco
{
public interface IRfcContext : IDisposable
{
Task<Either<RfcErrorInfo, IFunction>> CreateFunction(string name);
Task<Either<RfcErrorInfo, Unit>> InvokeFunction(IFunction function);
Task<Either<RfcErrorInfo, IRfcContext>> Ping();
Task<Either<RfcErrorInfo, Unit>> Commit();
Task<Either<RfcErrorInfo, Unit>> CommitAndWait();
Task<Either<RfcErrorInfo, Unit>> Rollback();
EitherAsync<RfcErrorInfo, IFunction> CreateFunction(string name);
EitherAsync<RfcErrorInfo, Unit> InvokeFunction(IFunction function);
EitherAsync<RfcErrorInfo, IRfcContext> Ping();
EitherAsync<RfcErrorInfo, Unit> Commit();
EitherAsync<RfcErrorInfo, Unit> CommitAndWait();
EitherAsync<RfcErrorInfo, Unit> Rollback();

Task<Either<RfcErrorInfo, IRfcContext>> PingAsync();
Task<Either<RfcErrorInfo, Unit>> CommitAsync();
Task<Either<RfcErrorInfo, Unit>> CommitAndWaitAsync();
Task<Either<RfcErrorInfo, Unit>> RollbackAsync();
}
}
2 changes: 1 addition & 1 deletion src/YaNco.Abstractions/YaNco.Abstractions.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ This package contains abstraction definitions.
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Dbosoft.Functional" Version="1.0.0" />
<PackageReference Include="Dbosoft.Functional" Version="2.0.0-beta.1" />
<PackageReference Include="GitVersionTask" Version="5.3.7">
<PrivateAssets>all</PrivateAssets>
<IncludeAssets>runtime; build; native; contentfiles; analyzers</IncludeAssets>
Expand Down
33 changes: 16 additions & 17 deletions src/YaNco.Core/Connection.cs
Original file line number Diff line number Diff line change
Expand Up @@ -69,47 +69,46 @@ public Connection(
});
}

public static Task<Either<RfcErrorInfo,IConnection>> Create(IDictionary<string, string> connectionParams, IRfcRuntime runtime)
public static EitherAsync<RfcErrorInfo,IConnection> Create(IDictionary<string, string> connectionParams, IRfcRuntime runtime)
{
return runtime.OpenConnection(connectionParams).Map(handle => (IConnection) new Connection(handle, runtime)).AsTask();
return runtime.OpenConnection(connectionParams).ToAsync().Map(handle => (IConnection) new Connection(handle, runtime));
}


public Task<Either<RfcErrorInfo, Unit>> CommitAndWait()
public EitherAsync<RfcErrorInfo, Unit> CommitAndWait()
{
return CreateFunction("BAPI_TRANSACTION_COMMIT")
.SetField("WAIT", "X")
.MapAsync(f => f.Apply(InvokeFunction).Map(u => f))
.Bind(f => f.Apply(InvokeFunction).Map(u => f))
.HandleReturn()
.MapAsync(f => Unit.Default);
.Map(f => Unit.Default);

}

public Task<Either<RfcErrorInfo, Unit>> Commit()
public EitherAsync<RfcErrorInfo, Unit> Commit()
{
return CreateFunction("BAPI_TRANSACTION_COMMIT")
.MapAsync(f => f.Apply(InvokeFunction).Map(u=>f))
.Bind(f => f.Apply(InvokeFunction).Map(u=>f))
.HandleReturn()
.MapAsync(f => Unit.Default);
.Map(f => Unit.Default);

}

public Task<Either<RfcErrorInfo, Unit>> Rollback()
public EitherAsync<RfcErrorInfo, Unit> Rollback()
{
return CreateFunction("BAPI_TRANSACTION_ROLLBACK")
.BindAsync(InvokeFunction);
.Bind(InvokeFunction);

}


public Task<Either<RfcErrorInfo, IFunction>> CreateFunction(string name) =>
_stateAgent.Tell(new CreateFunctionMessage(name)).MapAsync(r => (IFunction) r);
public EitherAsync<RfcErrorInfo, IFunction> CreateFunction(string name) =>
_stateAgent.Tell(new CreateFunctionMessage(name)).ToAsync().Map(r => (IFunction) r);

public Task<Either<RfcErrorInfo, Unit>> InvokeFunction(IFunction function) =>
_stateAgent.Tell(new InvokeFunctionMessage(function)).MapAsync(r => Unit.Default);
public EitherAsync<RfcErrorInfo, Unit> InvokeFunction(IFunction function) =>
_stateAgent.Tell(new InvokeFunctionMessage(function)).ToAsync().Map(r => Unit.Default);

public Task<Either<RfcErrorInfo, Unit>> AllowStartOfPrograms(StartProgramDelegate callback) =>
_stateAgent.Tell(new AllowStartOfProgramsMessage(callback)).MapAsync(r => Unit.Default);
public EitherAsync<RfcErrorInfo, Unit> AllowStartOfPrograms(StartProgramDelegate callback) =>
_stateAgent.Tell(new AllowStartOfProgramsMessage(callback)).ToAsync().Map(r => Unit.Default);


private class AgentMessage
Expand Down
25 changes: 9 additions & 16 deletions src/YaNco.Core/FunctionalDataContainerExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,46 +1,39 @@
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
using LanguageExt;

namespace Dbosoft.YaNco
{
public static class FunctionalDataContainerExtensions
{
public static Either<RfcErrorInfo, TDataContainer> SetField<TDataContainer, T>(this Either<RfcErrorInfo, TDataContainer> self, string name, T value)
public static EitherAsync<RfcErrorInfo, TDataContainer> SetField<TDataContainer, T>(this EitherAsync<RfcErrorInfo, TDataContainer> self, string name, T value)
where TDataContainer : IDataContainer
{
return self.Bind(s => s.SetField(name, value).Map(u=> s));
}

public static Task<Either<RfcErrorInfo, TDataContainer>> SetField<TDataContainer, T>(this Task<Either<RfcErrorInfo, TDataContainer>> self, string name, T value)
where TDataContainer : IDataContainer
{
return self.BindAsync(s => s.SetField(name, value).Map(u => s));
return self.Bind(s => s.SetField(name, value).Map(u => s).ToAsync());
}


public static Task<Either<RfcErrorInfo, TDataContainer>> SetStructure<TDataContainer>(this Task<Either<RfcErrorInfo, TDataContainer>> self, string structureName, Func<Either<RfcErrorInfo, IStructure>, Either<RfcErrorInfo, IStructure>> map)
public static EitherAsync<RfcErrorInfo, TDataContainer> SetStructure<TDataContainer>(this EitherAsync<RfcErrorInfo, TDataContainer> self, string structureName, Func<Either<RfcErrorInfo, IStructure>, Either<RfcErrorInfo, IStructure>> map)
where TDataContainer : IDataContainer
{
return self.BindAsync(dc => dc.GetStructure(structureName).Use(used => used.Apply(map).Map(u => dc)));
return self.Bind(dc => dc.GetStructure(structureName).Use(used => used.Apply(map).Map(u => dc)).ToAsync());
}

public static Task<Either<RfcErrorInfo, TDataContainer>> SetTable<TDataContainer, TInput>(
this Task<Either<RfcErrorInfo, TDataContainer>> self, string tableName,
public static EitherAsync<RfcErrorInfo, TDataContainer> SetTable<TDataContainer, TInput>(
this EitherAsync<RfcErrorInfo, TDataContainer> self, string tableName,
IEnumerable<TInput> inputList,
Func<Either<RfcErrorInfo, IStructure>, TInput, Either<RfcErrorInfo, IStructure>> map)
where TDataContainer : IDataContainer
=> SetTable(self, tableName, () => inputList, map);

public static Task<Either<RfcErrorInfo, TDataContainer>> SetTable<TDataContainer, TInput>(this Task<Either<RfcErrorInfo, TDataContainer>> self, string tableName, Func<IEnumerable<TInput>> inputListFunc, Func<Either<RfcErrorInfo, IStructure>, TInput, Either<RfcErrorInfo, IStructure>> map)
public static EitherAsync<RfcErrorInfo, TDataContainer> SetTable<TDataContainer, TInput>(this EitherAsync<RfcErrorInfo, TDataContainer> self, string tableName, Func<IEnumerable<TInput>> inputListFunc, Func<Either<RfcErrorInfo, IStructure>, TInput, Either<RfcErrorInfo, IStructure>> map)
where TDataContainer : IDataContainer
{
return self.BindAsync(dc => dc.GetTable(tableName).Use(used=> used.Map(table => (dc, table, inputListFunc))
return self.Bind(dc => dc.GetTable(tableName).Use(used=> used.Map(table => (dc, table, inputListFunc))

.Bind(t => t.inputListFunc().Map(
input => t.table.AppendRow().Apply(row=>map(row,input))
).Traverse(l => l).Map(_ => dc))));
).Traverse(l => l).Map(_ => dc))).ToAsync());

}

Expand Down
95 changes: 34 additions & 61 deletions src/YaNco.Core/FunctionalFunctionsExtensions.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading.Tasks;
using LanguageExt;

Expand All @@ -9,21 +10,21 @@ namespace Dbosoft.YaNco
public static class FunctionalFunctionsExtensions
{

public static Task<Either<RfcErrorInfo, R1>> Commit<R1>(this Task<Either<RfcErrorInfo, R1>> self,
internal static EitherAsync<RfcErrorInfo, R1> Commit<R1>(this EitherAsync<RfcErrorInfo, R1> self,
IRfcContext context)
{
return self.BindAsync(res => context.Commit().MapAsync(u => res));
return self.Bind(res => context.Commit().Map(u => res));
}

public static Task<Either<RfcErrorInfo, R1>> CommitAndWait<R1>(this Task<Either<RfcErrorInfo, R1>> self,
internal static EitherAsync<RfcErrorInfo, R1> CommitAndWait<R1>(this EitherAsync<RfcErrorInfo, R1> self,
IRfcContext context)
{
return self.BindAsync(res => context.CommitAndWait().MapAsync(u => res));
return self.Bind(res => context.CommitAndWait().Map(u => res));
}

public static Task<Either<RfcErrorInfo, IFunction>> HandleReturn(this Task<Either<RfcErrorInfo, IFunction>> self)
public static EitherAsync<RfcErrorInfo, IFunction> HandleReturn(this EitherAsync<RfcErrorInfo, IFunction> self)
{
return self.BindAsync(f =>
return self.Bind(f => (
from ret in f.GetStructure("RETURN")
from type in ret.GetField<string>("TYPE")
from id in ret.GetField<string>("ID")
Expand All @@ -35,7 +36,7 @@ from v3 in ret.GetField<string>("MESSAGE_V3")
from v4 in ret.GetField<string>("MESSAGE_V4")

from _ in ErrorOrResult(f, type, id, number, message, v1, v2, v3, v4)
select f);
select f).ToAsync());

}

Expand All @@ -48,91 +49,63 @@ private static Either<RfcErrorInfo, TResult> ErrorOrResult<TResult>(TResult resu
}

// ReSharper disable InconsistentNaming
public static Task<Either<RfcErrorInfo, TResult>> CallFunction<TRInput,TResult>(this IRfcContext context, string functionName, Func<Task<Either<RfcErrorInfo, IFunction>>, Task<Either<RfcErrorInfo, TRInput>>> Input, Func<Task<Either<RfcErrorInfo, IFunction>>, Task<Either<RfcErrorInfo, TResult>>> Output)
{
return context.CreateFunction(functionName).Use(
func => func
.Apply(Input).BindAsync(i=>func)
.BindAsync(context.InvokeFunction).Map(i => func)
.Apply(Output));

}

public static Task<Either<RfcErrorInfo, TResult>> CallFunction<TRInput, TResult>(this IRfcContext context, string functionName, Func<Task<Either<RfcErrorInfo, IFunction>>, Task<Either<RfcErrorInfo, TRInput>>> Input, Func<Task<Either<RfcErrorInfo, IFunction>>, EitherAsync<RfcErrorInfo, TResult>> Output)
public static EitherAsync<RfcErrorInfo, TResult> CallFunction<TRInput, TResult>(this IRfcContext context,
string functionName, Func<EitherAsync<RfcErrorInfo, IFunction>, EitherAsync<RfcErrorInfo, TRInput>> Input,
Func<IFunction, Either<RfcErrorInfo,TResult>> Output)
{
return context.CreateFunction(functionName).Use(
func => func
.Apply(Input).BindAsync(i => func)
.BindAsync(context.InvokeFunction).Map(i => func)
.Apply(f => Output(f).ToEither()));

.Apply(Input).Bind(i => func)
.Bind(context.InvokeFunction).Bind(i => func)
.Bind(f=> Output(f).ToAsync()));
}

public static Task<Either<RfcErrorInfo, TResult>> CallFunction<TResult>(this IRfcContext context, string functionName, Func<Task<Either<RfcErrorInfo, IFunction>>, Task<Either<RfcErrorInfo, TResult>>> Output)
public static Task<Either<RfcErrorInfo, TResult>> CallFunctionAsync<TRInput, TResult>(this IRfcContext context,
string functionName, Func<EitherAsync<RfcErrorInfo, IFunction>, EitherAsync<RfcErrorInfo, TRInput>> Input,
Func<IFunction, Either<RfcErrorInfo, TResult>> Output)
{
return context.CreateFunction(functionName).Use(
func => func
.BindAsync(context.InvokeFunction).Map(i => func)
.Apply(Output));
return CallFunction(context, functionName, Input, Output).ToEither();
}

public static Task<Either<RfcErrorInfo, TResult>> CallFunction<TResult>(this IRfcContext context, string functionName, Func<Task<Either<RfcErrorInfo, IFunction>>, EitherAsync<RfcErrorInfo, TResult>> Output)
public static EitherAsync<RfcErrorInfo, TResult> CallFunction<TResult>(this IRfcContext context, string functionName, Func<IFunction, Either<RfcErrorInfo, TResult>> Output)
{
return context.CreateFunction(functionName).Use(
func => func
.BindAsync(context.InvokeFunction).Map(i => func)
.Apply(f => Output(f).ToEither()));
.Bind(context.InvokeFunction).Bind(i => func)
.Bind(f => Output(f).ToAsync()));
}

public static Task<Either<RfcErrorInfo, Unit>> CallFunctionAsUnit<TRInput>(this IRfcContext context, string functionName, Func<Task<Either<RfcErrorInfo, IFunction>>, Task<Either<RfcErrorInfo, TRInput>>> Input)
public static Task<Either<RfcErrorInfo, TResult>> CallFunctionAsync<TResult>(this IRfcContext context,
string functionName, Func<IFunction, Either<RfcErrorInfo, TResult>> Output)
{
return context.CreateFunction(functionName).Use(
func => func
.Apply(Input).BindAsync(i => func)
.BindAsync(context.InvokeFunction));
return CallFunction(context, functionName, Output).ToEither();
}

public static Task<Either<RfcErrorInfo, Unit>> CallFunctionAsUnit<TRInput,TResult>(this IRfcContext context, string functionName, Func<Task<Either<RfcErrorInfo, IFunction>>, Task<Either<RfcErrorInfo, TRInput>>> Input, Func<Task<Either<RfcErrorInfo, IFunction>>, Task<Either<RfcErrorInfo, TResult>>> Output)
public static EitherAsync<RfcErrorInfo, Unit> CallFunctionAsUnit<TRInput>(this IRfcContext context, string functionName, Func<EitherAsync<RfcErrorInfo, IFunction>, EitherAsync<RfcErrorInfo, TRInput>> Input)
{
return context.CreateFunction(functionName).Use(
func => func
.Apply(Input).BindAsync(i => func)
.BindAsync(context.InvokeFunction).Map(i => func)
.Apply(Output)).MapAsync(f => Unit.Default);

.Apply(Input).Bind(i => func)
.Bind(context.InvokeFunction));
}

public static Task<Either<RfcErrorInfo, Unit>> CallFunctionAsUnit<TRInput, TResult>(this IRfcContext context, string functionName, Func<Task<Either<RfcErrorInfo, IFunction>>, Task<Either<RfcErrorInfo, TRInput>>> Input, Func<Task<Either<RfcErrorInfo, IFunction>>, EitherAsync<RfcErrorInfo, TResult>> Output)
public static Task<Either<RfcErrorInfo, Unit>> CallFunctionAsUnitAsync<TRInput>(this IRfcContext context,
string functionName, Func<EitherAsync<RfcErrorInfo, IFunction>, EitherAsync<RfcErrorInfo, TRInput>> Input)
{
return context.CreateFunction(functionName).Use(
func => func
.Apply(Input).BindAsync(i => func)
.BindAsync(context.InvokeFunction).Map(i => func)
.Apply(f => Output(f).ToEither()))
.MapAsync(f => Unit.Default);

return CallFunctionAsUnit(context, functionName, Input).ToEither();
}

public static Task<Either<RfcErrorInfo, Unit>> CallFunction(this IRfcContext context, string functionName)
public static EitherAsync<RfcErrorInfo, Unit> CallFunction(this IRfcContext context, string functionName)
{
return context.CreateFunction(functionName).Use(
func => func.BindAsync(context.InvokeFunction));

}
func => func.Bind(context.InvokeFunction));

public static Task<Either<RfcErrorInfo, T>> GetField<T>(this Task<Either<RfcErrorInfo, IFunction>> self, string name)
{
return self.BindAsync(s => s.GetField<T>(name));
}

static public EitherAsync<RfcErrorInfo, IEnumerable<TResult>> MapTable<TResult>(this Task<Either<RfcErrorInfo, IFunction>> self, string tableName, Func<IStructure, Either<RfcErrorInfo, TResult>> mapperFunc)
{
return self.BindAsync(f => f.MapTable(tableName, mapperFunc)).ToAsync();
}

static public EitherAsync<RfcErrorInfo, TResult> MapStructure<TResult>(this Task<Either<RfcErrorInfo, IFunction>> self, string structureName, Func<IStructure, Either<RfcErrorInfo, TResult>> mapperFunc)
public static Task<Either<RfcErrorInfo, Unit>> CallFunctionAsync(this IRfcContext context, string functionName)
{
return self.BindAsync(f => f.MapStructure(structureName, mapperFunc)).ToAsync();
return CallFunction(context, functionName).ToEither();
}
}
}
Loading

0 comments on commit 5e6388f

Please sign in to comment.