Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 0 additions & 4 deletions McdaToolkit.slnx

This file was deleted.

13 changes: 13 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,19 @@ Make sure to read the [docs](https://sarcasticmoose.github.io/mcda-toolkit-docs)
- [Math.Net Numerics](https://numerics.mathdotnet.com/)
- [Light Results](https://github.com/jscarle/LightResults)

## Extensions

### McdaToolkit.Exporters.Abstraction

Provides common interfaces and base contracts for exporting results generated by **McdaToolkit**.
It enables a consistent and extensible export mechanism, allowing different output formats to be implemented independently of the core library.

More in the [docs](src/lib/McdaToolkit.Exporters.Abstraction/README.md)

### Available extensions

#### [McdaToolkit.Exporters.Json](src/lib/McdaToolkit.Exporters.Json/README.md)

## Quick Example

Here's a simple example to show how to prepare and structure your data for an MCDA calculation using the MCDA Toolkit.
Expand Down
6 changes: 6 additions & 0 deletions src/McdaToolkit.slnx
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
<Solution>
<Project Path="lib/McdaToolkit.Exporters.Abstraction/McdaToolkit.Exporters.Abstraction.csproj" />
<Project Path="lib/McdaToolkit.Exporters.Json/McdaToolkit.Exporters.Json.csproj" />
<Project Path="lib/McdaToolkit/McdaToolkit.csproj" />
<Project Path="tests/McdaToolkit.UnitTests/McdaToolkit.UnitTests.csproj" />
</Solution>
10 changes: 0 additions & 10 deletions src/McdaToolkit/Models/Abstraction/IMcdaMethod.cs

This file was deleted.

18 changes: 0 additions & 18 deletions src/McdaToolkit/Models/Abstraction/McdaMethod.cs

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace McdaToolkit.Exporters.Abstraction.FileFormat
{
public interface IFileFormat
{
string Format { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;

namespace McdaToolkit.Exporters.Abstraction.FileName.Generators
{
public sealed class DateTimeFileNameGenerator : FileNameGeneratorBase
{
protected override string GenerateUniqueName()
{
return DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss");
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
using System.Text;

namespace McdaToolkit.Exporters.Abstraction.FileName.Generators
{
public abstract class FileNameGeneratorBase : IFileNameGenerator
{
protected abstract string GenerateUniqueName();

public string Generate()
{
return new StringBuilder()
.Append(StaticNames.FileFirstSegment)
.Append('_')
.Append(GenerateUniqueName())
.ToString();
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
namespace McdaToolkit.Exporters.Abstraction.FileName
{
public interface IFileNameGenerator
{
public string Generate();
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using LightResults;
using McdaToolkit.Exporters.Abstraction.FileWriter.Results.Success;
using McdaToolkit.Exporters.Abstraction.Path;

namespace McdaToolkit.Exporters.Abstraction.FileWriter
{
public interface IFileWriter
{
ValueTask<Result<ISuccessFileOperation>> WriteToFile(
Stream stream,
OutputPath outputPath,
CancellationToken ct = default);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
using System;
using System.IO;
using System.Threading;
using System.Threading.Tasks;
using LightResults;
using McdaToolkit.Exporters.Abstraction.FileWriter.Results.Errors;
using McdaToolkit.Exporters.Abstraction.FileWriter.Results.Success;
using McdaToolkit.Exporters.Abstraction.Path;

namespace McdaToolkit.Exporters.Abstraction.FileWriter
{
internal sealed class InternalFileWriter : IFileWriter
{
private readonly int _bufferSize;

public InternalFileWriter(int bufferSize = 8192)
{
_bufferSize = bufferSize;
}

public async ValueTask<Result<ISuccessFileOperation>> WriteToFile(
Stream stream,
OutputPath outputPath,
CancellationToken ct = default)
{
if(outputPath is null) throw new ArgumentNullException(nameof(outputPath));
if(stream is null) throw new ArgumentNullException(nameof(stream));

stream.Position = 0;
stream.Seek(0, SeekOrigin.Begin);

try
{
await using var fileStream = new FileStream(
outputPath.ToString(),
FileMode.Create,
FileAccess.ReadWrite,
FileShare.None,
_bufferSize);

fileStream.Position = 0;
fileStream.Seek(0, SeekOrigin.Begin);

var buffer = new byte[_bufferSize];
var totalWritedBytes = 0;
var currentReadBytes = 0;

while ((currentReadBytes = await stream.ReadAsync(buffer, 0, _bufferSize, ct)) > 0)
{
await fileStream.WriteAsync(buffer.AsMemory(0, currentReadBytes), ct);
totalWritedBytes += currentReadBytes;
}
if (totalWritedBytes == 0) return new NoneDataWrited();

await fileStream.FlushAsync(ct);
await stream.FlushAsync(ct);
return new DataWrited(totalWritedBytes);
}
catch (IOException ex)
{
return new IoError(ex);
}
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using System;
using LightResults;

namespace McdaToolkit.Exporters.Abstraction.FileWriter.Results.Errors
{
public class IoError : Error
{
public IoError(Exception exception) : base(exception.Message)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
namespace McdaToolkit.Exporters.Abstraction.FileWriter.Results.Success
{
public class DataWrited : ISuccessFileOperation
{
public DataWrited(int writedBytes)
{
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace McdaToolkit.Exporters.Abstraction.FileWriter.Results.Success
{
public interface ISuccessFileOperation {}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
namespace McdaToolkit.Exporters.Abstraction.FileWriter.Results.Success
{
public class NoneDataWrited : ISuccessFileOperation {}
}
26 changes: 26 additions & 0 deletions src/lib/McdaToolkit.Exporters.Abstraction/IExporter.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
using System.Threading;
using System.Threading.Tasks;
using LightResults;
using McdaToolkit.Data;

namespace McdaToolkit.Exporters.Abstraction
{
public interface IExporter
{
/// <summary>
/// Asynchronously exports the provided execution details.
/// </summary>
/// <param name="details">
/// The <see cref="ExecutionDetails"/> containing the results of an MCDA method execution,
/// including rankings, criteria, and any metadata.
/// </param>
/// <param name="ct">A <see cref="CancellationToken"/> to observe while performing the export.</param>
/// <returns>
/// A <see cref="ValueTask"/> representing the asynchronous operation.
/// The <see cref="IResult"/> indicates whether the export succeeded or failed.
/// </returns>
ValueTask<IResult> ExportAsync(
ExecutionDetails details,
CancellationToken ct);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
using McdaToolkit.Exporters.Abstraction.Path;

namespace McdaToolkit.Exporters.Abstraction
{
internal interface IExporterSettings
{
public OutputPath Path { get; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<Nullable>enable</Nullable>
<Version>1.0.0</Version>
<PackageReadmeFile>README.md</PackageReadmeFile>
<TargetFrameworks>netstandard2.1;net6.0</TargetFrameworks>
<Copyright>© 2026 Jakub Tokarczyk</Copyright>
<PackageLicenseExpression>MIT</PackageLicenseExpression>
<RepositoryUrl>https://github.com/SarcasticMoose/mcda-toolkit</RepositoryUrl>
<PackageIcon>icon.png</PackageIcon>
<GenerateDocumentationFile>true</GenerateDocumentationFile>
</PropertyGroup>

<ItemGroup Label="Resources">
<None Include="README.md" Pack="true" PackagePath="\" />
<None Include="..\..\..\images\icon.png" Pack="true" PackagePath="\" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\McdaToolkit\McdaToolkit.csproj" />
</ItemGroup>

<ItemGroup>
<InternalsVisibleTo Include="McdaToolkit.Exporters.Json.UnitTests" />
<InternalsVisibleTo Include="McdaToolkit.Exporters.Json" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
using McdaToolkit.Exporters.Abstraction.FileName;

namespace McdaToolkit.Exporters.Abstraction.Path
{
public interface IOutputPathBuilder
{
IOutputPathBuilder WithDirectory(string directory);
IOutputPathBuilder WithFileNameGenerator(IFileNameGenerator fileNameGenerator);
OutputPath Build();
}
}
21 changes: 21 additions & 0 deletions src/lib/McdaToolkit.Exporters.Abstraction/Path/OutputPath.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
using System;

namespace McdaToolkit.Exporters.Abstraction.Path
{
public class OutputPath
{
private readonly string _fullPath;

internal OutputPath(string fullPath)
{
_fullPath = fullPath;
}

public override string ToString()
{
return _fullPath;
}

public static OutputPath Default => new OutputPath(System.IO.Path.Join(Environment.CurrentDirectory, ""));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,42 @@
using System;
using System.Text;
using McdaToolkit.Exporters.Abstraction.FileFormat;
using McdaToolkit.Exporters.Abstraction.FileName;
using McdaToolkit.Exporters.Abstraction.FileName.Generators;

namespace McdaToolkit.Exporters.Abstraction.Path
{
public abstract class OutputPathBuilder<TFileFormat> :
IOutputPathBuilder
where TFileFormat : IFileFormat, new()
{
private IFileNameGenerator? _fileNameGenerator;
private IFileFormat _fileFormat = new TFileFormat();
private string? _directory;

public IOutputPathBuilder WithDirectory(string directory)
{
_directory = directory;
return this;
}

public IOutputPathBuilder WithFileNameGenerator(IFileNameGenerator fileNameGenerator)
{
_fileNameGenerator = fileNameGenerator;
return this;
}

public OutputPath Build()
{
_fileNameGenerator ??= new DateTimeFileNameGenerator();
_directory ??= Environment.CurrentDirectory;

var fileName = new StringBuilder();
fileName.Append(_fileNameGenerator.Generate());
fileName.Append('.');
fileName.Append(_fileFormat.Format);

return new OutputPath(System.IO.Path.Join(_directory, fileName.ToString()));
}
}
}
Loading
Loading