Flow.Launcher/Flow.Launcher.Infrastructure/Storage/JsonStorage.cs

129 lines
3.5 KiB
C#
Raw Normal View History

2023-01-07 19:11:43 +00:00
#nullable enable
using System;
2017-02-12 20:03:32 +00:00
using System.Globalization;
using System.IO;
using System.Text.Json;
2020-04-21 09:12:17 +00:00
using Flow.Launcher.Infrastructure.Logger;
2020-04-21 09:12:17 +00:00
namespace Flow.Launcher.Infrastructure.Storage
{
/// <summary>
/// Serialize object using json format.
/// </summary>
2021-05-11 19:10:03 +00:00
public class JsonStorage<T> where T : new()
{
2023-01-07 19:11:43 +00:00
protected T? Data;
// need a new directory name
public const string DirectoryName = "Settings";
public const string FileSuffix = ".json";
2023-01-07 19:11:43 +00:00
protected string FilePath { get; init; } = null!;
2023-01-07 19:11:43 +00:00
private string TempFilePath => $"{FilePath}.tmp";
2023-01-07 19:11:43 +00:00
private string BackupFilePath => $"{FilePath}.bak";
2023-01-07 19:11:43 +00:00
protected string DirectoryPath { get; init; } = null!;
2017-02-06 22:04:52 +00:00
public T Load()
{
2023-01-07 19:11:43 +00:00
string? serialized = null;
if (File.Exists(FilePath))
{
2023-01-07 19:11:43 +00:00
serialized = File.ReadAllText(FilePath);
}
if (!string.IsNullOrEmpty(serialized))
{
try
{
Data = JsonSerializer.Deserialize<T>(serialized) ?? TryLoadBackup() ?? LoadDefault();
}
2023-01-07 19:11:43 +00:00
catch (JsonException)
{
2023-01-07 19:11:43 +00:00
Data = TryLoadBackup() ?? LoadDefault();
}
}
else
{
2023-01-07 19:11:43 +00:00
Data = TryLoadBackup() ?? LoadDefault();
}
2023-01-07 19:11:43 +00:00
return Data.NonNull();
}
2023-01-07 19:11:43 +00:00
private T LoadDefault()
{
2023-01-07 19:11:43 +00:00
if (File.Exists(FilePath))
{
2023-01-07 19:11:43 +00:00
BackupOriginFile();
}
2017-02-13 09:38:48 +00:00
2023-01-07 19:11:43 +00:00
return new T();
}
2023-01-07 19:11:43 +00:00
private T? TryLoadBackup()
{
2023-01-07 19:11:43 +00:00
if (!File.Exists(BackupFilePath))
return default;
try
{
2023-01-07 19:11:43 +00:00
var data = JsonSerializer.Deserialize<T>(File.ReadAllText(BackupFilePath));
2023-01-07 19:11:43 +00:00
if (data != null)
{
2023-01-22 22:17:09 +00:00
Log.Info($"|JsonStorage.Load|Failed to load settings.json, {BackupFilePath} restored successfully");
2023-01-27 15:38:39 +00:00
if(File.Exists(FilePath))
File.Replace(BackupFilePath, FilePath, null);
else
File.Move(BackupFilePath, FilePath);
2023-01-07 19:11:43 +00:00
return data;
}
2023-01-07 19:11:43 +00:00
return default;
}
catch (JsonException)
{
return default;
}
}
private void BackupOriginFile()
{
var timestamp = DateTime.Now.ToString("yyyy-MM-dd-HH-mm-ss-fffffff", CultureInfo.CurrentUICulture);
var directory = Path.GetDirectoryName(FilePath).NonNull();
var originName = Path.GetFileNameWithoutExtension(FilePath);
var backupName = $"{originName}-{timestamp}{FileSuffix}";
var backupPath = Path.Combine(directory, backupName);
File.Copy(FilePath, backupPath, true);
// todo give user notification for the backup process
}
public void Save()
{
string serialized = JsonSerializer.Serialize(Data,
new JsonSerializerOptions
{
WriteIndented = true
});
2023-01-07 19:11:43 +00:00
File.WriteAllText(TempFilePath, serialized);
if (!File.Exists(FilePath))
{
File.Move(TempFilePath, FilePath);
}
else
{
File.Replace(TempFilePath, FilePath, BackupFilePath);
}
}
}
}