From af65b7fd1df203f15af5e7d8bc2f6c87d04490f5 Mon Sep 17 00:00:00 2001 From: C-xC-c Date: Sat, 8 Feb 2020 22:14:23 +0000 Subject: [PATCH] Replace ResultT with a tuple. Result is a fundamentally good idea, but just doesn't fit into bantflags properly. We don't implement the other functional extensions that would make it useful, and our use case is so small that the extra safety we get isn't worth the code complexity. It was just used as a wrapper around a tuple like (T thingWeVerifyAgainstBusinessLogic, bool failed, string errorMessage), and we can ignore the bool by using default and checking for null. Less code, easier to read. --- BantFlags/Controllers/FlagsController.cs | 10 ++--- BantFlags/Data/PostModel.cs | 14 +++---- BantFlags/Data/ResultT.cs | 30 --------------- BantFlags/Data/Staging.cs | 47 ++++++++++++------------ BantFlags/Pages/Upload.cshtml.cs | 24 ++++++------ 5 files changed, 48 insertions(+), 77 deletions(-) delete mode 100644 BantFlags/Data/ResultT.cs diff --git a/BantFlags/Controllers/FlagsController.cs b/BantFlags/Controllers/FlagsController.cs index fc9de0a..05bacdc 100644 --- a/BantFlags/Controllers/FlagsController.cs +++ b/BantFlags/Controllers/FlagsController.cs @@ -61,16 +61,16 @@ namespace BantFlags.Controllers { string splitFlag = (version ?? 0) > 1 ? "," : "||"; // comma for v2+, else || for backwards compatibility. - Result post = PostModel.Create(post_nr, board, regions, splitFlag, Database.KnownFlags, Database.Boards); + (PostModel flag, string error) = PostModel.Create(post_nr, board, regions, splitFlag, Database.KnownFlags, Database.Boards); - if (post.Failed) + if (flag is null) { - return Problem(post.ErrorMessage, statusCode: StatusCodes.Status400BadRequest); + return Problem(error, statusCode: StatusCodes.Status400BadRequest); } - await Database.InsertPost(post.Value); + await Database.InsertPost(flag); - return Ok(post.Value); + return Ok(flag); } /// diff --git a/BantFlags/Data/PostModel.cs b/BantFlags/Data/PostModel.cs index dc37230..a301b89 100644 --- a/BantFlags/Data/PostModel.cs +++ b/BantFlags/Data/PostModel.cs @@ -22,31 +22,31 @@ namespace BantFlags.Data Flags = flags; } - public static Result Create(string post_nr, string board, string regions, string splitFlag, HashSet knownFlags, HashSet boards) + public static (PostModel, string) Create(string post_nr, string board, string regions, string splitFlag, HashSet knownFlags, HashSet boards) { string[] empty = { "empty, or there were errors. Re-set your flags." }; if (!int.TryParse(post_nr, out int postNumber)) - return Result.Fail("Invalid post number."); + return (default, "Invalid post number."); if (!boards.Contains(board)) - return Result.Fail("Invalid board parameter."); + return (default, "Invalid board parameter."); if (regions == null) - return Result.Pass(new PostModel(postNumber, board, empty)); + return (new PostModel(postNumber, board, empty), default); var flags = regions.Split(splitFlag); if (flags.Count() > 30) - return Result.Fail("Too many flags."); + return (default, "Too many flags."); foreach (string flag in flags) { if (!knownFlags.Contains(flag)) // Not ideal but it's better than doing it in the controller or passing the database here. - return Result.Pass(new PostModel(postNumber, board, empty)); + return (new PostModel(postNumber, board, empty), default); } - return Result.Pass(new PostModel(postNumber, board, flags)); + return (new PostModel(postNumber, board, flags), default); } } } \ No newline at end of file diff --git a/BantFlags/Data/ResultT.cs b/BantFlags/Data/ResultT.cs deleted file mode 100644 index 4b3ba6d..0000000 --- a/BantFlags/Data/ResultT.cs +++ /dev/null @@ -1,30 +0,0 @@ -// (C) Copyright 2019 C-xC-c -// This file is part of BantFlags. -// BantFlags is licensed under the GNU AGPL Version 3.0 or later. -// see the LICENSE file or -using System; - -namespace BantFlags.Data -{ - public struct Result - { - public bool Failed { get; private set; } - - public string ErrorMessage { get; private set; } - - private T _Value { get; set; } - - public T Value => Failed ? throw new Exception() : _Value; - - public Result(bool failed, string error, T value) - { - Failed = failed; - ErrorMessage = error; - _Value = value; - } - - public static Result Pass(T value) => new Result(false, default, value); - - public static Result Fail(string error) => new Result(true, error, default); - } -} \ No newline at end of file diff --git a/BantFlags/Data/Staging.cs b/BantFlags/Data/Staging.cs index b556ab0..73f0001 100644 --- a/BantFlags/Data/Staging.cs +++ b/BantFlags/Data/Staging.cs @@ -68,35 +68,36 @@ namespace BantFlags.Data FlagMethod = method; } - public static Result CreateFromDelete(string name) - => Result.Pass(new Flag(name, Method.Delete)); // We don't need any validation for deleted flags. + public static Flag CreateFromDelete(string name) => new Flag(name, Method.Delete); // We don't need any validation for deleted flags. - public static Result CreateFromRename(string oldName, string newName, HashSet names) + public static (Flag, string) CreateFromRename(string oldName, string newName, HashSet names) { - Result fileName = ValidateFileName(newName, names); + (bool valid, string error) = ValidateFileName(newName, names); - if (fileName.Failed) - return Result.Fail(fileName.ErrorMessage); + if (!valid) + { + return (default, error); + } - return Result.Pass(new Flag(newName, oldName, Method.Rename)); + return (new Flag(newName, oldName, Method.Rename), default); } - public static async Task> CreateFromFile(IFormFile upload, HashSet names) + public static async Task<(Flag, string)> CreateFromFile(IFormFile upload, HashSet names) { byte[] PNGHeader = { 0x89, 0x50, 0x4E, 0x47, 0x0D, 0x0A, 0x1A, 0x0A }; if (upload.ContentType.ToLower() != "image/png") - return Result.Fail("Image must be a png."); + return (default, "Image must be a png."); if (upload.Length > 15 * 1024) - return Result.Fail("File too big. Max size is 15kb."); + return (default, "File too big. Max size is 15kb."); var name = Path.GetFileNameWithoutExtension(upload.FileName); - Result fileName = ValidateFileName(name, names); + (bool valid, string error) = ValidateFileName(name, names); - if (fileName.Failed) - return Result.Fail(fileName.ErrorMessage); + if (!valid) + return (default, error); using (var memoryStream = new MemoryStream()) { @@ -106,7 +107,7 @@ namespace BantFlags.Data using (var image = new MagickImage(memoryStream)) { if (image.Width != 16 || image.Height != 11) - return Result.Fail("Invalid image dimensions. Flags should be 16px by 11px."); + return (default, "Invalid image dimensions. Flags should be 16px by 11px."); } using (var reader = new BinaryReader(memoryStream)) @@ -114,11 +115,11 @@ namespace BantFlags.Data reader.BaseStream.Position = 0; if (!reader.ReadBytes(PNGHeader.Length).SequenceEqual(PNGHeader)) - return Result.Fail("Invalid png header."); + return (default, "Invalid png header."); } } - return Result.Pass(new Flag(name, Method.Add)); + return (new Flag(name, Method.Add), default); } /// @@ -126,24 +127,24 @@ namespace BantFlags.Data /// /// The file name to validate. /// The list of current file names. - private static Result ValidateFileName(string name, HashSet names) + private static (bool, string) ValidateFileName(string name, HashSet names) { if (string.IsNullOrWhiteSpace(name)) - return Result.Fail("Flag name can't be empty."); + return (false, "Flag name can't be empty."); if (name.Length > 100) - return Result.Fail("Flag name too long."); + return (false, "Flag name too long."); if (name == "empty, or there were errors. Re - set your flags.") - return Result.Fail("Invalid flag name."); + return (false, "Invalid flag name."); if (name.Contains("||") || name.Contains(",")) - return Result.Fail("Flag name contains invalid characters. You can't use \"||\" or \",\"."); + return (false, "Flag name contains invalid characters. You can't use \"||\" or \",\"."); if (names.Contains(name)) - return Result.Fail("A flag with that name already exists."); + return (false, "A flag with that name already exists."); - return Result.Pass(name); + return (true, name); } } } \ No newline at end of file diff --git a/BantFlags/Pages/Upload.cshtml.cs b/BantFlags/Pages/Upload.cshtml.cs index 35b57ae..793904f 100644 --- a/BantFlags/Pages/Upload.cshtml.cs +++ b/BantFlags/Pages/Upload.cshtml.cs @@ -43,7 +43,7 @@ namespace BantFlags public IActionResult OnPostDelete(string flag) { - var stagingFlag = Flag.CreateFromDelete(flag).Value; + var stagingFlag = Flag.CreateFromDelete(flag); StagedFlags.Flags.Add(stagingFlag); StagedFlags.Names.Remove(stagingFlag.Name); @@ -54,28 +54,28 @@ namespace BantFlags public IActionResult OnPostRename(string flag, string newName) { - var stagingFlag = Flag.CreateFromRename(flag, newName, AllNames); + (Flag stagingFlag, string error) = Flag.CreateFromRename(flag, newName, AllNames); - if (stagingFlag.Failed) + if (stagingFlag is null) { - Message = stagingFlag.ErrorMessage; + Message = error; return Page(); } - StagedFlags.Flags.Add(stagingFlag.Value); - StagedFlags.Names.Add(stagingFlag.Value.Name); + StagedFlags.Flags.Add(stagingFlag); + StagedFlags.Names.Add(stagingFlag.Name); - Message = $"{stagingFlag.Value.OldName} renamed to {stagingFlag.Value.Name}."; + Message = $"{stagingFlag.OldName} renamed to {stagingFlag.Name}."; return Page(); } public async Task OnPostAddAsync(IFormFile upload, bool gloss) { - var stagingFlag = await Flag.CreateFromFile(upload, AllNames); + (Flag stagingFlag, string error) = await Flag.CreateFromFile(upload, AllNames); - if (stagingFlag.Failed) + if (stagingFlag is null) { - Message = stagingFlag.ErrorMessage; + Message = error; return Page(); } @@ -98,9 +98,9 @@ namespace BantFlags image.Write(WebRoot + "/flags/staging/" + upload.FileName); - StagedFlags.Flags.Add(stagingFlag.Value); + StagedFlags.Flags.Add(stagingFlag); - Message = $"{stagingFlag.Value.Name} uploaded"; + Message = $"{stagingFlag.Name} uploaded"; return Page(); }