Skip to content

Commit

Permalink
Align naming behavior of CollectionSegments to Connections (#4937)
Browse files Browse the repository at this point in the history
  • Loading branch information
gkfischer committed May 8, 2022
1 parent 1096ec7 commit 201f112
Show file tree
Hide file tree
Showing 23 changed files with 521 additions and 260 deletions.

This file was deleted.

@@ -1,13 +1,13 @@
namespace HotChocolate.Types.Pagination;

/// <summary>
/// Represents the offset paging page info.
/// Represents the offset paging page info.
/// This class provides additional information about the selected page.
/// </summary>
public class CollectionSegmentInfo : IPageInfo
{
/// <summary>
/// Initializes <see cref="CollectionSegmentCountType{T}" />.
/// Initializes <see cref="CollectionSegmentInfo" />.
/// </summary>
/// <param name="hasNextPage"></param>
/// <param name="hasPreviousPage"></param>
Expand Down
@@ -1,79 +1,136 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using HotChocolate.Configuration;
using HotChocolate.Resolvers;
using HotChocolate.Types.Descriptors;
using HotChocolate.Types.Descriptors.Definitions;
using static HotChocolate.Properties.TypeResources;

namespace HotChocolate.Types.Pagination;

public class CollectionSegmentType<T>
: ObjectType<CollectionSegment>
internal class CollectionSegmentType
: ObjectType
, IPageType
where T : class, IOutputType
{
/// <summary>
/// Initializes <see cref="CollectionSegmentType{T}" />.
/// </summary>
public CollectionSegmentType()
internal CollectionSegmentType(
NameString? collectionSegmentName,
ITypeReference nodeType,
bool withTotalCount)
{
}
if (nodeType is null)
{
throw new ArgumentNullException(nameof(nodeType));
}

/// <summary>
/// Initializes <see cref="CollectionSegmentType{T}" />.
/// </summary>
/// <param name="configure">
/// A delegate adding more configuration to the type.
/// </param>
public CollectionSegmentType(
Action<IObjectTypeDescriptor<CollectionSegment>> configure)
: base(descriptor =>
Definition = CreateTypeDefinition(withTotalCount);

if (collectionSegmentName is not null)
{
ApplyConfig(descriptor);
configure(descriptor);
})
{
Definition.Name = collectionSegmentName.Value + "CollectionSegment";
}
else
{
Definition.Configurations.Add(
new CompleteConfiguration(
(c, d) =>
{
IType type = c.GetType<IType>(nodeType);
var definition = (ObjectTypeDefinition)d;
definition.Name = type.NamedType().Name + "CollectionSegment";
},
Definition,
ApplyConfigurationOn.Naming,
nodeType,
TypeDependencyKind.Named));
}

Definition.Configurations.Add(
new CompleteConfiguration(
(c, d) =>
{
ItemType = c.GetType<IOutputType>(nodeType);
var definition = (ObjectTypeDefinition)d;
ObjectFieldDefinition nodes = definition.Fields.First(IsItemsField);
nodes.Type = TypeReference.Parse($"[{ItemType.Print()}]", TypeContext.Output);
},
Definition,
ApplyConfigurationOn.Naming,
nodeType,
TypeDependencyKind.Named));

Definition.Dependencies.Add(new(nodeType));
}

/// <summary>
/// Gets the item type of this collection segment.
/// </summary>
public IOutputType ItemType { get; private set; } = default!;

protected override void Configure(IObjectTypeDescriptor<CollectionSegment> descriptor) =>
ApplyConfig(descriptor);

protected static void ApplyConfig(IObjectTypeDescriptor<CollectionSegment> descriptor)
protected override void OnBeforeRegisterDependencies(
ITypeDiscoveryContext context,
DefinitionBase definition,
IDictionary<string, object?> contextData)
{
descriptor
.Name(dependency => $"{dependency.Name}CollectionSegment")
.DependsOn<T>()
.BindFieldsExplicitly();

descriptor
.Field(i => i.Items)
.Name("items")
.Type<ListType<T>>();

descriptor
.Field(t => t.Info)
.Name("pageInfo")
.Description("Information to aid in pagination.")
.Type<NonNullType<CollectionSegmentInfoType>>();
context.Dependencies.Add(new(
context.TypeInspector.GetOutputTypeRef(typeof(CollectionSegmentInfoType))));

base.OnBeforeRegisterDependencies(context, definition, contextData);
}

protected override void OnRegisterDependencies(
ITypeDiscoveryContext context,
ObjectTypeDefinition definition)
private static ObjectTypeDefinition CreateTypeDefinition(bool withTotalCount)
{
base.OnRegisterDependencies(context, definition);
context.Dependencies.Add(new(context.TypeInspector.GetTypeRef(typeof(T))));
var definition = new ObjectTypeDefinition(
default,
CollectionSegmentType_Description,
typeof(CollectionSegment));

definition.Fields.Add(new(
Names.PageInfo,
CollectionSegmentType_PageInfo_Description,
TypeReference.Parse("CollectionSegmentInfo!"),
pureResolver: GetPagingInfo));

definition.Fields.Add(new(
Names.Items,
CollectionSegmentType_Items_Description,
pureResolver: GetItems) {CustomSettings = {ContextDataKeys.Items}});

if (withTotalCount)
{
definition.Fields.Add(new(
Names.TotalCount,
type: TypeReference.Parse($"{ScalarNames.Int}!"),
resolver: GetTotalCountAsync));
}

return definition;
}

protected override void OnCompleteType(
ITypeCompletionContext context,
ObjectTypeDefinition definition)
private static IPageInfo GetPagingInfo(IPureResolverContext context)
=> context.Parent<CollectionSegment>().Info;

private static IEnumerable<object?> GetItems(IPureResolverContext context)
=> context.Parent<CollectionSegment>().Items;

private static async ValueTask<object?> GetTotalCountAsync(IResolverContext context)
=> await context.Parent<CollectionSegment>().GetTotalCountAsync(context.RequestAborted);

private static bool IsItemsField(ObjectFieldDefinition field)
=> field.CustomSettings.Count > 0 &&
field.CustomSettings[0].Equals(ContextDataKeys.Items);

internal static class Names
{
base.OnCompleteType(context, definition);
public const string PageInfo = "pageInfo";
public const string Items = "items";
public const string TotalCount = "totalCount";
}

ItemType = context.GetType<IOutputType>(
context.TypeInspector.GetTypeRef(typeof(T)));
private static class ContextDataKeys
{
public const string Items = "HotChocolate.Types.CollectionSegment.Items";
}
}

0 comments on commit 201f112

Please sign in to comment.