parser_demo/
parser_demo.rs

1use bytestr::ByteStr;
2
3/// A simple HTTP request parser example demonstrating how to use ByteStr's convenience methods for zero-copy parsing
4fn main() {
5    // Simulate HTTP request
6    let request = ByteStr::from(
7        "GET /api/users?name=john&age=25 HTTP/1.1\r\n\
8         Host: example.com\r\n\
9         User-Agent: Mozilla/5.0\r\n\
10         Accept: application/json\r\n\
11         \r\n",
12    );
13
14    println!("=== HTTP Request Parsing Example ===");
15
16    // Parse request line
17    let (request_line, headers_and_body) = request.split_once("\r\n").unwrap();
18    println!("Request line: {}", request_line.as_str());
19
20    // Parse method, path and version
21    let mut parts = request_line.split_whitespace();
22    let method = parts.next().unwrap();
23    let path_and_query = parts.next().unwrap();
24    let version = parts.next().unwrap();
25
26    println!("  Method: {}", method.as_str());
27    println!("  HTTP Version: {}", version.as_str());
28
29    // Parse path and query parameters
30    if let Some((path, query)) = path_and_query.split_once("?") {
31        println!("  Path: {}", path.as_str());
32        println!("  Query Parameters:");
33
34        // Parse query parameters
35        for param in query.split("&") {
36            if let Some((key, value)) = param.split_once("=") {
37                println!("    {} = {}", key.as_str(), value.as_str());
38            }
39        }
40    } else {
41        println!("  Path: {}", path_and_query.as_str());
42    }
43
44    // Parse headers
45    let (headers_section, _body) = headers_and_body.split_once("\r\n\r\n").unwrap();
46    println!("  Headers:");
47
48    for header_line in headers_section.lines() {
49        if let Some((name, value)) = header_line.split_once(": ") {
50            println!("    {}: {}", name.as_str(), value.trim().as_str());
51        }
52    }
53
54    println!("\n=== Configuration File Parsing Example ===");
55
56    // Configuration file parsing example
57    let config = ByteStr::from(
58        "# Server configuration\n\
59         port=8080\n\
60         host=localhost\n\
61         debug=true\n\
62         # Database configuration\n\
63         db.host=127.0.0.1\n\
64         db.port=5432\n",
65    );
66
67    for line in config.lines() {
68        let line = line.trim();
69
70        // Skip comments and empty lines
71        if line.is_empty() || line.as_str().starts_with('#') {
72            continue;
73        }
74
75        if let Some((key, value)) = line.split_once("=") {
76            println!("Config: {} = {}", key.as_str(), value.as_str());
77        }
78    }
79
80    println!("\n=== Data Parsing Example ===");
81
82    // Parse CSV-like data
83    let csv_data = ByteStr::from("name,age,city\nJohn,25,New York\nJane,30,London\n");
84
85    let mut lines_iter = csv_data.lines();
86    let header = lines_iter.next().unwrap();
87
88    println!("CSV Header:");
89    for (i, column) in header.split(",").enumerate() {
90        println!("  Column {}: {}", i + 1, column.as_str());
91    }
92
93    println!("CSV Data:");
94    for (row_num, line) in lines_iter.enumerate() {
95        println!("  Row {}:", row_num + 1);
96        for (i, value) in line.split(",").enumerate() {
97            println!("    Column {}: {}", i + 1, value.as_str());
98        }
99    }
100
101    println!("\n=== Lexical Analysis Example ===");
102
103    // Simple lexical analysis
104    let code = ByteStr::from("let x = 42; // a variable");
105    let mut remaining = code;
106
107    while !remaining.is_empty() {
108        // Skip whitespace characters
109        remaining = remaining.skip_while(|c| c.is_whitespace());
110
111        if remaining.is_empty() {
112            break;
113        }
114
115        // Check for comments
116        if remaining.as_str().starts_with("//") {
117            let comment = remaining.take_until("\n");
118            println!("Comment: {}", comment.as_str());
119            break;
120        }
121
122        // Parse identifiers
123        if remaining.as_str().chars().next().unwrap().is_alphabetic() {
124            let (identifier, rest) = remaining.take_while(|c| c.is_alphanumeric() || c == '_');
125            println!("Identifier: {}", identifier.as_str());
126            remaining = rest;
127        }
128        // Parse numbers
129        else if remaining.as_str().chars().next().unwrap().is_ascii_digit() {
130            let (number, rest) = remaining.take_while(|c| c.is_ascii_digit());
131            println!("Number: {}", number.as_str());
132            remaining = rest;
133        }
134        // Parse operators
135        else {
136            let (operator, rest) = remaining.take_while(|c| "=;".contains(c));
137            if !operator.is_empty() {
138                println!("Operator: {}", operator.as_str());
139                remaining = rest;
140            } else {
141                // Skip one character
142                remaining = remaining.skip(1);
143            }
144        }
145    }
146}