Skip to main content

mago_analyzer/plugin/libraries/stdlib/random/
random_bytes.rs

1//! `random_bytes()` return type provider.
2
3use mago_codex::ttype::get_empty_string;
4use mago_codex::ttype::get_non_empty_string;
5use mago_codex::ttype::union::TUnion;
6
7use crate::plugin::context::InvocationInfo;
8use crate::plugin::context::ProviderContext;
9use crate::plugin::provider::Provider;
10use crate::plugin::provider::ProviderMeta;
11use crate::plugin::provider::function::FunctionReturnTypeProvider;
12use crate::plugin::provider::function::FunctionTarget;
13
14static META: ProviderMeta =
15    ProviderMeta::new("php::random::random_bytes", "random_bytes", "Returns non-empty-string when length > 0");
16
17/// Provider for the `random_bytes()` function.
18///
19/// Returns `non-empty-string` when the length argument is > 0.
20#[derive(Default)]
21pub struct RandomBytesProvider;
22
23impl Provider for RandomBytesProvider {
24    fn meta() -> &'static ProviderMeta {
25        &META
26    }
27}
28
29impl FunctionReturnTypeProvider for RandomBytesProvider {
30    fn targets() -> FunctionTarget {
31        FunctionTarget::Exact("random_bytes")
32    }
33
34    fn get_return_type(
35        &self,
36        context: &ProviderContext<'_, '_, '_>,
37        invocation: &InvocationInfo<'_, '_, '_>,
38    ) -> Option<TUnion> {
39        let length_argument = invocation.get_argument(0, &["length"])?;
40        let length_argument_type = context.get_expression_type(length_argument)?;
41        let length_argument_integer = length_argument_type.get_single_int()?;
42        let minimum_value = length_argument_integer.get_minimum_value()?;
43
44        Some(if minimum_value > 0 { get_non_empty_string() } else { get_empty_string() })
45    }
46}