Skip to content

Commit 51313e3

Browse files
committed
Support CSharp
Create basic language implementation. Start adding tests. Add snapshot tests Update slice type to map to IEnumerable instead of Array. Drop support for Unit type and return an error. Support anonymous structs Update slice of user type test snapshot Support namespace option Support serialization with json attributes Remove EnumLabel and use EnumMember attribute instead. Update all test snapshots according to the new changes. C# without naming convention option Add required attribute For newtonsoft json to require a non optional property, the property has to have the required attribute. Otherwise, it allows it to be null and a default value is provided.
1 parent edccd96 commit 51313e3

File tree

46 files changed

+1423
-43
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

46 files changed

+1423
-43
lines changed

cli/src/config.rs

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,15 @@ pub struct GoParams {
6262
pub type_mappings: HashMap<String, String>,
6363
}
6464

65-
/// The parameters that are used to configure the behaviour of typeshare
65+
#[derive(Default, Serialize, Deserialize, PartialEq, Eq, Debug)]
66+
#[serde(default)]
67+
pub struct CSharpParams {
68+
pub type_mappings: HashMap<String, String>,
69+
pub namespace: String,
70+
pub without_csharp_naming_convention: bool,
71+
}
72+
73+
/// The paramters that are used to configure the behaviour of typeshare
6674
/// from the configuration file `typeshare.toml`
6775
#[derive(Serialize, Deserialize, Default, Debug, PartialEq)]
6876
#[serde(default)]
@@ -77,6 +85,7 @@ pub(crate) struct Config {
7785
pub go: GoParams,
7886
#[serde(skip)]
7987
pub target_os: Vec<String>,
88+
pub csharp: CSharpParams,
8089
}
8190

8291
pub(crate) fn store_config(config: &Config, file_path: Option<&Path>) -> anyhow::Result<()> {

cli/src/main.rs

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,12 @@ fn language(
212212
type_mappings: config.typescript.type_mappings,
213213
..Default::default()
214214
}),
215+
SupportedLanguage::CSharp => Box::new(CSharp {
216+
namespace: config.csharp.namespace,
217+
type_mappings: config.csharp.type_mappings,
218+
without_csharp_naming_convention: config.csharp.without_csharp_naming_convention,
219+
..Default::default()
220+
}),
215221
#[cfg(feature = "go")]
216222
SupportedLanguage::Go => Box::new(Go {
217223
package: config.go.package,
@@ -262,6 +268,10 @@ fn override_configuration(mut config: Config, options: &Args) -> anyhow::Result<
262268
config.scala.module_name = scala_module_name.to_string();
263269
}
264270

271+
if let Some(csharp_namespace) = options.value_of(ARG_CSHARP_NAMESPACE) {
272+
config.csharp.namespace = csharp_namespace.to_string();
273+
}
274+
265275
#[cfg(feature = "go")]
266276
{
267277
if let Some(go_package) = options.go_package.as_ref() {

cli/src/parse.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,7 @@ fn output_file_name(language_type: SupportedLanguage, crate_name: &CrateName) ->
5959
SupportedLanguage::Swift => pascal_case(),
6060
SupportedLanguage::TypeScript => snake_case(),
6161
SupportedLanguage::Python => snake_case(),
62+
SupportedLanguage::CSharp => pascal_case(),
6263
}
6364
}
6465

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
#nullable enable
2+
3+
using System.Reflection;
4+
using JsonSubTypes;
5+
using Newtonsoft.Json;
6+
using System.Runtime.Serialization;
7+
8+
/** Generated type representing the anonymous struct variant `List` of the `AnonymousStructWithRename` Rust enum */
9+
public class AnonymousStructWithRenameListInner {
10+
public IEnumerable<string> list { get; set; }
11+
}
12+
13+
/** Generated type representing the anonymous struct variant `LongFieldNames` of the `AnonymousStructWithRename` Rust enum */
14+
public class AnonymousStructWithRenameLongFieldNamesInner {
15+
public string some_long_field_name { get; set; }
16+
public bool and { get; set; }
17+
public IEnumerable<string> but_one_more { get; set; }
18+
}
19+
20+
/** Generated type representing the anonymous struct variant `KebabCase` of the `AnonymousStructWithRename` Rust enum */
21+
public class AnonymousStructWithRenameKebabCaseInner {
22+
public IEnumerable<string> another-list { get; set; }
23+
public string camelCaseStringField { get; set; }
24+
public bool something-else { get; set; }
25+
}
26+
27+
[JsonConverter(typeof(JsonSubtypes), "type")]
28+
[JsonSubtypes.KnownSubType(typeof(List), "List")]
29+
[JsonSubtypes.KnownSubType(typeof(LongFieldNames), "LongFieldNames")]
30+
[JsonSubtypes.KnownSubType(typeof(KebabCase), "KebabCase")]
31+
public abstract record AnonymousStructWithRename
32+
{
33+
public record list(AnonymousStructWithRenameListInner Content): AnonymousStructWithRename();
34+
public record longFieldNames(AnonymousStructWithRenameLongFieldNamesInner Content): AnonymousStructWithRename();
35+
public record kebabCase(AnonymousStructWithRenameKebabCaseInner Content): AnonymousStructWithRename();
36+
}
37+
38+
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
#nullable enable
2+
3+
using System.Reflection;
4+
using JsonSubTypes;
5+
using Newtonsoft.Json;
6+
using System.Runtime.Serialization;
7+
8+
public class ItemDetailsFieldValue {
9+
public string Hello { get; set; }
10+
}
11+
12+
[JsonConverter(typeof(JsonSubtypes), "t")]
13+
[JsonSubtypes.KnownSubType(typeof(String), "String")]
14+
[JsonSubtypes.KnownSubType(typeof(Number), "Number")]
15+
[JsonSubtypes.KnownSubType(typeof(NumberArray), "NumberArray")]
16+
[JsonSubtypes.KnownSubType(typeof(ReallyCoolType), "ReallyCoolType")]
17+
[JsonSubtypes.KnownSubType(typeof(ArrayReallyCoolType), "ArrayReallyCoolType")]
18+
[JsonSubtypes.KnownSubType(typeof(DictionaryReallyCoolType), "DictionaryReallyCoolType")]
19+
public abstract record AdvancedColors
20+
{
21+
public record String(string C) : AdvancedColors();
22+
public record Number(int C) : AdvancedColors();
23+
public record NumberArray(IEnumerable<int> C) : AdvancedColors();
24+
public record ReallyCoolType(ItemDetailsFieldValue C) : AdvancedColors();
25+
public record ArrayReallyCoolType(IEnumerable<ItemDetailsFieldValue> C) : AdvancedColors();
26+
public record DictionaryReallyCoolType(IDictionary<string, ItemDetailsFieldValue> C) : AdvancedColors();
27+
}
28+
29+
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
#nullable enable
2+
3+
using System.Reflection;
4+
using JsonSubTypes;
5+
using Newtonsoft.Json;
6+
using System.Runtime.Serialization;
7+
8+
namespace Company.Domain.Models;
9+
10+
/** Struct comment */
11+
public class ItemDetailsFieldValue {
12+
}
13+
14+
/** Enum comment */
15+
[JsonConverter(typeof(JsonSubtypes), "type")]
16+
[JsonSubtypes.KnownSubType(typeof(String), "String")]
17+
[JsonSubtypes.KnownSubType(typeof(Number), "Number")]
18+
[JsonSubtypes.KnownSubType(typeof(UnsignedNumber), "UnsignedNumber")]
19+
[JsonSubtypes.KnownSubType(typeof(NumberArray), "NumberArray")]
20+
[JsonSubtypes.KnownSubType(typeof(ReallyCoolType), "ReallyCoolType")]
21+
public abstract record AdvancedColors
22+
{
23+
/** This is a case comment */
24+
public record String(string Content) : AdvancedColors();
25+
public record Number(int Content) : AdvancedColors();
26+
public record UnsignedNumber(uint Content) : AdvancedColors();
27+
public record NumberArray(IEnumerable<int> Content) : AdvancedColors();
28+
/** Comment on the last element */
29+
public record ReallyCoolType(ItemDetailsFieldValue Content) : AdvancedColors();
30+
}
31+
32+
33+
[JsonConverter(typeof(JsonSubtypes), "type")]
34+
[JsonSubtypes.KnownSubType(typeof(String), "String")]
35+
[JsonSubtypes.KnownSubType(typeof(Number), "Number")]
36+
[JsonSubtypes.KnownSubType(typeof(NumberArray), "NumberArray")]
37+
[JsonSubtypes.KnownSubType(typeof(ReallyCoolType), "ReallyCoolType")]
38+
public abstract record AdvancedColors2
39+
{
40+
/** This is a case comment */
41+
public record String(string Content) : AdvancedColors2();
42+
public record Number(int Content) : AdvancedColors2();
43+
public record NumberArray(IEnumerable<int> Content) : AdvancedColors2();
44+
/** Comment on the last element */
45+
public record ReallyCoolType(ItemDetailsFieldValue Content) : AdvancedColors2();
46+
}
47+
48+
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
#nullable enable
2+
3+
using System.Reflection;
4+
using JsonSubTypes;
5+
using Newtonsoft.Json;
6+
using System.Runtime.Serialization;
7+
8+
[JsonConverter(typeof(JsonSubtypes), "type")]
9+
[JsonSubtypes.KnownSubType(typeof(A), "A")]
10+
[JsonSubtypes.KnownSubType(typeof(C), "C")]
11+
public abstract record SomeEnum
12+
{
13+
public record A(): SomeEnum();
14+
public record C(int Content) : SomeEnum();
15+
}
16+
17+
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
#nullable enable
2+
3+
using System.Reflection;
4+
using JsonSubTypes;
5+
using Newtonsoft.Json;
6+
using System.Runtime.Serialization;
7+
8+
/** This is a comment. */
9+
public enum Colors
10+
{
11+
Red,
12+
13+
Blue,
14+
15+
Green,
16+
17+
}
18+
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
#nullable enable
2+
3+
using System.Reflection;
4+
using JsonSubTypes;
5+
using Newtonsoft.Json;
6+
using System.Runtime.Serialization;
7+
8+
public class AddressDetails {
9+
}
10+
11+
[JsonConverter(typeof(JsonSubtypes), "type")]
12+
[JsonSubtypes.KnownSubType(typeof(FixedAddress), "FixedAddress")]
13+
[JsonSubtypes.KnownSubType(typeof(NoFixedAddress), "NoFixedAddress")]
14+
public abstract record Address
15+
{
16+
public record FixedAddress(AddressDetails Content) : Address();
17+
public record NoFixedAddress(): Address();
18+
}
19+
20+
Lines changed: 69 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#nullable enable
2+
3+
using System.Reflection;
4+
using JsonSubTypes;
5+
using Newtonsoft.Json;
6+
using System.Runtime.Serialization;
7+
8+
[JsonConverter(typeof(JsonSubtypes), "type")]
9+
[JsonSubtypes.KnownSubType(typeof(VariantA), "VariantA")]
10+
[JsonSubtypes.KnownSubType(typeof(VariantB), "VariantB")]
11+
public abstract record GenericEnum<TA, TB>
12+
{
13+
public record VariantA(TA Content) : GenericEnum<TA, TB>();
14+
public record VariantB(TB Content) : GenericEnum<TA, TB>();
15+
}
16+
17+
18+
public class StructUsingGenericEnum {
19+
public GenericEnum<string, short> EnumField { get; set; }
20+
}
21+
22+
[JsonConverter(typeof(JsonSubtypes), "type")]
23+
[JsonSubtypes.KnownSubType(typeof(VariantC), "VariantC")]
24+
[JsonSubtypes.KnownSubType(typeof(VariantD), "VariantD")]
25+
[JsonSubtypes.KnownSubType(typeof(VariantE), "VariantE")]
26+
public abstract record GenericEnumUsingGenericEnum<T>
27+
{
28+
public record VariantC(GenericEnum<T, T> Content) : GenericEnumUsingGenericEnum<T>();
29+
public record VariantD(GenericEnum<string, IDictionary<string, T>> Content) : GenericEnumUsingGenericEnum<T>();
30+
public record VariantE(GenericEnum<string, uint> Content) : GenericEnumUsingGenericEnum<T>();
31+
}
32+
33+
34+
/** Generated type representing the anonymous struct variant `VariantF` of the `GenericEnumsUsingStructVariants` Rust enum */
35+
public class GenericEnumsUsingStructVariantsVariantFInner<T> {
36+
public T Action { get; set; }
37+
}
38+
39+
/** Generated type representing the anonymous struct variant `VariantG` of the `GenericEnumsUsingStructVariants` Rust enum */
40+
public class GenericEnumsUsingStructVariantsVariantGInner<T, TU> {
41+
public T Action { get; set; }
42+
public TU Response { get; set; }
43+
}
44+
45+
/** Generated type representing the anonymous struct variant `VariantH` of the `GenericEnumsUsingStructVariants` Rust enum */
46+
public class GenericEnumsUsingStructVariantsVariantHInner {
47+
public int NonGeneric { get; set; }
48+
}
49+
50+
/** Generated type representing the anonymous struct variant `VariantI` of the `GenericEnumsUsingStructVariants` Rust enum */
51+
public class GenericEnumsUsingStructVariantsVariantIInner<T, TU> {
52+
public IEnumerable<T> Vec { get; set; }
53+
public MyType<T, TU> Action { get; set; }
54+
}
55+
56+
[JsonConverter(typeof(JsonSubtypes), "type")]
57+
[JsonSubtypes.KnownSubType(typeof(VariantF), "VariantF")]
58+
[JsonSubtypes.KnownSubType(typeof(VariantG), "VariantG")]
59+
[JsonSubtypes.KnownSubType(typeof(VariantH), "VariantH")]
60+
[JsonSubtypes.KnownSubType(typeof(VariantI), "VariantI")]
61+
public abstract record GenericEnumsUsingStructVariants<T, TU>
62+
{
63+
public record VariantF(GenericEnumsUsingStructVariantsVariantFInner<T> Content): GenericEnumsUsingStructVariants<T, TU>();
64+
public record VariantG(GenericEnumsUsingStructVariantsVariantGInner<T, TU> Content): GenericEnumsUsingStructVariants<T, TU>();
65+
public record VariantH(GenericEnumsUsingStructVariantsVariantHInner Content): GenericEnumsUsingStructVariants<T, TU>();
66+
public record VariantI(GenericEnumsUsingStructVariantsVariantIInner<T, TU> Content): GenericEnumsUsingStructVariants<T, TU>();
67+
}
68+
69+

0 commit comments

Comments
 (0)