From c2f5583c0e151a5942b463061d999b997a27adf1 Mon Sep 17 00:00:00 2001 From: Alexandros Kritikos Date: Tue, 16 Feb 2021 12:27:47 +0200 Subject: [PATCH] =?UTF-8?q?=E2=9C=A8=20Adds=20FileInfoToString=20converter?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Converters/FileInfoToStringConverter.cs | 59 +++++++++++++++ .../FileInfoToStringConverter.cs | 75 +++++++++++++++++++ 2 files changed, 134 insertions(+) create mode 100644 src/Configuration.Persistence/Converters/FileInfoToStringConverter.cs create mode 100644 tests/Configuration.PersistenceTests/ConverterTests/FileInfoToStringConverter.cs diff --git a/src/Configuration.Persistence/Converters/FileInfoToStringConverter.cs b/src/Configuration.Persistence/Converters/FileInfoToStringConverter.cs new file mode 100644 index 0000000..122ab56 --- /dev/null +++ b/src/Configuration.Persistence/Converters/FileInfoToStringConverter.cs @@ -0,0 +1,59 @@ +namespace Kritikos.Configuration.Persistence.Converters +{ + using System.IO; + + using Microsoft.EntityFrameworkCore.Storage; + using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + + /// + /// Converts from to and from string. + /// + public class FileInfoToStringConverter : ValueConverter + { + /// + /// Initializes a new instance of the class. + /// + /// Character used as directory separator in the persistence layer. + /// used as path base when handling relative paths. + /// + /// Hints that can be used by the to create data types with appropriate + /// facets for the converted data. + /// + public FileInfoToStringConverter( + char separator, + FileSystemInfo? basePath = null, + ConverterMappingHints? mappingHints = null) + : base( + v => FromFileInfo(basePath, v, separator), + v => FromPath(basePath, v, separator), + mappingHints) + { + } + + private static FileInfo FromPath(FileSystemInfo? basePath, string filePath, char separator) + { + var path = (basePath == null + ? filePath + : Path.Combine(basePath.FullName, filePath)) + .Replace(separator, Path.DirectorySeparatorChar); + + return new FileInfo(path); + } + + private static string FromFileInfo(FileSystemInfo? basePath, FileSystemInfo file, char separator) + { + var path = file.FullName; + path = basePath != null + ? path + .Replace(basePath?.FullName ?? string.Empty, string.Empty)[1..] + : path; + + path = separator != '\\' && Path.DirectorySeparatorChar == '\\' && Path.GetPathRoot(path).Length - 1 > 0 + ? path[(Path.GetPathRoot(path).Length - 1)..] + : path; + path = path.Replace(Path.DirectorySeparatorChar, separator); + + return path; + } + } +} diff --git a/tests/Configuration.PersistenceTests/ConverterTests/FileInfoToStringConverter.cs b/tests/Configuration.PersistenceTests/ConverterTests/FileInfoToStringConverter.cs new file mode 100644 index 0000000..3dac06a --- /dev/null +++ b/tests/Configuration.PersistenceTests/ConverterTests/FileInfoToStringConverter.cs @@ -0,0 +1,75 @@ +namespace Kritikos.Configuration.PersistenceTests.ConverterTests +{ + using System.IO; + + using FluentAssertions; + + using Microsoft.EntityFrameworkCore.Storage.ValueConversion; + + using Xunit; + + public class FileInfoToStringConverter + { + private const string WindowsBase = @"C:\Windows\System32"; + private const string WindowsRelative = @"drivers\etc\hosts"; + + private const string WindowsPath = @"C:\Windows\System32\drivers\etc\hosts"; + + private const string LinuxBase = @"/srv/http"; + private const string LinuxRelative = @"root/index.html"; + private const string LinuxPath = @"/srv/http/root/index.html"; + + private static readonly ConverterMappingHints MappingHints = new(unicode: true); + + [Fact] + public void Relative_path_windows() + { + var converter = + new Persistence.Converters.FileInfoToStringConverter('\\', new DirectoryInfo(WindowsBase), MappingHints); + + var file = converter.ConvertFromProvider(WindowsRelative) as FileInfo; + var foo = converter.ConvertToProvider(file) as string; + + file.FullName.Should().Be(WindowsPath); + foo.Should().Be(WindowsRelative); + } + + [Fact] + public void Absolute_path_windows() + { + var converter = + new Persistence.Converters.FileInfoToStringConverter('\\', mappingHints: MappingHints); + + var file = converter.ConvertFromProvider(WindowsPath) as FileInfo; + var foo = converter.ConvertToProvider(file) as string; + + file.FullName.Should().Be(WindowsPath); + foo.Should().Be(WindowsPath); + } + + [Fact] + public void Relative_path_linux() + { + var converter = + new Persistence.Converters.FileInfoToStringConverter('/', new DirectoryInfo(LinuxBase), + mappingHints: MappingHints); + + var file = converter.ConvertFromProvider(LinuxRelative) as FileInfo; + var foo = converter.ConvertToProvider(file) as string; + + foo.Should().Be(LinuxRelative); + } + + [Fact] + public void Absolute_path_linux() + { + var converter = + new Persistence.Converters.FileInfoToStringConverter('/', mappingHints: MappingHints); + + var file = converter.ConvertFromProvider(LinuxPath) as FileInfo; + var foo = converter.ConvertToProvider(file) as string; + + foo.Should().Be(LinuxPath); + } + } +}