Repository: nushell/nushell
File: crates/nu-command/src/formats/to/msgpack.rs (Rust)

Code before:
                    serialize_types,
                )?;
            }
        }
        Value::Nothing { .. } => {
            mp::write_nil(out)
                .map_err(InvalidMarkerWrite)
                .err_span(span)?;
        }
        Value::Closure { val, .. } => {
            if serialize_types {
                let block = engine_state.get_block(val.block_id);
                let closure_string: &str = if let Some(span) = block.span {
                    let contents_bytes = engine_state.get_span_contents(span);
                    &String::from_utf8_lossy(contents_bytes)
                } else {
                    return Err(WriteError::Shell(Box::new(ShellError::CantConvert {
                        to_type: "string".into(),
                        from_type: "closure".into(),
                        span,
                        help: Some(format!(
                            "unable to retrieve block contents for closure with id {}",
                            val.block_id.get()
                        )),
                    })));
                };
                mp::write_str(out, closure_string).err_span(span)?;
            } else {
                return Err(WriteError::Shell(Box::new(ShellError::UnsupportedInput {
                    msg: "closures are currently not deserializable (use --serialize to serialize as a string)".into(),
                    input: "value originates from here".into(),
                    msg_span: call_span,
                    input_span: span,
                })));
            }
        }
        Value::Error { error, .. } => {
            return Err(WriteError::Shell(error.clone()));
        }
        Value::CellPath { val, .. } => {
            // Write as a list of strings/ints
            mp::write_array_len(out, convert(val.members.len(), span)?).err_span(span)?;
            for member in &val.members {
                match member {
                    PathMember::String { val, .. } => {
                        mp::write_str(out, val).err_span(span)?;
                    }
                    PathMember::Int { val, .. } => {
                        mp::write_uint(out, *val as u64).err_span(span)?;
                    }
                }

Review comment (suggestion):
Could this part you repeated across a few places live on the closure type?

e.g. `Closure::coerce_to_string`

Code after:
                    serialize_types,
                )?;
            }
        }
        Value::Nothing { .. } => {
            mp::write_nil(out)
                .map_err(InvalidMarkerWrite)
                .err_span(span)?;
        }
        Value::Closure { val, .. } => {
            if serialize_types {
                let closure_string = val
                    .coerce_into_string(engine_state, span)
                    .map_err(|err| WriteError::Shell(Box::new(err)))?;
                mp::write_str(out, &closure_string).err_span(span)?;
            } else {
                return Err(WriteError::Shell(Box::new(ShellError::UnsupportedInput {
                    msg: "closures are currently not deserializable (use --serialize to serialize as a string)".into(),
                    input: "value originates from here".into(),
                    msg_span: call_span,
                    input_span: span,
                })));
            }
        }
        Value::Error { error, .. } => {
            return Err(WriteError::Shell(error.clone()));
        }
        Value::CellPath { val, .. } => {
            // Write as a list of strings/ints
            mp::write_array_len(out, convert(val.members.len(), span)?).err_span(span)?;
            for member in &val.members {
                match member {
                    PathMember::String { val, .. } => {
                        mp::write_str(out, val).err_span(span)?;
                    }
                    PathMember::Int { val, .. } => {
                        mp::write_uint(out, *val as u64).err_span(span)?;
                    }
                }
            }
        }
        Value::Binary { val, .. } => {
            mp::write_bin(out, val).err_span(span)?;
        }
        Value::Custom { val, .. } => {
            write_value(
                out,
                &val.to_base_value(span)?,
                depth,
                engine_state,
                call_span,