mirror of
https://github.com/tribufu/tribufu-dotnet
synced 2025-06-15 01:44:19 +00:00
Add shared packages
This commit is contained in:
@ -5,9 +5,18 @@
|
||||
<ItemGroup>
|
||||
<PackageVersion Include="dotenv.net" Version="3.2.0" />
|
||||
<PackageVersion Include="JsonSubTypes" Version="2.0.1" />
|
||||
<PackageVersion Include="Microsoft.EntityFrameworkCore" Version="8.0.16" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Binder" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.EnvironmentVariables" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Ini" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration.Json" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.Configuration" Version="8.0.0" />
|
||||
<PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="8.0.1" />
|
||||
<PackageVersion Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageVersion Include="Polly" Version="8.1.0" />
|
||||
<PackageVersion Include="RestSharp" Version="112.1.0" />
|
||||
<PackageVersion Include="System.ComponentModel.Annotations" Version="5.0.0" />
|
||||
<PackageVersion Include="Tomlyn.Extensions.Configuration" Version="1.0.6" />
|
||||
<PackageVersion Include="Tomlyn" Version="0.17.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
84
Tribufu.sln
84
Tribufu.sln
@ -7,6 +7,18 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tribufu.Generated", "src\Tr
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tribufu.Example", "src\Tribufu.Example\Tribufu.Example.csproj", "{D6392A29-E2DC-4050-B4C1-B279DD2D226D}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tribufu.Logging", "src\Tribufu.Logging\Tribufu.Logging.csproj", "{CFD80847-9B98-4991-BADF-8714E7D8D81C}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tribufu.Configuration", "src\Tribufu.Configuration\Tribufu.Configuration.csproj", "{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tribufu.Runtime", "src\Tribufu.Runtime\Tribufu.Runtime.csproj", "{26EEB407-733C-4383-9211-B083CD5F593B}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tribufu.Database", "src\Tribufu.Database\Tribufu.Database.csproj", "{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tribufu.Serialization", "src\Tribufu.Serialization\Tribufu.Serialization.csproj", "{D6DAE078-2F80-49DD-97A3-B1223FE04F91}"
|
||||
EndProject
|
||||
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Tribufu.ComponentModel", "src\Tribufu.ComponentModel\Tribufu.ComponentModel.csproj", "{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
@ -53,6 +65,78 @@ Global
|
||||
{D6392A29-E2DC-4050-B4C1-B279DD2D226D}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D6392A29-E2DC-4050-B4C1-B279DD2D226D}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D6392A29-E2DC-4050-B4C1-B279DD2D226D}.Release|x86.Build.0 = Release|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Release|x64.Build.0 = Release|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{CFD80847-9B98-4991-BADF-8714E7D8D81C}.Release|x86.Build.0 = Release|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Release|x64.Build.0 = Release|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{C0A841C8-9FC5-4AC0-B9AD-6BBFCEDCBE5F}.Release|x86.Build.0 = Release|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Release|x64.Build.0 = Release|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{26EEB407-733C-4383-9211-B083CD5F593B}.Release|x86.Build.0 = Release|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Release|x64.Build.0 = Release|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{E7F9A76F-C087-410B-B4B5-A928A6CDC2BA}.Release|x86.Build.0 = Release|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Release|x64.Build.0 = Release|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{D6DAE078-2F80-49DD-97A3-B1223FE04F91}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Debug|x64.ActiveCfg = Debug|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Debug|x64.Build.0 = Debug|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Release|x64.ActiveCfg = Release|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Release|x64.Build.0 = Release|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7CB04FFD-8F4B-4B40-BB4B-2BAA19D783E1}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
5
scripts/package.ps1
Normal file
5
scripts/package.ps1
Normal file
@ -0,0 +1,5 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
dotnet clean
|
||||
dotnet build -c Release
|
||||
dotnet pack
|
@ -1,3 +0,0 @@
|
||||
#!/usr/bin/env sh
|
||||
|
||||
dotnet pack
|
30
src/Tribufu.ComponentModel/EnumMemberConverter.cs
Normal file
30
src/Tribufu.ComponentModel/EnumMemberConverter.cs
Normal file
@ -0,0 +1,30 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using System;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Runtime.Serialization;
|
||||
|
||||
namespace Tribufu.ComponentModel
|
||||
{
|
||||
public class EnumMemberConverter<T> : EnumConverter
|
||||
{
|
||||
public EnumMemberConverter(Type type) : base(type) { }
|
||||
|
||||
public override object ConvertFrom(ITypeDescriptorContext context, CultureInfo culture, object value)
|
||||
{
|
||||
var type = typeof(T);
|
||||
|
||||
foreach (var field in type.GetFields())
|
||||
{
|
||||
if (Attribute.GetCustomAttribute(field, typeof(EnumMemberAttribute)) is EnumMemberAttribute attribute && value is string enumValue && attribute.Value == enumValue)
|
||||
{
|
||||
return field.GetValue(null);
|
||||
}
|
||||
}
|
||||
|
||||
return base.ConvertFrom(context, culture, value);
|
||||
}
|
||||
}
|
||||
}
|
1
src/Tribufu.ComponentModel/README.md
Normal file
1
src/Tribufu.ComponentModel/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Tribufu
|
16
src/Tribufu.ComponentModel/Tribufu.ComponentModel.csproj
Normal file
16
src/Tribufu.ComponentModel/Tribufu.ComponentModel.csproj
Normal file
@ -0,0 +1,16 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<PackageId>Tribufu.ComponentModel</PackageId>
|
||||
<Description>Tribufu ComponentModel Extensions</Description>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFrameworks>netstandard2.0;net45;net5.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
</Project>
|
53
src/Tribufu.Configuration/ConfigurationManager.cs
Normal file
53
src/Tribufu.Configuration/ConfigurationManager.cs
Normal file
@ -0,0 +1,53 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System.IO;
|
||||
using Tomlyn.Extensions.Configuration;
|
||||
using Tribufu.Logging;
|
||||
using Tribufu.Runtime;
|
||||
|
||||
namespace Tribufu.Configuration
|
||||
{
|
||||
public static class ConfigurationManager
|
||||
{
|
||||
public static IConfiguration Configuration { get; private set; }
|
||||
|
||||
public static IConfiguration Load(string[] fileNames)
|
||||
{
|
||||
var configDirectory = ApplicationContext.GetConfigDirectory();
|
||||
var configurationBuilder = new ConfigurationBuilder();
|
||||
configurationBuilder.AddEnvironmentVariables();
|
||||
|
||||
foreach (var fileName in fileNames)
|
||||
{
|
||||
var fullPath = Path.Combine(configDirectory, fileName);
|
||||
if (!File.Exists(fullPath))
|
||||
{
|
||||
Logger.Debug($"Config file '{fullPath}' not found, skipping.");
|
||||
continue;
|
||||
}
|
||||
|
||||
var ext = Path.GetExtension(fullPath).ToLowerInvariant();
|
||||
switch (ext)
|
||||
{
|
||||
case ".ini":
|
||||
configurationBuilder.AddIniFile(fullPath, true, false);
|
||||
break;
|
||||
case ".json":
|
||||
configurationBuilder.AddJsonFile(fullPath, true, false);
|
||||
break;
|
||||
case ".toml":
|
||||
configurationBuilder.AddTomlFile(fullPath, true, false);
|
||||
break;
|
||||
default:
|
||||
Logger.Warn($"Unsupported config file extension: {ext}");
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Configuration = configurationBuilder.Build();
|
||||
return Configuration;
|
||||
}
|
||||
}
|
||||
}
|
1
src/Tribufu.Configuration/README.md
Normal file
1
src/Tribufu.Configuration/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Tribufu
|
30
src/Tribufu.Configuration/Tribufu.Configuration.csproj
Normal file
30
src/Tribufu.Configuration/Tribufu.Configuration.csproj
Normal file
@ -0,0 +1,30 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<PackageId>Tribufu.Configuration</PackageId>
|
||||
<Description>Tribufu Configuration Extensions</Description>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFrameworks>netstandard2.0;net6.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Binder" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.EnvironmentVariables" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Ini" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration.Json" />
|
||||
<PackageReference Include="Microsoft.Extensions.Configuration" />
|
||||
<PackageReference Include="Newtonsoft.Json" />
|
||||
<PackageReference Include="Tomlyn.Extensions.Configuration" />
|
||||
<PackageReference Include="Tomlyn" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tribufu.Logging\Tribufu.Logging.csproj" />
|
||||
<ProjectReference Include="..\Tribufu.Runtime\Tribufu.Runtime.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
55
src/Tribufu.Database/DatabaseConfiguration.cs
Normal file
55
src/Tribufu.Database/DatabaseConfiguration.cs
Normal file
@ -0,0 +1,55 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using Microsoft.Extensions.Configuration;
|
||||
using System;
|
||||
|
||||
namespace Tribufu.Database
|
||||
{
|
||||
public class DatabaseConfiguration
|
||||
{
|
||||
public DatabaseDriver Driver { get; set; }
|
||||
|
||||
public string? Version { get; set; }
|
||||
|
||||
public string? Host { get; set; }
|
||||
|
||||
public string? Port { get; set; }
|
||||
|
||||
public string? User { get; set; }
|
||||
|
||||
public string? Password { get; set; }
|
||||
|
||||
public string? Schema { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Loads the <see cref="DatabaseConfiguration"/> from the "database" section or from root-level keys prefixed with "database_".
|
||||
/// </summary>
|
||||
/// <param name="configuration">The configuration source.</param>
|
||||
/// <returns>The populated <see cref="DatabaseConfiguration"/> instance.</returns>
|
||||
public static DatabaseConfiguration Load(IConfiguration configuration)
|
||||
{
|
||||
var section = configuration.GetSection("database");
|
||||
var useRootFallback = !section.Exists();
|
||||
|
||||
string? GetConfig(string key) => useRootFallback ? configuration[$"database_{key}"] : section[key];
|
||||
|
||||
var driverString = GetConfig("driver") ?? throw new Exception("Missing database driver");
|
||||
if (!Enum.TryParse<DatabaseDriver>(driverString, true, out var driver))
|
||||
{
|
||||
throw new Exception($"Unsupported database driver: {driverString}");
|
||||
}
|
||||
|
||||
return new DatabaseConfiguration
|
||||
{
|
||||
Driver = driver,
|
||||
Version = GetConfig("version"),
|
||||
Host = GetConfig("host"),
|
||||
Port = GetConfig("port"),
|
||||
User = GetConfig("user"),
|
||||
Password = GetConfig("password"),
|
||||
Schema = GetConfig("schema")
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
12
src/Tribufu.Database/DatabaseConstants.cs
Normal file
12
src/Tribufu.Database/DatabaseConstants.cs
Normal file
@ -0,0 +1,12 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
namespace Tribufu.Database
|
||||
{
|
||||
public static class DatabaseConstants
|
||||
{
|
||||
public const uint DEFAULT_PAGINATION = 20;
|
||||
|
||||
public const uint MAX_PAGINATION = 100;
|
||||
}
|
||||
}
|
22
src/Tribufu.Database/DatabaseDriver.cs
Normal file
22
src/Tribufu.Database/DatabaseDriver.cs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
namespace Tribufu.Database
|
||||
{
|
||||
public enum DatabaseDriver : byte
|
||||
{
|
||||
MySql = 0,
|
||||
|
||||
Postgres = 1,
|
||||
|
||||
SqlServer = 2,
|
||||
|
||||
Oracle = 3,
|
||||
|
||||
Firebird = 4,
|
||||
|
||||
Sqlite = 5,
|
||||
|
||||
MongoDb = 6,
|
||||
}
|
||||
}
|
1
src/Tribufu.Database/README.md
Normal file
1
src/Tribufu.Database/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Tribufu
|
39
src/Tribufu.Database/Repositories/IRepository.cs
Normal file
39
src/Tribufu.Database/Repositories/IRepository.cs
Normal file
@ -0,0 +1,39 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Tribufu.Database.Repositories
|
||||
{
|
||||
public interface IRepository<T, K> where T : class
|
||||
{
|
||||
IList<T> GetAll();
|
||||
|
||||
Task<IList<T>> GetAllAsync();
|
||||
|
||||
IList<T> GetPage(uint page, uint limit);
|
||||
|
||||
Task<IList<T>> GetPageAsync(uint page, uint limit);
|
||||
|
||||
T? GetOne(K key);
|
||||
|
||||
Task<T?> GetOneAsync(K key);
|
||||
|
||||
T? Create(T entity);
|
||||
|
||||
Task<T?> CreateAsync(T entity);
|
||||
|
||||
T? Update(T entity);
|
||||
|
||||
Task<T?> UpdateAsync(T entity);
|
||||
|
||||
void Delete(K key);
|
||||
|
||||
Task DeleteAsync(K key);
|
||||
|
||||
void Delete(T entity);
|
||||
|
||||
Task DeleteAsync(T entity);
|
||||
}
|
||||
}
|
113
src/Tribufu.Database/Repositories/Repository.cs
Normal file
113
src/Tribufu.Database/Repositories/Repository.cs
Normal file
@ -0,0 +1,113 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using Microsoft.EntityFrameworkCore;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace Tribufu.Database.Repositories
|
||||
{
|
||||
public class Repository<C, T, K> : IRepository<T, K> where C : DbContext where T : class
|
||||
{
|
||||
protected readonly C _context;
|
||||
|
||||
protected readonly DbSet<T> _dbSet;
|
||||
|
||||
public Repository(C context)
|
||||
{
|
||||
_context = context ?? throw new ArgumentNullException(nameof(context));
|
||||
_dbSet = context.Set<T>();
|
||||
}
|
||||
|
||||
public virtual IList<T> GetAll()
|
||||
{
|
||||
return [.. _dbSet];
|
||||
}
|
||||
|
||||
public virtual async Task<IList<T>> GetAllAsync()
|
||||
{
|
||||
return await _dbSet.ToListAsync();
|
||||
}
|
||||
|
||||
public virtual IList<T> GetPage(uint page, uint limit)
|
||||
{
|
||||
return _dbSet.Skip((int)((page < 1 ? 0 : page - 1) * limit)).Take((int)limit).ToList();
|
||||
}
|
||||
|
||||
public virtual async Task<IList<T>> GetPageAsync(uint page, uint limit)
|
||||
{
|
||||
return await _dbSet.Skip((int)((page < 1 ? 0 : page - 1) * limit)).Take((int)limit).ToListAsync();
|
||||
}
|
||||
|
||||
public virtual T? GetOne(K key)
|
||||
{
|
||||
return _dbSet.Find(key);
|
||||
}
|
||||
|
||||
public virtual async Task<T?> GetOneAsync(K key)
|
||||
{
|
||||
return await _dbSet.FindAsync(key);
|
||||
}
|
||||
|
||||
public virtual T? Create(T entity)
|
||||
{
|
||||
_dbSet.Add(entity);
|
||||
|
||||
var result = _context.SaveChanges();
|
||||
return result > 0 ? entity : null;
|
||||
}
|
||||
|
||||
public virtual async Task<T?> CreateAsync(T entity)
|
||||
{
|
||||
await _dbSet.AddAsync(entity);
|
||||
var result = await _context.SaveChangesAsync();
|
||||
return result > 0 ? entity : null;
|
||||
}
|
||||
|
||||
public virtual T? Update(T entity)
|
||||
{
|
||||
_dbSet.Update(entity);
|
||||
var result = _context.SaveChanges();
|
||||
return result > 0 ? entity : null;
|
||||
}
|
||||
|
||||
public virtual async Task<T?> UpdateAsync(T entity)
|
||||
{
|
||||
_dbSet.Update(entity);
|
||||
var result = await _context.SaveChangesAsync();
|
||||
return result > 0 ? entity : null;
|
||||
}
|
||||
|
||||
public virtual void Delete(K key)
|
||||
{
|
||||
var entity = _dbSet.Find(key);
|
||||
if (entity != null)
|
||||
{
|
||||
Delete(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual async Task DeleteAsync(K key)
|
||||
{
|
||||
var entity = await _dbSet.FindAsync(key);
|
||||
if (entity != null)
|
||||
{
|
||||
await DeleteAsync(entity);
|
||||
}
|
||||
}
|
||||
|
||||
public virtual void Delete(T entity)
|
||||
{
|
||||
_dbSet.Remove(entity);
|
||||
_context.SaveChanges();
|
||||
}
|
||||
|
||||
public virtual async Task DeleteAsync(T entity)
|
||||
{
|
||||
_dbSet.Remove(entity);
|
||||
await _context.SaveChangesAsync();
|
||||
}
|
||||
}
|
||||
}
|
25
src/Tribufu.Database/Tribufu.Database.csproj
Normal file
25
src/Tribufu.Database/Tribufu.Database.csproj
Normal file
@ -0,0 +1,25 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<PackageId>Tribufu.Database</PackageId>
|
||||
<Description>Tribufu Database Extensions</Description>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<Nullable>enable</Nullable>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFrameworks>net8.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tribufu.Configuration\Tribufu.Configuration.csproj" />
|
||||
<ProjectReference Include="..\Tribufu.Logging\Tribufu.Logging.csproj" />
|
||||
<ProjectReference Include="..\Tribufu.Runtime\Tribufu.Runtime.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
@ -1,8 +1,9 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: UNLICENSED
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using dotenv.net;
|
||||
using Tribufu.Generated.Client;
|
||||
using Tribufu.Logging;
|
||||
|
||||
namespace Tribufu.Test
|
||||
{
|
||||
@ -10,21 +11,23 @@ namespace Tribufu.Test
|
||||
{
|
||||
public static async Task Main(string[] args)
|
||||
{
|
||||
Logger.Initialize(LogLevel.All);
|
||||
|
||||
DotEnv.Load(new DotEnvOptions(ignoreExceptions: true, envFilePaths: [".env", "../../.env"]));
|
||||
|
||||
var apiKey = Environment.GetEnvironmentVariable("TRIBUFU_API_KEY");
|
||||
var tribufu = new TribufuApi(apiKey ?? "");
|
||||
|
||||
Console.WriteLine(TribufuApi.GetVersion());
|
||||
Logger.Debug(TribufuApi.GetVersion());
|
||||
|
||||
try
|
||||
{
|
||||
var result = await tribufu.GetUserInfoAsync();
|
||||
Console.WriteLine(result);
|
||||
Logger.Debug(result.ToString());
|
||||
}
|
||||
catch (ApiException e)
|
||||
{
|
||||
Console.WriteLine(e.Message);
|
||||
Logger.Debug(e.Message);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -9,6 +9,7 @@
|
||||
<PackageReference Include="dotenv.net" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tribufu.Logging\Tribufu.Logging.csproj" />
|
||||
<ProjectReference Include="..\Tribufu\Tribufu.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
22
src/Tribufu.Logging/LogLevel.cs
Normal file
22
src/Tribufu.Logging/LogLevel.cs
Normal file
@ -0,0 +1,22 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
namespace Tribufu.Logging
|
||||
{
|
||||
public enum LogLevel : byte
|
||||
{
|
||||
Off = 0,
|
||||
|
||||
Trace = 1,
|
||||
|
||||
Debug = 2,
|
||||
|
||||
Info = 3,
|
||||
|
||||
Warn = 4,
|
||||
|
||||
Error = 5,
|
||||
|
||||
All = 6,
|
||||
}
|
||||
}
|
59
src/Tribufu.Logging/Logger.cs
Normal file
59
src/Tribufu.Logging/Logger.cs
Normal file
@ -0,0 +1,59 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using System;
|
||||
|
||||
namespace Tribufu.Logging
|
||||
{
|
||||
public static class Logger
|
||||
{
|
||||
private static LogLevel _level = LogLevel.Off;
|
||||
|
||||
public static void Initialize(LogLevel level = LogLevel.Off)
|
||||
{
|
||||
_level = level;
|
||||
}
|
||||
|
||||
public static void Info(string message)
|
||||
{
|
||||
Log(LogLevel.Info, message, ConsoleColor.Green);
|
||||
}
|
||||
|
||||
public static void Warn(string message)
|
||||
{
|
||||
Log(LogLevel.Warn, message, ConsoleColor.Yellow);
|
||||
}
|
||||
|
||||
public static void Error(string message)
|
||||
{
|
||||
Log(LogLevel.Error, message, ConsoleColor.Red);
|
||||
}
|
||||
|
||||
public static void Debug(string message)
|
||||
{
|
||||
Log(LogLevel.Debug, message, ConsoleColor.White);
|
||||
}
|
||||
|
||||
public static void Trace(string message)
|
||||
{
|
||||
Log(LogLevel.Trace, message, ConsoleColor.Gray);
|
||||
}
|
||||
|
||||
private static void Log(LogLevel level, string message, ConsoleColor color)
|
||||
{
|
||||
if (_level == LogLevel.Off)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (_level == LogLevel.All || level >= _level)
|
||||
{
|
||||
var defaultColor = Console.ForegroundColor;
|
||||
Console.ForegroundColor = color;
|
||||
var timestamp = DateTime.Now.ToString("yyyy-MM-ddTHH:mm:ss");
|
||||
Console.WriteLine($"[{timestamp}] [{level.ToString().ToUpper()}]: {message}");
|
||||
Console.ForegroundColor = defaultColor;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1
src/Tribufu.Logging/README.md
Normal file
1
src/Tribufu.Logging/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Tribufu
|
18
src/Tribufu.Logging/Tribufu.Logging.csproj
Normal file
18
src/Tribufu.Logging/Tribufu.Logging.csproj
Normal file
@ -0,0 +1,18 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<PackageId>Tribufu.Logging</PackageId>
|
||||
<Description>Tribufu Logging Extensions</Description>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFrameworks>netstandard2.0;net45;net5.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
</ItemGroup>
|
||||
</Project>
|
183
src/Tribufu.Runtime/ApplicationContext.cs
Normal file
183
src/Tribufu.Runtime/ApplicationContext.cs
Normal file
@ -0,0 +1,183 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Runtime.InteropServices;
|
||||
using Tribufu.Logging;
|
||||
|
||||
namespace Tribufu.Runtime
|
||||
{
|
||||
/// <summary>
|
||||
/// Provides standardized access to important application directories, such as config, saved data, logs, and platform-specific binaries.
|
||||
/// This is especially useful for abstracting file path logic across environments (development, production, etc).
|
||||
/// </summary>
|
||||
public static class ApplicationContext
|
||||
{
|
||||
/// <summary>
|
||||
/// Gets the root base directory of the application.
|
||||
/// </summary>
|
||||
/// <remarks>
|
||||
/// - In development, this resolves to the root of the repository (five levels above bin/Debug or bin/Release).
|
||||
/// - In production, it resolves to two levels above the binary location.
|
||||
/// - It uses case-insensitive checks and runtime heuristics to improve accuracy.
|
||||
/// </remarks>
|
||||
/// <returns>The absolute path to the base directory.</returns>
|
||||
public static string GetBaseDirectory()
|
||||
{
|
||||
try
|
||||
{
|
||||
string baseDirectory;
|
||||
string defaultBaseDirectory = AppContext.BaseDirectory;
|
||||
|
||||
bool isDevelopment = defaultBaseDirectory.ToLowerInvariant().Contains("debug");
|
||||
|
||||
if (isDevelopment)
|
||||
{
|
||||
// Go 5 levels up to simulate project root
|
||||
baseDirectory = Path.Combine(defaultBaseDirectory, "..", "..", "..", "..", "..");
|
||||
}
|
||||
else
|
||||
{
|
||||
baseDirectory = Path.Combine(defaultBaseDirectory, "..", "..");
|
||||
}
|
||||
|
||||
return Path.GetFullPath(baseDirectory);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
Logger.Warn($"(ApplicationContext) Failed to resolve base directory: {ex.Message}");
|
||||
return AppContext.BaseDirectory;
|
||||
}
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the platform-specific binary directory.
|
||||
/// </summary>
|
||||
/// <returns>
|
||||
/// The absolute path to <c>bin/<runtime-identifier></c> if available,
|
||||
/// otherwise falls back to <c>bin/dotnet</c>.
|
||||
/// </returns>
|
||||
public static string GetBinDirectory()
|
||||
{
|
||||
var binDirectory = Path.Combine(GetBaseDirectory(), "bin");
|
||||
|
||||
#if NETSTANDARD
|
||||
var runtimeIdentifier = GetRuntimeIdentifierLegacy();
|
||||
|
||||
if (!string.IsNullOrEmpty(runtimeIdentifier))
|
||||
{
|
||||
binDirectory = Path.Combine(binDirectory, runtimeIdentifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
binDirectory = Path.Combine(binDirectory, "dotnet");
|
||||
}
|
||||
#else
|
||||
if (!string.IsNullOrEmpty(RuntimeInformation.RuntimeIdentifier))
|
||||
{
|
||||
binDirectory = Path.Combine(binDirectory, RuntimeInformation.RuntimeIdentifier);
|
||||
}
|
||||
else
|
||||
{
|
||||
binDirectory = Path.Combine(binDirectory, "dotnet");
|
||||
}
|
||||
#endif
|
||||
|
||||
return binDirectory;
|
||||
}
|
||||
|
||||
private static string GetRuntimeIdentifierLegacy()
|
||||
{
|
||||
string osPart;
|
||||
PlatformID platform = Environment.OSVersion.Platform;
|
||||
|
||||
switch (platform)
|
||||
{
|
||||
case PlatformID.Win32NT:
|
||||
osPart = "win";
|
||||
break;
|
||||
case PlatformID.Unix:
|
||||
if (IsMacOS())
|
||||
osPart = "osx";
|
||||
else
|
||||
osPart = "linux";
|
||||
break;
|
||||
case PlatformID.MacOSX:
|
||||
osPart = "osx";
|
||||
break;
|
||||
default:
|
||||
osPart = "unknown";
|
||||
break;
|
||||
}
|
||||
|
||||
var archPart = Environment.Is64BitProcess ? "x64" : "x86";
|
||||
if (osPart == "unknown")
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return $"{osPart}-{archPart}";
|
||||
}
|
||||
|
||||
private static bool IsMacOS()
|
||||
{
|
||||
if (Environment.OSVersion.Platform == PlatformID.Unix)
|
||||
{
|
||||
Version version = Environment.OSVersion.Version;
|
||||
|
||||
if (version.Major >= 19)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the configuration directory.
|
||||
/// </summary>
|
||||
/// <returns>The absolute path to the <c>config</c> directory.</returns>
|
||||
public static string GetConfigDirectory()
|
||||
{
|
||||
return Path.Combine(GetBaseDirectory(), "config");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the assets directory.
|
||||
/// </summary>
|
||||
/// <returns>The absolute path to the <c>assets</c> directory.</returns>
|
||||
public static string GetAssetsDirectory()
|
||||
{
|
||||
return Path.Combine(GetBaseDirectory(), "assets");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the saved data directory.
|
||||
/// </summary>
|
||||
/// <returns>The absolute path to the <c>saved</c> directory.</returns>
|
||||
public static string GetSavedDirectory()
|
||||
{
|
||||
return Path.Combine(GetBaseDirectory(), "saved");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the cache directory inside <c>saved</c>.
|
||||
/// </summary>
|
||||
/// <returns>The absolute path to the <c>saved/cache</c> directory.</returns>
|
||||
public static string GetCacheDirectory()
|
||||
{
|
||||
return Path.Combine(GetSavedDirectory(), "cache");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Gets the path to the logs directory inside <c>saved</c>.
|
||||
/// </summary>
|
||||
/// <returns>The absolute path to the <c>saved/logs</c> directory.</returns>
|
||||
public static string GetLogsDirectory()
|
||||
{
|
||||
return Path.Combine(GetSavedDirectory(), "logs");
|
||||
}
|
||||
}
|
||||
}
|
1
src/Tribufu.Runtime/README.md
Normal file
1
src/Tribufu.Runtime/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Tribufu
|
19
src/Tribufu.Runtime/Tribufu.Runtime.csproj
Normal file
19
src/Tribufu.Runtime/Tribufu.Runtime.csproj
Normal file
@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<PackageId>Tribufu.Runtime</PackageId>
|
||||
<Description>Tribufu Runtime Extensions</Description>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFrameworks>netstandard2.0;net5.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ProjectReference Include="..\Tribufu.Logging\Tribufu.Logging.csproj" />
|
||||
</ItemGroup>
|
||||
</Project>
|
46
src/Tribufu.Serialization/DecimalNullableStringConverter.cs
Normal file
46
src/Tribufu.Serialization/DecimalNullableStringConverter.cs
Normal file
@ -0,0 +1,46 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Tribufu.Serialization
|
||||
{
|
||||
public class DecimalNullableStringConverter : JsonConverter<decimal?>
|
||||
{
|
||||
public override decimal? ReadJson(JsonReader reader, Type objectType, decimal? existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (reader.TokenType == JsonToken.String || reader.TokenType == JsonToken.Integer)
|
||||
{
|
||||
string value = reader.Value?.ToString();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return decimal.Parse(value);
|
||||
}
|
||||
|
||||
throw new JsonSerializationException($"Unexpected token {reader.TokenType} when parsing decimal?.");
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, decimal? value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.HasValue)
|
||||
{
|
||||
writer.WriteValue(value.Value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
32
src/Tribufu.Serialization/DecimalStringConverter.cs
Normal file
32
src/Tribufu.Serialization/DecimalStringConverter.cs
Normal file
@ -0,0 +1,32 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
using System.Globalization;
|
||||
|
||||
namespace Tribufu.Serialization
|
||||
{
|
||||
public class DecimalStringConverter : JsonConverter<decimal>
|
||||
{
|
||||
public override decimal ReadJson(JsonReader reader, Type objectType, decimal existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.String && decimal.TryParse(reader.Value?.ToString(), out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (reader.TokenType == JsonToken.Integer)
|
||||
{
|
||||
return Convert.ToUInt64(reader.Value);
|
||||
}
|
||||
|
||||
throw new JsonSerializationException($"Unexpected token {reader.TokenType} when parsing decimal.");
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, decimal value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteValue(value.ToString(CultureInfo.InvariantCulture));
|
||||
}
|
||||
}
|
||||
}
|
1
src/Tribufu.Serialization/README.md
Normal file
1
src/Tribufu.Serialization/README.md
Normal file
@ -0,0 +1 @@
|
||||
# Tribufu
|
19
src/Tribufu.Serialization/Tribufu.Serialization.csproj
Normal file
19
src/Tribufu.Serialization/Tribufu.Serialization.csproj
Normal file
@ -0,0 +1,19 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<PackageId>Tribufu.Serialization</PackageId>
|
||||
<Description>Tribufu Serialization Extensions</Description>
|
||||
<PackageReadmeFile>README.md</PackageReadmeFile>
|
||||
</PropertyGroup>
|
||||
<PropertyGroup>
|
||||
<AppDesignerFolder>Properties</AppDesignerFolder>
|
||||
<GeneratePackageOnBuild>true</GeneratePackageOnBuild>
|
||||
<OutputType>Library</OutputType>
|
||||
<TargetFrameworks>netstandard2.0;net45;net5.0</TargetFrameworks>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<None Include="README.md" Pack="true" PackagePath="\" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Newtonsoft.Json" />
|
||||
</ItemGroup>
|
||||
</Project>
|
45
src/Tribufu.Serialization/ULongNullableStringConverter.cs
Normal file
45
src/Tribufu.Serialization/ULongNullableStringConverter.cs
Normal file
@ -0,0 +1,45 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Tribufu.Serialization
|
||||
{
|
||||
public class ULongNullableStringConverter : JsonConverter<ulong?>
|
||||
{
|
||||
public override ulong? ReadJson(JsonReader reader, Type objectType, ulong? existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.Null)
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
if (reader.TokenType == JsonToken.String || reader.TokenType == JsonToken.Integer)
|
||||
{
|
||||
string value = reader.Value?.ToString();
|
||||
|
||||
if (string.IsNullOrWhiteSpace(value))
|
||||
{
|
||||
return null;
|
||||
}
|
||||
|
||||
return ulong.Parse(value);
|
||||
}
|
||||
|
||||
throw new JsonSerializationException($"Unexpected token {reader.TokenType} when parsing ulong?.");
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, ulong? value, JsonSerializer serializer)
|
||||
{
|
||||
if (value.HasValue)
|
||||
{
|
||||
writer.WriteValue(value.Value.ToString());
|
||||
}
|
||||
else
|
||||
{
|
||||
writer.WriteNull();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
31
src/Tribufu.Serialization/ULongStringConverter.cs
Normal file
31
src/Tribufu.Serialization/ULongStringConverter.cs
Normal file
@ -0,0 +1,31 @@
|
||||
// Copyright (c) Tribufu. All Rights Reserved.
|
||||
// SPDX-License-Identifier: MIT
|
||||
|
||||
using Newtonsoft.Json;
|
||||
using System;
|
||||
|
||||
namespace Tribufu.Serialization
|
||||
{
|
||||
public class ULongStringConverter : JsonConverter<ulong>
|
||||
{
|
||||
public override ulong ReadJson(JsonReader reader, Type objectType, ulong existingValue, bool hasExistingValue, JsonSerializer serializer)
|
||||
{
|
||||
if (reader.TokenType == JsonToken.String && ulong.TryParse(reader.Value?.ToString(), out var result))
|
||||
{
|
||||
return result;
|
||||
}
|
||||
|
||||
if (reader.TokenType == JsonToken.Integer)
|
||||
{
|
||||
return Convert.ToUInt64(reader.Value);
|
||||
}
|
||||
|
||||
throw new JsonSerializationException($"Unexpected token {reader.TokenType} when parsing ulong.");
|
||||
}
|
||||
|
||||
public override void WriteJson(JsonWriter writer, ulong value, JsonSerializer serializer)
|
||||
{
|
||||
writer.WriteValue(value.ToString());
|
||||
}
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user