fn transform_stream()

in compiler/crates/relay-transforms/src/defer_stream/mod.rs [161:259]


    fn transform_stream(
        &mut self,
        linked_field: &LinkedField,
        stream: &Directive,
    ) -> Result<Transformed<Selection>, Diagnostic> {
        let schema_field = self.program.schema.field(linked_field.definition.item);
        if !schema_field.type_.is_list() {
            return Err(Diagnostic::error(
                ValidationMessage::StreamFieldIsNotAList {
                    field_name: schema_field.name.item,
                },
                stream.name.location,
            ));
        }

        let StreamDirective {
            if_arg,
            label_arg,
            initial_count_arg,
            use_customized_batch_arg,
        } = StreamDirective::from(stream);

        let transformed_linked_field = self.default_transform_linked_field(linked_field);
        let get_next_selection = |directives| match transformed_linked_field {
            Transformed::Replace(mut selection) => {
                selection.set_directives(directives);
                Transformed::Replace(selection)
            }
            Transformed::Keep => {
                Transformed::Replace(Selection::LinkedField(Arc::new(LinkedField {
                    directives,
                    ..linked_field.clone()
                })))
            }
            Transformed::Delete => Transformed::Delete,
        };
        if is_literal_false_arg(if_arg) {
            return Ok(get_next_selection(remove_directive(
                &linked_field.directives,
                stream.name.item,
            )));
        }

        if initial_count_arg.is_none() {
            return Err(Diagnostic::error(
                ValidationMessage::StreamInitialCountRequired,
                stream.name.location,
            ));
        }

        let label_value = get_literal_string_argument(stream, label_arg)?;
        let label = label_value.unwrap_or_else(|| {
            get_applied_fragment_name(
                linked_field.alias_or_name(&self.program.schema),
                &linked_field.arguments,
            )
        });
        let transformed_label = transform_label(
            self.current_document_name
                .expect("We expect the parent name to be defined here."),
            DEFER_STREAM_CONSTANTS.stream_name,
            label,
        );
        self.record_label(transformed_label, stream);
        let next_label_value = Value::Constant(ConstantValue::String(transformed_label));
        let next_label_arg = Argument {
            name: WithLocation {
                item: DEFER_STREAM_CONSTANTS.label_arg,
                location: label_arg.map_or(stream.name.location, |arg| arg.name.location),
            },
            value: WithLocation {
                item: next_label_value,
                location: label_arg.map_or(stream.name.location, |arg| arg.value.location),
            },
        };

        let mut next_arguments = Vec::with_capacity(4);
        next_arguments.push(next_label_arg);
        if let Some(if_arg) = if_arg {
            next_arguments.push(if_arg.clone());
        }
        if let Some(initial_count_arg) = initial_count_arg {
            next_arguments.push(initial_count_arg.clone());
        }
        if let Some(use_customized_batch_arg) = use_customized_batch_arg {
            next_arguments.push(use_customized_batch_arg.clone());
        }

        let next_stream = Directive {
            name: stream.name,
            arguments: next_arguments,
            data: None,
        };

        Ok(get_next_selection(replace_directive(
            &linked_field.directives,
            next_stream,
        )))
    }