function createFieldProcessor(
	field,
	normalizeRequest,
	assertRequest,
	assertTarget,
) {
	return function fieldProcessor(request, conditionNames) {
		request = assertRequest(request);

		const match = findMatch(normalizeRequest(request), field);

		if (match === null) return [[], null];

		const [mapping, remainingRequest, isSubpathMapping, isPattern, usedField] =
			match;

		/** @type {DirectMapping | null} */
		let direct = null;

		if (isConditionalMapping(mapping)) {
			direct = conditionalMapping(
				/** @type {ConditionalMapping} */ (mapping),
				conditionNames,
			);

			// matching not found
			if (direct === null) return [[], null];
		} else {
			direct = /** @type {DirectMapping} */ (mapping);
		}

		return [
			directMapping(
				remainingRequest,
				isPattern,
				isSubpathMapping,
				direct,
				conditionNames,
				assertTarget,
			),
			usedField,
		];
	};
}
@param {ExportsField | ImportsField} field root
@param {(s: string) => string} normalizeRequest Normalize request, for `imports` field it adds `#`, for `exports` field it adds `.` or `./`
@param {(s: string) => string} assertRequest assertRequest
@param {(s: string, f: boolean) => void} assertTarget assertTarget
@returns {FieldProcessor} field processor