openrouter-rust 0.1.0

A modular, type-safe Rust client for the OpenRouter API
Documentation
#[cfg(test)]
mod tests {
    use openrouter_rust::{
        types::{Function, Message, ResponseFormat, Role, Tool},
        ChatCompletionBuilder,
    };
    use serde_json::json;

    #[test]
    fn test_chat_completion_builder_basic() {
        let request = ChatCompletionBuilder::new("openai/gpt-3.5-turbo")
            .user_message("Hello")
            .build();

        assert_eq!(request.model, "openai/gpt-3.5-turbo");
        assert_eq!(request.messages.len(), 1);
        assert_eq!(request.messages[0].role, Role::User);
        assert_eq!(request.messages[0].content, Some("Hello".to_string()));
    }

    #[test]
    fn test_chat_completion_builder_with_system() {
        let request = ChatCompletionBuilder::new("anthropic/claude-3.5-sonnet")
            .system_message("You are a helpful assistant")
            .user_message("What is 2+2?")
            .assistant_message("The answer is 4.")
            .build();

        assert_eq!(request.messages.len(), 3);
        assert_eq!(request.messages[0].role, Role::System);
        assert_eq!(request.messages[0].content, Some("You are a helpful assistant".to_string()));
        assert_eq!(request.messages[1].role, Role::User);
        assert_eq!(request.messages[2].role, Role::Assistant);
    }

    #[test]
    fn test_chat_completion_builder_with_parameters() {
        let request = ChatCompletionBuilder::new("openai/gpt-4")
            .user_message("Test message")
            .temperature(0.7)
            .top_p(0.9)
            .max_tokens(100)
            .build();

        assert_eq!(request.temperature, Some(0.7));
        assert_eq!(request.top_p, Some(0.9));
        assert_eq!(request.max_tokens, Some(100));
    }

    #[test]
    fn test_chat_completion_builder_with_stop() {
        let request = ChatCompletionBuilder::new("openai/gpt-3.5-turbo")
            .user_message("Hello")
            .stop(vec!["END".to_string(), "STOP".to_string()])
            .build();

        assert_eq!(
            request.stop,
            Some(vec!["END".to_string(), "STOP".to_string()])
        );
    }

    #[test]
    fn test_chat_completion_builder_json_mode() {
        let request = ChatCompletionBuilder::new("openai/gpt-3.5-turbo")
            .user_message("Generate JSON")
            .response_format_json()
            .build();

        assert!(request.response_format.is_some());
        let format = request.response_format.unwrap();
        assert_eq!(format.response_type, "json_object");
        assert!(format.json_schema.is_none());
    }

    #[test]
    fn test_chat_completion_builder_with_tools() {
        let tool = Tool {
            tool_type: "function".to_string(),
            function: Function {
                name: "get_weather".to_string(),
                description: Some("Get weather information".to_string()),
                parameters: json!({
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "The city name"
                        }
                    },
                    "required": ["location"]
                }),
            },
        };

        let request = ChatCompletionBuilder::new("openai/gpt-4")
            .user_message("What's the weather?")
            .tools(vec![tool])
            .build();

        assert!(request.tools.is_some());
        assert_eq!(request.tools.as_ref().unwrap().len(), 1);
        assert_eq!(
            request.tools.as_ref().unwrap()[0].function.name,
            "get_weather"
        );
    }

    #[test]
    fn test_chat_completion_builder_stream() {
        let request = ChatCompletionBuilder::new("openai/gpt-3.5-turbo")
            .user_message("Hello")
            .stream(true)
            .build();

        assert_eq!(request.stream, Some(true));
    }

    #[test]
    fn test_message_serialization() {
        let message = Message {
            role: Role::User,
            content: Some("Hello, world!".to_string()), tool_calls: None,
            name: None,
        };

        let json = serde_json::to_string(&message).unwrap();
        assert!(json.contains("\"role\":\"user\""));
        assert!(json.contains("\"content\":\"Hello, world!\""));
    }

    #[test]
    fn test_message_deserialization() {
        let json = r#"{"role":"assistant","content":"Hello!","name":null}"#;
        let message: Message = serde_json::from_str(json).unwrap();

        assert!(matches!(message.role, Role::Assistant));
        assert_eq!(message.content, Some("Hello!".to_string()));
    }

    #[test]
    fn test_message_with_name() {
        let message = Message {
            role: Role::User,
            content: Some("Hello".to_string()), tool_calls: None,
            name: Some("Alice".to_string()),
        };

        let json = serde_json::to_string(&message).unwrap();
        assert!(json.contains("\"name\":\"Alice\""));
    }

    #[test]
    fn test_function_serialization() {
        let function = Function {
            name: "calculate".to_string(),
            description: Some("Calculate something".to_string()),
            parameters: json!({
                "type": "object",
                "properties": {}
            }),
        };

        let json = serde_json::to_string(&function).unwrap();
        assert!(json.contains("\"name\":\"calculate\""));
        assert!(json.contains("\"description\":\"Calculate something\""));
    }

    #[test]
    fn test_response_format_with_schema() {
        let format = ResponseFormat {
            response_type: "json_schema".to_string(),
            json_schema: Some(json!({
                "name": "person",
                "schema": {
                    "type": "object",
                    "properties": {
                        "name": {"type": "string"},
                        "age": {"type": "integer"}
                    }
                }
            })),
        };

        let json = serde_json::to_string(&format).unwrap();
        assert!(json.contains("\"type\":\"json_schema\""));
    }
}