Subject: Re: [PATCH v2 1/3] promisor-remote: refactor to get rid of 'struct strvec'

From: Patrick Steinhardt <[email-masked]>
Date: Wed, 7 May 2025 10:25:36 +0200

On Tue, Apr 29, 2025 at 04:52:41PM +0200, Christian Couder wrote:
> diff --git a/promisor-remote.c b/promisor-remote.c
> index 5801ebfd9b..24d0e70132 100644
> --- a/promisor-remote.c
> +++ b/promisor-remote.c
> @@ -314,10 +314,51 @@ static int allow_unsanitized(char ch)
>  	return ch > 32 && ch < 127;
>  }
>  
> -static void promisor_info_vecs(struct repository *repo,
> -			       struct strvec *names,
> -			       struct strvec *urls)
> +/*
> + * Linked list for promisor remotes involved in the "promisor-remote"
> + * protocol capability.
> + *
> + * 'fields' contains a defined set of field name/value pairs for
> + * each promisor remote. Field names are stored in the 'string'
> + * member, and values in the 'util' member.
> + *
> + * Currently supported field names:
> + * - "name": The name of the promisor remote.
> + * - "url": The URL of the promisor remote.
> + *
> + * Except for "name", each "<field_name>/<field_value>" pair should
> + * correspond to a "remote.<name>.<field_name>" config variable set to
> + * <field_value> where "<name>" is a promisor remote name.
> + *
> + * 'fields' should not be sorted, as we will rely on the order we put
> + * things into it. So, for example, 'string_list_append()' should be
> + * used instead of 'string_list_insert()'.
> + */
> +struct promisor_info {
> +	struct promisor_info *next;
> +	struct string_list fields;

Now that we have a restricted set of accepted fields, wouldn't it be
easier to store those as individual members of this struct directly?

[snip]
>  /*
> - * Find first index of 'nicks' where there is 'nick'. 'nick' is
> - * compared case sensitively to the strings in 'nicks'. If not found
> - * 'nicks->nr' is returned.
> + * Find first element of 'p' where the 'name' field is 'nick'. 'nick'
> + * is compared case sensitively to the strings in 'p'. If not found
> + * NULL is returned.
>   */
> -static size_t remote_nick_find(struct strvec *nicks, const char *nick)
> +static struct promisor_info *remote_nick_find(struct promisor_info *p, const char *nick)
>  {
> -	for (size_t i = 0; i < nicks->nr; i++)
> -		if (!strcmp(nicks->v[i], nick))
> -			return i;
> -	return nicks->nr;
> +	for (; p; p = p->next) {
> +		if (strcmp(p->fields.items[0].string, "name"))
> +			BUG("First field of promisor info should be 'name', but was '%s'.",
> +			    p->fields.items[0].string);
> +		if (!strcmp(p->fields.items[0].util, nick))
> +			return p;
> +	}
> +	return NULL;
>  }
>  
>  enum accept_promisor {

If so, we could also simplify code like this because we wouldn't have to
assume any indices anymore.

Patrick