Skip to content

Commit 0656646

Browse files
authored
DeepClone: Use sourcegenerator to fix trimming issues (#32)
1 parent fd3e346 commit 0656646

5 files changed

Lines changed: 106 additions & 12 deletions

File tree

src/MudBlazor.ThemeManager/Components/MudThemeManager.razor.cs

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
using Microsoft.AspNetCore.Components;
22
using MudBlazor.State;
33
using MudBlazor.ThemeManager.Extensions;
4-
using System.Diagnostics.CodeAnalysis;
54

65
namespace MudBlazor.ThemeManager;
76

@@ -49,7 +48,6 @@ public MudThemeManager()
4948
[Parameter]
5049
public EventCallback<ThemeManagerTheme> ThemeChanged { get; set; }
5150

52-
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
5351
protected override void OnInitialized()
5452
{
5553
base.OnInitialized();
Lines changed: 86 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,22 +1,98 @@
1-
using System.Diagnostics.CodeAnalysis;
2-
using System.Text.Json;
1+
using System.Text.Json;
32

43
namespace MudBlazor.ThemeManager.Extensions;
54

65
internal static class Extension
76
{
8-
private static readonly JsonSerializerOptions JsonOptions = new();
7+
private static readonly PaletteSerializerContext PaletteSerializerContext = new();
8+
private static readonly ThemeSerializerContext ThemeSerializerContext = new();
99

10-
[RequiresUnreferencedCode("JSON serialization and deserialization might require types that cannot be statically analyzed.")]
11-
public static T? DeepClone<T>(this T source)
10+
public static MudTheme DeepClone(this MudTheme source)
1211
{
13-
if (source is not null)
12+
// TODO: Needs this to be done https://github.com/MudBlazor/MudBlazor/pull/9434
13+
//var themeType = typeof(MudTheme);
14+
//var serializeStr = JsonSerializer.Serialize(source, themeType, ThemeSerializerContext);
15+
//var copyObj = (MudTheme?)JsonSerializer.Deserialize(serializeStr, themeType, ThemeSerializerContext);
16+
17+
//return copyObj;
18+
19+
// Code below is a workaround for the above issue
20+
21+
return new MudTheme
22+
{
23+
PaletteDark = source.PaletteDark.DeepClone() ?? new PaletteDark(),
24+
PaletteLight = source.PaletteLight.DeepClone() ?? new PaletteLight(),
25+
Shadows = DeepCloneTheme(source.Shadows) ?? new Shadow(),
26+
LayoutProperties = DeepCloneTheme(source.LayoutProperties) ?? new LayoutProperties(),
27+
ZIndex = DeepCloneTheme(source.ZIndex) ?? new ZIndex(),
28+
PseudoCss = DeepCloneTheme(source.PseudoCss) ?? new PseudoCss(),
29+
// Exception case
30+
Typography = new Typography
31+
{
32+
Default = DeepCloneBaseTypography(source.Typography.Default),
33+
H1 = DeepCloneBaseTypography(source.Typography.H1),
34+
H2 = DeepCloneBaseTypography(source.Typography.H2),
35+
H3 = DeepCloneBaseTypography(source.Typography.H3),
36+
H4 = DeepCloneBaseTypography(source.Typography.H4),
37+
H5 = DeepCloneBaseTypography(source.Typography.H5),
38+
H6 = DeepCloneBaseTypography(source.Typography.H6),
39+
Subtitle1 = DeepCloneBaseTypography(source.Typography.Subtitle1),
40+
Subtitle2 = DeepCloneBaseTypography(source.Typography.Subtitle2),
41+
Body1 = DeepCloneBaseTypography(source.Typography.Body1),
42+
Body2 = DeepCloneBaseTypography(source.Typography.Body2),
43+
Input = DeepCloneBaseTypography(source.Typography.Input),
44+
Button = DeepCloneBaseTypography(source.Typography.Button),
45+
Caption = DeepCloneBaseTypography(source.Typography.Caption),
46+
Overline = DeepCloneBaseTypography(source.Typography.Overline)
47+
}
48+
};
49+
}
50+
51+
public static PaletteDark? DeepClone(this PaletteDark source) => DeepClonePalette(source);
52+
53+
public static PaletteLight? DeepClone(this PaletteLight source) => DeepClonePalette(source);
54+
55+
private static T? DeepClonePalette<T>(T source) where T : Palette
56+
{
57+
var paletteType = typeof(T);
58+
var serializeStr = JsonSerializer.Serialize(source, paletteType, PaletteSerializerContext);
59+
var copyObj = (T?)JsonSerializer.Deserialize(serializeStr, paletteType, PaletteSerializerContext);
60+
61+
return copyObj;
62+
}
63+
64+
private static T? DeepCloneTheme<T>(T source) where T : class
65+
{
66+
var paletteType = typeof(T);
67+
var serializeStr = JsonSerializer.Serialize(source, paletteType, ThemeSerializerContext);
68+
var copyObj = (T?)JsonSerializer.Deserialize(serializeStr, paletteType, ThemeSerializerContext);
69+
70+
return copyObj;
71+
}
72+
73+
private static T DeepCloneBaseTypography<T>(T baseTypography) where T : BaseTypography, new()
74+
{
75+
string[] fontFamilyCloned = new string[baseTypography.FontFamily?.Length ?? 0];
76+
if (baseTypography.FontFamily is not null)
1477
{
15-
var serializeStr = JsonSerializer.Serialize(source, JsonOptions);
16-
var copyObj = JsonSerializer.Deserialize<T>(serializeStr, JsonOptions);
17-
return copyObj;
78+
Array.Copy(baseTypography.FontFamily, fontFamilyCloned, baseTypography.FontFamily.Length);
1879
}
1980

20-
return default;
81+
82+
var fontWeightCloned = baseTypography.FontWeight;
83+
var fontSizeCloned = baseTypography.FontSize;
84+
var lineHeightCloned = baseTypography.LineHeight;
85+
var letterSpacingCloned = baseTypography.LetterSpacing;
86+
var textTransformCloned = baseTypography.TextTransform;
87+
88+
return new T
89+
{
90+
FontWeight = fontWeightCloned,
91+
FontFamily = fontFamilyCloned,
92+
FontSize = fontSizeCloned,
93+
LineHeight = lineHeightCloned,
94+
LetterSpacing = letterSpacingCloned,
95+
TextTransform = textTransformCloned,
96+
};
2197
}
2298
}
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace MudBlazor.ThemeManager.Extensions;
4+
5+
[JsonSerializable(typeof(Palette))]
6+
[JsonSerializable(typeof(PaletteDark))]
7+
[JsonSerializable(typeof(PaletteLight))]
8+
internal sealed partial class PaletteSerializerContext : JsonSerializerContext;
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
using System.Text.Json.Serialization;
2+
3+
namespace MudBlazor.ThemeManager.Extensions;
4+
5+
6+
//[JsonSerializable(typeof(MudTheme))] TODO: Needs this to be done https://github.com/MudBlazor/MudBlazor/pull/9434 rest can be removed after
7+
[JsonSerializable(typeof(Shadow))]
8+
[JsonSerializable(typeof(LayoutProperties))]
9+
[JsonSerializable(typeof(ZIndex))]
10+
[JsonSerializable(typeof(PseudoCss))]
11+
internal sealed partial class ThemeSerializerContext : JsonSerializerContext;

src/MudBlazor.ThemeManager/MudBlazor.ThemeManager.csproj

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22

33
<PropertyGroup>
44
<TargetFrameworks>net7.0;net8.0</TargetFrameworks>
5+
<LangVersion>latest</LangVersion>
56
<ImplicitUsings>enable</ImplicitUsings>
67
<Nullable>enable</Nullable>
78
<IsTrimmable>true</IsTrimmable>

0 commit comments

Comments
 (0)