(&self, context: &FunctionContext)
| 172 | } |
| 173 | |
| 174 | fn execute(&self, context: &FunctionContext) -> FunctionResult<Value> { |
| 175 | if context.arguments.len() != 2 { |
| 176 | return Err(FunctionError::InvalidArgumentCount { |
| 177 | expected: 2, |
| 178 | actual: context.arguments.len(), |
| 179 | }); |
| 180 | } |
| 181 | |
| 182 | let datetime_arg = &context.arguments[0]; |
| 183 | let timezone_arg = &context.arguments[1]; |
| 184 | |
| 185 | // Extract timezone string |
| 186 | let tz_str = |
| 187 | timezone_arg |
| 188 | .as_string() |
| 189 | .ok_or_else(|| FunctionError::InvalidArgumentType { |
| 190 | message: "Timezone must be a string".to_string(), |
| 191 | })?; |
| 192 | |
| 193 | // Parse timezone |
| 194 | let timezone = parse_timezone(tz_str) |
| 195 | .map_err(|e| FunctionError::InvalidArgumentType { message: e })?; |
| 196 | |
| 197 | // Convert datetime to UTC first if needed |
| 198 | let utc_dt = match datetime_arg.as_datetime_utc() { |
| 199 | Some(dt) => dt, |
| 200 | None => { |
| 201 | return Err(FunctionError::InvalidArgumentType { |
| 202 | message: "First argument must be a datetime".to_string(), |
| 203 | }) |
| 204 | } |
| 205 | }; |
| 206 | |
| 207 | // Convert to target timezone |
| 208 | Ok(timezone.convert_from_utc(&utc_dt)) |
| 209 | } |
| 210 | |
| 211 | fn graph_context_required(&self) -> bool { |
| 212 | false // Timezone functions are pure scalar functions |
nothing calls this directly
no test coverage detected