Skip to content

Commit 305ca8b

Browse files
authored
feat: Add support for visual studio
1 parent 56fb5f8 commit 305ca8b

File tree

9 files changed

+227
-152
lines changed

9 files changed

+227
-152
lines changed

README.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,14 @@ internal sealed partial class SourceGenerationContext : JsonSerializerContext;
112112
```
113113
- It's all! Now you can build your project and use the generated code with full trimming/nativeAOT support.
114114

115+
## Known Errors
116+
117+
### Generator error: "Could not write to output file 'Path/to/file'. Could not find part of the path"
118+
119+
This error happens if the generated file path is too long. This happens if you didn't activated long path support on windows.
120+
To enable it follow the offical docs:
121+
https://learn.microsoft.com/en-us/windows/win32/fileio/maximum-file-path-limitation?tabs=registry#registry-setting-to-enable-long-paths
122+
115123
## 📚Examples of use in real SDKs📚
116124
- https://github.com/tryAGI/OpenAI
117125
- https://github.com/tryAGI/Ollama

src/libs/AutoSDK/Helpers/Box.cs

Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
namespace AutoSDK.Helpers;
2+
3+
public static class BoxEtensions
4+
{
5+
public static T Unbox<T>(this Box box)
6+
{
7+
return (T)box.Value;
8+
}
9+
public static Box Box<T>(this T tobox)
10+
{
11+
return new Box() { Value = tobox };
12+
}
13+
}
14+
15+
/// <summary>
16+
/// This class is used to box any value type or reference type into an object.
17+
/// This is used to avoid generic type cycling in structs.
18+
/// This is only here to support visual studio. Other dotnet build tools do not require this.
19+
/// More information can be found here:
20+
/// https://github.com/dotnet/runtime/issues/6924
21+
/// </summary>
22+
public struct Box : IEquatable<Box>
23+
{
24+
private object _value;
25+
public object Value
26+
{
27+
get => _value;
28+
set => _value = value;
29+
}
30+
31+
public override bool Equals(object? obj)
32+
{
33+
if (obj is null)
34+
{
35+
return false;
36+
}
37+
if (obj is Box other)
38+
{
39+
return ReferenceEquals(Value, other.Value);
40+
}
41+
return false;
42+
}
43+
44+
bool IEquatable<Box>.Equals(Box other)
45+
{
46+
return this.Equals(other);
47+
}
48+
49+
public override int GetHashCode()
50+
{
51+
return Value?.GetHashCode() ?? 0;
52+
}
53+
54+
public static bool operator ==(Box left, Box right)
55+
{
56+
return left.Equals(right);
57+
}
58+
59+
public static bool operator !=(Box left, Box right)
60+
{
61+
return !(left == right);
62+
}
63+
}

src/libs/AutoSDK/Models/ModelData.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,13 @@
1-
using System.Collections.Immutable;
21
using AutoSDK.Extensions;
2+
using AutoSDK.Helpers;
3+
using System.Collections.Immutable;
34

45
namespace AutoSDK.Models;
56

67
public record struct ModelData(
78
SchemaContext SchemaContext,
89
string Id,
9-
ImmutableArray<ModelData> Parents,
10+
ImmutableArray<Box> Parents,
1011
string Namespace,
1112
Settings Settings,
1213
ModelStyle Style,
@@ -25,7 +26,7 @@ public static ModelData FromSchemaContext(
2526
SchemaContext context)
2627
{
2728
context = context ?? throw new ArgumentNullException(nameof(context));
28-
29+
2930
var parents = new List<ModelData>();
3031
var parent = context.Parent;
3132
while (parent != null)
@@ -38,11 +39,11 @@ public static ModelData FromSchemaContext(
3839
}
3940

4041
parents.Reverse();
41-
42+
4243
return new ModelData(
4344
SchemaContext: context,
4445
Id: context.Id,
45-
Parents: parents.ToImmutableArray(),
46+
Parents: parents.Select(p => p.Box()).ToImmutableArray(),
4647
Namespace: context.Settings.Namespace,
4748
Style: context.Schema.IsEnum() ? ModelStyle.Enumeration : context.Settings.ModelStyle,
4849
Settings: context.Settings,
@@ -82,13 +83,13 @@ public static ModelData FromSchemaContext(
8283
// };
8384

8485
public string GlobalClassName => $"global::{Namespace}.{ClassName}";
85-
86+
8687
public string ExternalClassName => Settings.NamingConvention switch
8788
{
8889
NamingConvention.ConcatNames => ClassName,
89-
NamingConvention.InnerClasses => string.Join(".", Parents.Select(x => x.ClassName).Concat([ClassName])),
90+
NamingConvention.InnerClasses => string.Join(".", Parents.Select(x => x.Unbox<ModelData>().ClassName).Concat([ClassName])),
9091
_ => string.Empty,
9192
};
92-
93+
9394
public string FileNameWithoutExtension => $"{Namespace}.Models.{ExternalClassName}";
9495
}

src/libs/AutoSDK/Models/PropertyData.cs

Lines changed: 9 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
using AutoSDK.Extensions;
2+
using AutoSDK.Helpers;
23
using AutoSDK.Naming.Properties;
34

45
namespace AutoSDK.Models;
@@ -39,22 +40,22 @@ public static PropertyData FromSchemaContext(SchemaContext context)
3940
{
4041
context = context ?? throw new ArgumentNullException(nameof(context));
4142
var type = context.TypeData;
42-
43+
4344
// OpenAPI doesn't allow metadata for references so sometimes allOf with single item is used to add metadata.
4445
if (context.HasAllOfTypeForMetadata() &&
4546
!type.SubTypes.IsEmpty)
4647
{
47-
type = type.SubTypes[0] with
48+
type = type.SubTypes[0].Unbox<TypeData>() with
4849
{
49-
CSharpTypeRaw = type.SubTypes[0].CSharpTypeRaw,
50+
CSharpTypeRaw = type.SubTypes[0].Unbox<TypeData>().CSharpTypeRaw,
5051
CSharpTypeNullability = type.CSharpTypeNullability,
5152
};
5253
}
5354

5455
var requiredProperties = context.Parent != null
5556
? new HashSet<string>(context.Parent.Schema.Required)
5657
: [];
57-
58+
5859
var propertyName = context.PropertyName ?? throw new InvalidOperationException("Property name or parameter name is required.");
5960
var isRequired =
6061
requiredProperties.Contains(propertyName) &&
@@ -64,7 +65,7 @@ public static PropertyData FromSchemaContext(SchemaContext context)
6465
{
6566
isRequired = false;
6667
}
67-
68+
6869
return new PropertyData(
6970
Id: propertyName,
7071
Name: CSharpPropertyNameGenerator.ComputePropertyName(context),
@@ -81,19 +82,19 @@ public static PropertyData FromSchemaContext(SchemaContext context)
8182
DefaultValue: context.Schema is { ReadOnly: true } && !type.CSharpTypeNullability
8283
? "default!"
8384
: context.GetDefaultValue(),
84-
Example: context.Schema.Example?.GetString() is {} example &&
85+
Example: context.Schema.Example?.GetString() is { } example &&
8586
!string.IsNullOrWhiteSpace(example)
8687
? example.ClearForXml()
8788
: null,
8889
Summary: context.Schema.GetSummary(),
8990
ConverterType: type.ConverterType,
9091
DiscriminatorValue: string.Empty);
9192
}
92-
93+
9394
public string ParameterName => Name
9495
.Replace(".", string.Empty)
9596
.ToParameterName()
96-
97+
9798
// https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/keywords/
9899
.ReplaceIfEquals("abstract", "@abstract")
99100
.ReplaceIfEquals("as", "@as")

0 commit comments

Comments
 (0)