diff --git a/PocketCsvReader.Testing/Configuration/SchemaDescriptionBuilderTest.cs b/PocketCsvReader.Testing/Configuration/SchemaDescriptionBuilderTest.cs index 90288a0..5502bb9 100644 --- a/PocketCsvReader.Testing/Configuration/SchemaDescriptionBuilderTest.cs +++ b/PocketCsvReader.Testing/Configuration/SchemaDescriptionBuilderTest.cs @@ -96,6 +96,32 @@ public void NamedWithFields_ShouldSetFields() Assert.That(field.Name, Is.Not.Null.Or.Empty); } + private static IEnumerable CreateBuilder() + { + yield return new SchemaDescriptorBuilder().Named(); + yield return new SchemaDescriptorBuilder().Indexed(); + } + + [Test] + [TestCaseSource(nameof(CreateBuilder))] + public void InterfaceWithFields_ShouldSetFields(ISchemaDescriptorBuilder builder) + { + builder.WithField(typeof(int), "foo", (x) => x); + builder.WithField(typeof(DateTime), "bar", (f) => f.WithFormat("%Y-%M-%d")); + var descriptor = builder.Build(); + Assert.That(descriptor, Is.Not.Null); + Assert.That(descriptor!.Fields, Has.Length.EqualTo(2)); + Assert.That(descriptor.Fields["foo"].RuntimeType, Is.EqualTo(typeof(int))); + Assert.That(descriptor.Fields["foo"].Name, Is.EqualTo("foo")); + Assert.That(descriptor.Fields["foo"].Format, Is.Null); + Assert.That(descriptor.Fields["bar"].RuntimeType, Is.EqualTo(typeof(DateTime))); + Assert.That(descriptor.Fields["bar"].Name, Is.EqualTo("bar")); + Assert.That(descriptor.Fields["bar"].Format, Is.EqualTo("%Y-%M-%d")); + + foreach (var field in descriptor.Fields) + Assert.That(field.Name, Is.Not.Null.Or.Empty); + } + [Test] public void DuplicateNames_ShouldThrow() { diff --git a/PocketCsvReader/Configuration/FieldCollectionDescriptor.cs b/PocketCsvReader/Configuration/FieldCollectionDescriptor.cs index 8eeefa9..c267a75 100644 --- a/PocketCsvReader/Configuration/FieldCollectionDescriptor.cs +++ b/PocketCsvReader/Configuration/FieldCollectionDescriptor.cs @@ -70,7 +70,7 @@ public override FieldDescriptor this[int index] public override FieldDescriptor this[string name] { - get => throw new NotSupportedException(); + get => _list.FirstOrDefault(f => f.Name == name) ?? throw new KeyNotFoundException($"Field '{name}' not found."); } public override bool TryGetValue(string name, [NotNullWhen(true)] out FieldDescriptor? field) diff --git a/PocketCsvReader/Configuration/SchemaDescriptorBuilder.cs b/PocketCsvReader/Configuration/SchemaDescriptorBuilder.cs index 1733560..ec18b9b 100644 --- a/PocketCsvReader/Configuration/SchemaDescriptorBuilder.cs +++ b/PocketCsvReader/Configuration/SchemaDescriptorBuilder.cs @@ -18,6 +18,7 @@ public NamedSchemaDescriptorBuilder Named() public interface ISchemaDescriptorBuilder { SchemaDescriptor? Build(); + ISchemaDescriptorBuilder WithField(Type type, string name, Func func); } public class IndexedSchemaDescriptorBuilder : ISchemaDescriptorBuilder @@ -40,6 +41,12 @@ public IndexedSchemaDescriptorBuilder WithField(Type type, Func func) + => WithField(type, (builder) => func(builder.WithName(name))); + + ISchemaDescriptorBuilder ISchemaDescriptorBuilder.WithField(Type type, string name, Func func) + => WithField(type, name, func); + public SchemaDescriptor? Build() { foreach (var field in _fields) @@ -58,11 +65,17 @@ public NamedSchemaDescriptorBuilder WithField(string name) => WithField(name, x => x); public NamedSchemaDescriptorBuilder WithField(string name, Func func) + => WithField(typeof(T), name, func); + + public NamedSchemaDescriptorBuilder WithField(Type type, string name, Func func) { - _fields.Add(func(new FieldDescriptorBuilder(typeof(T)).WithName(name))); + _fields.Add(func(new FieldDescriptorBuilder(type).WithName(name))); return this; } + ISchemaDescriptorBuilder ISchemaDescriptorBuilder.WithField(Type type, string name, Func func) + => WithField(type, name, func); + public SchemaDescriptor? Build() { foreach (var field in _fields)