Skip to content

Commit 37785dd

Browse files
committed
🐞 Drop STJ source generation for now
Revert this once reactiveui/ReactiveUI#4019 is merged and out in a release.
1 parent 40e274d commit 37785dd

File tree

3 files changed

+71
-13
lines changed

3 files changed

+71
-13
lines changed

YoutubeDl.Wpf/Models/Settings.cs

+13-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
using MaterialDesignThemes.Wpf;
22
using System;
33
using System.ComponentModel;
4+
using System.Text.Encodings.Web;
5+
using System.Text.Json;
46
using System.Threading;
57
using System.Threading.Tasks;
68
using YoutubeDl.Wpf.Utils;
@@ -95,14 +97,23 @@ public class Settings
9597

9698
public string[] DownloadPathHistory { get; set; } = [];
9799

100+
private static readonly JsonSerializerOptions s_jsonSerializerOptions = new()
101+
{
102+
AllowTrailingCommas = true,
103+
Encoder = JavaScriptEncoder.UnsafeRelaxedJsonEscaping,
104+
IgnoreReadOnlyProperties = true,
105+
ReadCommentHandling = JsonCommentHandling.Skip,
106+
WriteIndented = true,
107+
};
108+
98109
/// <summary>
99110
/// Loads settings from Settings.json.
100111
/// </summary>
101112
/// <param name="cancellationToken">A token that may be used to cancel the read operation.</param>
102113
/// <returns>The <see cref="Settings"/> object.</returns>
103114
public static async Task<Settings> LoadAsync(CancellationToken cancellationToken = default)
104115
{
105-
var settings = await FileHelper.LoadFromJsonFileAsync("Settings.json", SettingsJsonSerializerContext.Default.Settings, cancellationToken).ConfigureAwait(false);
116+
Settings settings = await FileHelper.LoadFromJsonFileAsync<Settings>("Settings.json", s_jsonSerializerOptions, cancellationToken).ConfigureAwait(false);
106117
settings.Update();
107118
settings.Validate();
108119
return settings;
@@ -114,7 +125,7 @@ public static async Task<Settings> LoadAsync(CancellationToken cancellationToken
114125
/// <param name="cancellationToken">A token that may be used to cancel the write operation.</param>
115126
/// <returns>A task that represents the asynchronous write operation.</returns>
116127
public Task SaveAsync(CancellationToken cancellationToken = default)
117-
=> FileHelper.SaveToJsonFileAsync("Settings.json", this, SettingsJsonSerializerContext.Default.Settings, cancellationToken);
128+
=> FileHelper.SaveToJsonFileAsync("Settings.json", this, s_jsonSerializerOptions, cancellationToken);
118129

119130
/// <summary>
120131
/// Updates settings to the latest version.

YoutubeDl.Wpf/Models/SettingsJsonSerializerContext.cs

-11
This file was deleted.

YoutubeDl.Wpf/Utils/FileHelper.cs

+58
Original file line numberDiff line numberDiff line change
@@ -53,6 +53,27 @@ static FileHelper()
5353
}
5454
}
5555

56+
/// <summary>
57+
/// Loads the specified JSON file and deserializes its content as a <typeparamref name="TValue"/>.
58+
/// </summary>
59+
/// <typeparam name="TValue">The type to deserialize the JSON value into.</typeparam>
60+
/// <param name="path">JSON file path.</param>
61+
/// <param name="jsonSerializerOptions">Deserialization options.</param>
62+
/// <param name="cancellationToken">A token that may be used to cancel the read operation.</param>
63+
/// <returns>A <typeparamref name="TValue"/>.</returns>
64+
public static async Task<TValue> LoadFromJsonFileAsync<TValue>(string path, JsonSerializerOptions? jsonSerializerOptions = null, CancellationToken cancellationToken = default) where TValue : class, new()
65+
{
66+
path = GetAbsolutePath(path);
67+
if (!File.Exists(path))
68+
return new();
69+
70+
var fileStream = new FileStream(path, FileMode.Open);
71+
await using (fileStream.ConfigureAwait(false))
72+
{
73+
return await JsonSerializer.DeserializeAsync<TValue>(fileStream, jsonSerializerOptions, cancellationToken).ConfigureAwait(false) ?? new();
74+
}
75+
}
76+
5677
/// <summary>
5778
/// Serializes the provided value as JSON and saves to the specified file.
5879
/// </summary>
@@ -89,4 +110,41 @@ public static async Task SaveToJsonFileAsync<TValue>(
89110
if (canReplace)
90111
File.Replace(newPath, path, $"{path}.old");
91112
}
113+
114+
/// <summary>
115+
/// Serializes the provided value as JSON and saves to the specified file.
116+
/// </summary>
117+
/// <typeparam name="TValue">The type of the value to serialize.</typeparam>
118+
/// <param name="path">JSON file path.</param>
119+
/// <param name="value">The value to save.</param>
120+
/// <param name="jsonSerializerOptions">Serialization options.</param>
121+
/// <param name="cancellationToken">A token that may be used to cancel the write operation.</param>
122+
/// <returns>A task that represents the asynchronous write operation.</returns>
123+
public static async Task SaveToJsonFileAsync<TValue>(
124+
string path,
125+
TValue value,
126+
JsonSerializerOptions? jsonSerializerOptions = null,
127+
CancellationToken cancellationToken = default)
128+
{
129+
path = GetAbsolutePath(path);
130+
131+
var directoryPath = Path.GetDirectoryName(path);
132+
if (string.IsNullOrEmpty(directoryPath))
133+
throw new ArgumentException("Invalid path.", nameof(path));
134+
135+
_ = Directory.CreateDirectory(directoryPath);
136+
137+
// File.Replace throws an exception when the destination file does not exist.
138+
var canReplace = File.Exists(path);
139+
var newPath = canReplace ? $"{path}.new" : path;
140+
var fileStream = new FileStream(newPath, FileMode.Create);
141+
142+
await using (fileStream.ConfigureAwait(false))
143+
{
144+
await JsonSerializer.SerializeAsync(fileStream, value, jsonSerializerOptions, cancellationToken);
145+
}
146+
147+
if (canReplace)
148+
File.Replace(newPath, path, $"{path}.old");
149+
}
92150
}

0 commit comments

Comments
 (0)