Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Юдин Павел #172

Open
wants to merge 5 commits into
base: master
Choose a base branch
from
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
21 changes: 18 additions & 3 deletions ErrorHandling/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -58,21 +58,36 @@ public static Result<TOutput> Then<TInput, TOutput>(
this Result<TInput> input,
Func<TInput, TOutput> continuation)
{
throw new NotImplementedException();
return input.Then(inut => Of(() => continuation(inut)));
}

public static Result<TOutput> Then<TInput, TOutput>(
this Result<TInput> input,
Func<TInput, Result<TOutput>> continuation)
{
throw new NotImplementedException();
return input.IsSuccess ? continuation(input.Value) : Fail<TOutput>(input.Error);
}

public static Result<TInput> OnFail<TInput>(
this Result<TInput> input,
Action<string> handleError)
{
throw new NotImplementedException();
if (!input.IsSuccess) {
handleError(input.Error);
}

return input;
}

public static Result<TInput> RefineError<TInput>(this Result<TInput> input, string error)
{
return input.IsSuccess ? input : input.ReplaceError(e => $"{error}. {input.Error}");
}


public static Result<TInput> ReplaceError<TInput>(this Result<TInput> input, Func<string, string> error)
{
return input.IsSuccess ? input : Fail<TInput>(error(input.Error));
}
}
}
3 changes: 1 addition & 2 deletions ErrorHandling/Result_should.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
using FakeItEasy;
using FluentAssertions;
using NUnit.Framework;
using ResultOf;

namespace ResultOfTask
{
Expand Down Expand Up @@ -141,7 +142,6 @@ public void RunThen_WhenOk_ComplexScenario()
.Then(hex => parsed.GetValueOrThrow() + " -> " + Guid.Parse(hex + hex + hex + hex));
res.Should().BeEquivalentTo(Result.Ok("1358571172 -> 50fa26a4-50fa-26a4-50fa-26a450fa26a4"));
}
/*
[Test]
public void ReplaceError_IfFail()
{
Expand Down Expand Up @@ -175,6 +175,5 @@ public void RefineError_AddErrorMessageBeforePreviousErrorText()
.RefineError("Posting results to db")
.Should().BeEquivalentTo(Result.Fail<None>("Posting results to db. No connection"));
}
*/
}
}
15 changes: 8 additions & 7 deletions FileSenderRailway/Dependencies.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using System;
using System.Security.Cryptography.X509Certificates;
using ResultOf;

namespace FileSenderRailway
{
Expand All @@ -10,13 +11,11 @@ public interface ICryptographer

public interface IRecognizer
{
/// <exception cref="FormatException">Not recognized</exception>
Document Recognize(FileContent file);
Result<Document> Recognize(FileContent file);
}

public interface ISender
{
/// <exception cref="InvalidOperationException">Can't send</exception>
void Send(Document document);
}

Expand All @@ -30,10 +29,10 @@ public Document(string name, byte[] content, DateTime created, string format)
Content = content;
}

public string Name { get; set; }
public DateTime Created { get; set; }
public string Format { get; set; }
public byte[] Content { get; set; }
public string Name { get;}
public DateTime Created { get; }
public string Format { get; }
public byte[] Content { get; }
}

public class FileContent
Expand All @@ -59,5 +58,7 @@ public FileSendResult(FileContent file, string error = null)
public FileContent File { get; }
public string Error { get; }
public bool IsSuccess => Error == null;


}
}
55 changes: 28 additions & 27 deletions FileSenderRailway/FileSender.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography.X509Certificates;
using ResultOf;

namespace FileSenderRailway
{
Expand All @@ -23,42 +25,41 @@ public FileSender(
this.now = now;
}

private Result<Document> PrepareFileToSend(FileContent file, X509Certificate certificate)
{
var doc = recognizer.Recognize(file)
.Then(IsValidFormatVersion)
.Then(IsValidTimestamp)
.Then(doc => new Document(doc.Name,
cryptographer.Sign(doc.Content, certificate), doc.Created,
doc.Format))
.RefineError("Can't prepare file to send");
return doc;
}

public IEnumerable<FileSendResult> SendFiles(FileContent[] files, X509Certificate certificate)
{
foreach (var file in files)
{
string errorMessage = null;
try
{
Document doc = recognizer.Recognize(file);
if (!IsValidFormatVersion(doc))
throw new FormatException("Invalid format version");
if (!IsValidTimestamp(doc))
throw new FormatException("Too old document");
doc.Content = cryptographer.Sign(doc.Content, certificate);
sender.Send(doc);
}
catch (FormatException e)
{
errorMessage = "Can't prepare file to send. " + e.Message;
}
catch (InvalidOperationException e)
{
errorMessage = "Can't send. " + e.Message;
}
yield return new FileSendResult(file, errorMessage);
}
return from file in files
let doc = PrepareFileToSend(file, certificate).Then(doc => sender.Send(doc))
let errorMessage = doc.Error
select new FileSendResult(file, errorMessage);
}

private static Result<Document> IsValidFormatVersion(Document doc)
{
return CheckDocument(doc, d => d.Format == "4.0" || d.Format == "3.1", "Invalid format version");
;
}

private bool IsValidFormatVersion(Document doc)
private static Result<Document> CheckDocument(Document doc, Func<Document, bool> usl, string error)
{
return doc.Format == "4.0" || doc.Format == "3.1";
return usl(doc) ? doc : Result.Fail<Document>(error);
}

private bool IsValidTimestamp(Document doc)
private Result<Document> IsValidTimestamp(Document doc)
{
var oneMonthBefore = now().AddMonths(-1);
return doc.Created > oneMonthBefore;
return CheckDocument(doc, d => doc.Created > oneMonthBefore, "Too old document");
}
}
}
3 changes: 2 additions & 1 deletion FileSenderRailway/FileSender_Should.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
using FakeItEasy;
using FluentAssertions;
using NUnit.Framework;
using ResultOf;

namespace FileSenderRailway
{
Expand Down Expand Up @@ -51,7 +52,7 @@ public void BeOk_WhenGoodFormat(
public void Fail_WhenNotRecognized()
{
A.CallTo(() => recognizer.Recognize(file))
.Throws(new FormatException("Can't recognize"));
.Returns(Result.Fail<Document>("Can't recognize"));

VerifyErrorOnPrepareFile(file, certificate);
}
Expand Down
38 changes: 38 additions & 0 deletions TagsCloud/App/Actions/CircleCloudAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
using TagsCloud.App.Infrastructure;
using TagsCloud.CloudLayouter;
using TagsCloud.Infrastructure;
using TagsCloud.Infrastructure.UiActions;

namespace TagsCloud.App.Actions;

public class CircleCloudAction : IUiAction
{
private readonly IImageHolder imageHolder;
private readonly TagCloudPainter painter;
private readonly AppSettings settings;
private readonly Spiral spiral;

public CircleCloudAction(
AppSettings appSettings, IImageHolder imageHolder, TagCloudPainter painter, Spiral spiral)
{
settings = appSettings;
this.imageHolder = imageHolder;
this.painter = painter;
this.spiral = spiral;
}

public MenuCategory Category => MenuCategory.Types;
public string Name => "Круг";
public string Description => "";

public void Perform()
{
if (settings.File == null)
{
ErrorHandler.HandleError("сначала загрузи файл");
return;
}

painter.Paint(settings.File.FullName, spiral).OnFail(ErrorHandler.HandleError);
}
}
35 changes: 35 additions & 0 deletions TagsCloud/App/Actions/FlowerCloudAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
using TagsCloud.App.Infrastructure;
using TagsCloud.CloudLayouter;
using TagsCloud.Infrastructure;
using TagsCloud.Infrastructure.UiActions;

namespace TagsCloud.App.Actions;

public class FlowerCloudAction : IUiAction
{
private readonly FlowerSpiral flowerSpiral;
private readonly TagCloudPainter painter;
private readonly AppSettings settings;

public FlowerCloudAction(TagCloudPainter painter, AppSettings settings, FlowerSpiral spiral)
{
flowerSpiral = spiral;
this.settings = settings;
this.painter = painter;
}

public MenuCategory Category => MenuCategory.Types;
public string Name => "Цветок";
public string Description => "";

public void Perform()
{
if (settings.File == null)
{
ErrorHandler.HandleError("сначала загрузи файл");
return;
}

painter.Paint(settings.File.FullName, flowerSpiral).OnFail(ErrorHandler.HandleError);
}
}
29 changes: 29 additions & 0 deletions TagsCloud/App/Actions/ImageSettingsAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
using TagsCloud.App.Infrastructure;
using TagsCloud.App.Settings;
using TagsCloud.Infrastructure;
using TagsCloud.Infrastructure.UiActions;

namespace TagsCloud.App.Actions;

public class ImageSettingsAction : IUiAction
{
private readonly IImageHolder imageHolder;
private readonly ImageSettings imageSettings;

public ImageSettingsAction(IImageHolder imageHolder,
ImageSettings imageSettings)
{
this.imageHolder = imageHolder;
this.imageSettings = imageSettings;
}

public MenuCategory Category => MenuCategory.Settings;
public string Name => "Изображение...";
public string Description => "Размеры изображения";

public void Perform()
{
SettingsForm.For(imageSettings).ShowDialog();
imageHolder.RecreateImage(imageSettings).OnFail(ErrorHandler.HandleError);
}
}
36 changes: 36 additions & 0 deletions TagsCloud/App/Actions/SaveFileAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Windows.Forms;
using TagsCloud.App.Infrastructure;
using TagsCloud.Infrastructure.UiActions;

namespace TagsCloud.App.Actions;

public class SaveFileAction : IUiAction
{
private readonly IImageHolder imageHolder;

public SaveFileAction(IImageHolder imageHolder)
{
this.imageHolder = imageHolder;
}

public MenuCategory Category => MenuCategory.File;
public string Name => "Сохранить";
public string Description => "Сохранить изображение в файл";

public void Perform()
{
var imagesDirectoryPath = Path.GetFullPath("..//..//..//images");
if (!Directory.Exists(imagesDirectoryPath)) Directory.CreateDirectory(imagesDirectoryPath);
var dialog = new SaveFileDialog
{
CheckFileExists = false,
InitialDirectory = Path.GetFullPath(imagesDirectoryPath),
DefaultExt = "png",
FileName = "image.png",
Filter = "Изображения (*.png)|*.png"
};
var res = dialog.ShowDialog();
if (res == DialogResult.OK)
imageHolder.SaveImage(dialog.FileName).OnFail(ErrorHandler.HandleError);
}
}
32 changes: 32 additions & 0 deletions TagsCloud/App/Actions/TagSettingsAction.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
using System.Drawing.Text;
using TagsCloud.App.Infrastructure;
using TagsCloud.App.Settings;
using TagsCloud.Infrastructure;
using TagsCloud.Infrastructure.UiActions;

namespace TagsCloud.App.Actions;

public class TagSettingsAction : IUiAction
{
private readonly HashSet<string> fonts;
private readonly TagSettings tag;

public TagSettingsAction(TagSettings tag)
{
this.tag = tag;
fonts = new InstalledFontCollection().Families.Select(f => f.Name).ToHashSet();
}

public MenuCategory Category => MenuCategory.Settings;
public string Name => "Облако тегов...";
public string Description => "";

public void Perform()
{
SettingsForm.For(tag).ShowDialog();

if (!fonts.Contains(tag.FontFamily)) ErrorHandler.HandleError($"Шрифт {tag.FontFamily} не найден");

if (tag.Size < 0) ErrorHandler.HandleError("Размер шрифта не должен быть отрицательным");
}
}
Loading