---
title: Use map instead of and_then/or_else wrapping a constructor
description: Datadog, the leading service for cloud-scale monitoring.
breadcrumbs: >-
  Docs > Datadog Security > Code Security > Static Code Analysis (SAST) > SAST
  Rules > Use map instead of and_then/or_else wrapping a constructor
---

# Use map instead of and_then/or_else wrapping a constructor

{% callout %}
# Important note for users on the following Datadog sites: app.ddog-gov.com, us2.ddog-gov.com

{% alert level="danger" %}
This product is not supported for your selected [Datadog site](https://docs.datadoghq.com/getting_started/site.md). ({% placeholder "user-datadog-site-name" /%}).
{% /alert %}

{% /callout %}

## Metadata{% #metadata %}

**ID:** `rust-code-quality/bind-instead-of-map`

**Language:** Rust

**Severity:** Warning

**Category:** Best Practices

## Description{% #description %}

Using `and_then(|x| Some(y))`, `and_then(|x| Ok(y))`, or `or_else(|e| Err(y))` wraps a value in a constructor only for `and_then`/`or_else` to immediately unwrap it again. The extra layer adds noise without adding clarity.

## How to remediate?{% #how-to-remediate %}

Replace with the simpler combinator:

```rust
// Before
opt.and_then(|x| Some(x + 1))
// After
opt.map(|x| x + 1)

// Before
res.and_then(|x| Ok(x + 1))
// After
res.map(|x| x + 1)

// Before
res.or_else(|e| Err(e.to_string()))
// After
res.map_err(|e| e.to_string())

// Before
opt.or_else(|| None)
// After
opt
```

## Non-Compliant Code Examples{% #non-compliant-code-examples %}

```rust
fn option_and_then_some(opt: Option<i32>) -> Option<i32> {
    opt.and_then(|x| Some(x + 1))
}

fn result_and_then_ok(res: Result<i32, String>) -> Result<i32, String> {
    res.and_then(|x| Ok(x * 2))
}

fn result_or_else_err(res: Result<i32, String>) -> Result<i32, String> {
    res.or_else(|e| Err(e + "!"))
}

fn option_or_else_none(opt: Option<i32>) -> Option<i32> {
    opt.or_else(|| None)
}

fn option_and_then_block_closure(opt: Option<i32>) -> Option<i32> {
  opt.and_then(|x| { Some(x + 1) })
}

fn option_or_else_nested(opt: Option<i32>) -> Option<i32> {
  opt.and_then(|x| Some(inner.and_then(|y| Some(y + 1))))
}
```

## Compliant Code Examples{% #compliant-code-examples %}

```rust
fn already_map(opt: Option<i32>) -> Option<i32> {
    opt.map(|x| x + 1)
}

fn already_map_err(res: Result<i32, String>) -> Result<i32, String> {
    res.map_err(|e| e.to_string())
}

fn and_then_conditional(opt: Option<i32>) -> Option<i32> {
    opt.and_then(|x| if x > 0 { Some(x) } else { None })
}

fn or_else_returns_some(opt: Option<i32>) -> Option<i32> {
    opt.or_else(|| Some(0))
}

fn and_then_with_question_mark(opt: Option<Foo>) -> Option<(u32, Vec<String>)> {
    opt.and_then(|info| Some((info.id?, info.tags)))
}
```
  Seamless integrations. Try Datadog Code SecurityDatadog Code Security 
{% icon name="icon-external-link" /%}
 